diff options
-rw-r--r-- | crates/ra_db/src/lib.rs | 2 | ||||
-rw-r--r-- | crates/ra_db/src/syntax_ptr.rs | 52 | ||||
-rw-r--r-- | crates/ra_hir/src/code_model_impl/function/scope.rs | 13 | ||||
-rw-r--r-- | crates/ra_hir/src/expr.rs | 50 | ||||
-rw-r--r-- | crates/ra_hir/src/macros.rs | 13 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres/lower.rs | 10 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 2 | ||||
-rw-r--r-- | crates/ra_ide_api/src/call_info.rs | 4 | ||||
-rw-r--r-- | crates/ra_ide_api/src/imp.rs | 2 | ||||
-rw-r--r-- | crates/ra_ide_api/src/symbol_index.rs | 14 | ||||
-rw-r--r-- | crates/ra_syntax/src/lib.rs | 2 | ||||
-rw-r--r-- | crates/ra_syntax/src/ptr.rs | 53 |
12 files changed, 109 insertions, 108 deletions
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 @@ | |||
1 | //! ra_db defines basic database traits. The concrete DB is defined by ra_ide_api. | 1 | //! ra_db defines basic database traits. The concrete DB is defined by ra_ide_api. |
2 | mod cancellation; | 2 | mod cancellation; |
3 | mod syntax_ptr; | ||
4 | mod input; | 3 | mod input; |
5 | mod loc2id; | 4 | mod loc2id; |
6 | pub mod mock; | 5 | pub mod mock; |
@@ -12,7 +11,6 @@ use ra_syntax::{TextUnit, TextRange, SourceFile, TreeArc}; | |||
12 | pub use ::salsa as salsa; | 11 | pub use ::salsa as salsa; |
13 | pub use crate::{ | 12 | pub use crate::{ |
14 | cancellation::Canceled, | 13 | cancellation::Canceled, |
15 | syntax_ptr::LocalSyntaxPtr, | ||
16 | input::{ | 14 | input::{ |
17 | FilesDatabase, FileId, CrateId, SourceRoot, SourceRootId, CrateGraph, Dependency, | 15 | FilesDatabase, FileId, CrateId, SourceRoot, SourceRootId, CrateGraph, Dependency, |
18 | FileTextQuery, FileSourceRootQuery, SourceRootQuery, LocalRootsQuery, LibraryRootsQuery, CrateGraphQuery, | 16 | 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 @@ | |||
1 | use ra_syntax::{AstNode, SourceFile, SyntaxKind, SyntaxNode, TextRange, TreeArc}; | ||
2 | |||
3 | /// A pointer to a syntax node inside a file. | ||
4 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
5 | pub struct LocalSyntaxPtr { | ||
6 | range: TextRange, | ||
7 | kind: SyntaxKind, | ||
8 | } | ||
9 | |||
10 | impl LocalSyntaxPtr { | ||
11 | pub fn new(node: &SyntaxNode) -> LocalSyntaxPtr { | ||
12 | LocalSyntaxPtr { | ||
13 | range: node.range(), | ||
14 | kind: node.kind(), | ||
15 | } | ||
16 | } | ||
17 | |||
18 | pub fn resolve(self, file: &SourceFile) -> TreeArc<SyntaxNode> { | ||
19 | let mut curr = file.syntax(); | ||
20 | loop { | ||
21 | if curr.range() == self.range && curr.kind() == self.kind { | ||
22 | return curr.to_owned(); | ||
23 | } | ||
24 | curr = curr | ||
25 | .children() | ||
26 | .find(|it| self.range.is_subrange(&it.range())) | ||
27 | .unwrap_or_else(|| panic!("can't resolve local ptr to SyntaxNode: {:?}", self)) | ||
28 | } | ||
29 | } | ||
30 | |||
31 | pub fn range(self) -> TextRange { | ||
32 | self.range | ||
33 | } | ||
34 | |||
35 | pub fn kind(self) -> SyntaxKind { | ||
36 | self.kind | ||
37 | } | ||
38 | } | ||
39 | |||
40 | #[test] | ||
41 | fn test_local_syntax_ptr() { | ||
42 | use ra_syntax::{ast, AstNode}; | ||
43 | let file = SourceFile::parse("struct Foo { f: u32, }"); | ||
44 | let field = file | ||
45 | .syntax() | ||
46 | .descendants() | ||
47 | .find_map(ast::NamedFieldDef::cast) | ||
48 | .unwrap(); | ||
49 | let ptr = LocalSyntaxPtr::new(field.syntax()); | ||
50 | let field_syntax = ptr.resolve(&file); | ||
51 | assert_eq!(field.syntax(), &*field_syntax); | ||
52 | } | ||
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; | |||
3 | use rustc_hash::{FxHashMap, FxHashSet}; | 3 | use rustc_hash::{FxHashMap, FxHashSet}; |
4 | 4 | ||
5 | use ra_syntax::{ | 5 | use ra_syntax::{ |
6 | AstNode, SyntaxNode, TextUnit, TextRange, | 6 | AstNode, SyntaxNode, TextUnit, TextRange, SyntaxNodePtr, |
7 | algo::generate, | 7 | algo::generate, |
8 | ast, | 8 | ast, |
9 | }; | 9 | }; |
10 | use ra_arena::{Arena, RawId, impl_arena_id}; | 10 | use ra_arena::{Arena, RawId, impl_arena_id}; |
11 | use ra_db::LocalSyntaxPtr; | ||
12 | 11 | ||
13 | use crate::{Name, AsName, expr::{PatId, ExprId, Pat, Expr, Body, Statement, BodySyntaxMapping}}; | 12 | use crate::{Name, AsName, expr::{PatId, ExprId, Pat, Expr, Body, Statement, BodySyntaxMapping}}; |
14 | 13 | ||
@@ -126,7 +125,7 @@ pub struct ScopesWithSyntaxMapping { | |||
126 | #[derive(Debug, Clone, PartialEq, Eq)] | 125 | #[derive(Debug, Clone, PartialEq, Eq)] |
127 | pub struct ScopeEntryWithSyntax { | 126 | pub struct ScopeEntryWithSyntax { |
128 | name: Name, | 127 | name: Name, |
129 | ptr: LocalSyntaxPtr, | 128 | ptr: SyntaxNodePtr, |
130 | } | 129 | } |
131 | 130 | ||
132 | impl ScopeEntryWithSyntax { | 131 | impl ScopeEntryWithSyntax { |
@@ -134,7 +133,7 @@ impl ScopeEntryWithSyntax { | |||
134 | &self.name | 133 | &self.name |
135 | } | 134 | } |
136 | 135 | ||
137 | pub fn ptr(&self) -> LocalSyntaxPtr { | 136 | pub fn ptr(&self) -> SyntaxNodePtr { |
138 | self.ptr | 137 | self.ptr |
139 | } | 138 | } |
140 | } | 139 | } |
@@ -169,7 +168,7 @@ impl ScopesWithSyntaxMapping { | |||
169 | 168 | ||
170 | // XXX: during completion, cursor might be outside of any particular | 169 | // XXX: during completion, cursor might be outside of any particular |
171 | // expression. Try to figure out the correct scope... | 170 | // expression. Try to figure out the correct scope... |
172 | fn adjust(&self, ptr: LocalSyntaxPtr, original_scope: ScopeId, offset: TextUnit) -> ScopeId { | 171 | fn adjust(&self, ptr: SyntaxNodePtr, original_scope: ScopeId, offset: TextUnit) -> ScopeId { |
173 | let r = ptr.range(); | 172 | let r = ptr.range(); |
174 | let child_scopes = self | 173 | let child_scopes = self |
175 | .scopes | 174 | .scopes |
@@ -212,7 +211,7 @@ impl ScopesWithSyntaxMapping { | |||
212 | 211 | ||
213 | pub fn find_all_refs(&self, pat: &ast::BindPat) -> Vec<ReferenceDescriptor> { | 212 | pub fn find_all_refs(&self, pat: &ast::BindPat) -> Vec<ReferenceDescriptor> { |
214 | let fn_def = pat.syntax().ancestors().find_map(ast::FnDef::cast).unwrap(); | 213 | let fn_def = pat.syntax().ancestors().find_map(ast::FnDef::cast).unwrap(); |
215 | let name_ptr = LocalSyntaxPtr::new(pat.syntax()); | 214 | let name_ptr = SyntaxNodePtr::new(pat.syntax()); |
216 | fn_def | 215 | fn_def |
217 | .syntax() | 216 | .syntax() |
218 | .descendants() | 217 | .descendants() |
@@ -230,7 +229,7 @@ impl ScopesWithSyntaxMapping { | |||
230 | 229 | ||
231 | fn scope_for(&self, node: &SyntaxNode) -> Option<ScopeId> { | 230 | fn scope_for(&self, node: &SyntaxNode) -> Option<ScopeId> { |
232 | node.ancestors() | 231 | node.ancestors() |
233 | .map(LocalSyntaxPtr::new) | 232 | .map(SyntaxNodePtr::new) |
234 | .filter_map(|ptr| self.syntax_mapping.syntax_expr(ptr)) | 233 | .filter_map(|ptr| self.syntax_mapping.syntax_expr(ptr)) |
235 | .find_map(|it| self.scopes.scope_for(it)) | 234 | .find_map(|it| self.scopes.scope_for(it)) |
236 | } | 235 | } |
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; | |||
4 | use rustc_hash::FxHashMap; | 4 | use rustc_hash::FxHashMap; |
5 | 5 | ||
6 | use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap}; | 6 | use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap}; |
7 | use ra_db::LocalSyntaxPtr; | 7 | use ra_syntax::{ |
8 | use ra_syntax::ast::{self, AstNode, LoopBodyOwner, ArgListOwner, NameOwner, LiteralFlavor}; | 8 | SyntaxNodePtr, AstNode, |
9 | ast::{self, LoopBodyOwner, ArgListOwner, NameOwner, LiteralFlavor} | ||
10 | }; | ||
9 | 11 | ||
10 | use crate::{Path, type_ref::{Mutability, TypeRef}, Name, HirDatabase, DefId, Def, name::AsName}; | 12 | use crate::{Path, type_ref::{Mutability, TypeRef}, Name, HirDatabase, DefId, Def, name::AsName}; |
11 | use crate::ty::primitive::{UintTy, UncertainIntTy, UncertainFloatTy}; | 13 | use crate::ty::primitive::{UintTy, UncertainIntTy, UncertainFloatTy}; |
@@ -38,10 +40,10 @@ pub struct Body { | |||
38 | #[derive(Debug, Eq, PartialEq)] | 40 | #[derive(Debug, Eq, PartialEq)] |
39 | pub struct BodySyntaxMapping { | 41 | pub struct BodySyntaxMapping { |
40 | body: Arc<Body>, | 42 | body: Arc<Body>, |
41 | expr_syntax_mapping: FxHashMap<LocalSyntaxPtr, ExprId>, | 43 | expr_syntax_mapping: FxHashMap<SyntaxNodePtr, ExprId>, |
42 | expr_syntax_mapping_back: ArenaMap<ExprId, LocalSyntaxPtr>, | 44 | expr_syntax_mapping_back: ArenaMap<ExprId, SyntaxNodePtr>, |
43 | pat_syntax_mapping: FxHashMap<LocalSyntaxPtr, PatId>, | 45 | pat_syntax_mapping: FxHashMap<SyntaxNodePtr, PatId>, |
44 | pat_syntax_mapping_back: ArenaMap<PatId, LocalSyntaxPtr>, | 46 | pat_syntax_mapping_back: ArenaMap<PatId, SyntaxNodePtr>, |
45 | } | 47 | } |
46 | 48 | ||
47 | impl Body { | 49 | impl Body { |
@@ -71,31 +73,31 @@ impl Index<PatId> for Body { | |||
71 | } | 73 | } |
72 | 74 | ||
73 | impl BodySyntaxMapping { | 75 | impl BodySyntaxMapping { |
74 | pub fn expr_syntax(&self, expr: ExprId) -> Option<LocalSyntaxPtr> { | 76 | pub fn expr_syntax(&self, expr: ExprId) -> Option<SyntaxNodePtr> { |
75 | self.expr_syntax_mapping_back.get(expr).cloned() | 77 | self.expr_syntax_mapping_back.get(expr).cloned() |
76 | } | 78 | } |
77 | 79 | ||
78 | pub fn syntax_expr(&self, ptr: LocalSyntaxPtr) -> Option<ExprId> { | 80 | pub fn syntax_expr(&self, ptr: SyntaxNodePtr) -> Option<ExprId> { |
79 | self.expr_syntax_mapping.get(&ptr).cloned() | 81 | self.expr_syntax_mapping.get(&ptr).cloned() |
80 | } | 82 | } |
81 | 83 | ||
82 | pub fn node_expr(&self, node: &ast::Expr) -> Option<ExprId> { | 84 | pub fn node_expr(&self, node: &ast::Expr) -> Option<ExprId> { |
83 | self.expr_syntax_mapping | 85 | self.expr_syntax_mapping |
84 | .get(&LocalSyntaxPtr::new(node.syntax())) | 86 | .get(&SyntaxNodePtr::new(node.syntax())) |
85 | .cloned() | 87 | .cloned() |
86 | } | 88 | } |
87 | 89 | ||
88 | pub fn pat_syntax(&self, pat: PatId) -> Option<LocalSyntaxPtr> { | 90 | pub fn pat_syntax(&self, pat: PatId) -> Option<SyntaxNodePtr> { |
89 | self.pat_syntax_mapping_back.get(pat).cloned() | 91 | self.pat_syntax_mapping_back.get(pat).cloned() |
90 | } | 92 | } |
91 | 93 | ||
92 | pub fn syntax_pat(&self, ptr: LocalSyntaxPtr) -> Option<PatId> { | 94 | pub fn syntax_pat(&self, ptr: SyntaxNodePtr) -> Option<PatId> { |
93 | self.pat_syntax_mapping.get(&ptr).cloned() | 95 | self.pat_syntax_mapping.get(&ptr).cloned() |
94 | } | 96 | } |
95 | 97 | ||
96 | pub fn node_pat(&self, node: &ast::Pat) -> Option<PatId> { | 98 | pub fn node_pat(&self, node: &ast::Pat) -> Option<PatId> { |
97 | self.pat_syntax_mapping | 99 | self.pat_syntax_mapping |
98 | .get(&LocalSyntaxPtr::new(node.syntax())) | 100 | .get(&SyntaxNodePtr::new(node.syntax())) |
99 | .cloned() | 101 | .cloned() |
100 | } | 102 | } |
101 | 103 | ||
@@ -440,10 +442,10 @@ pub(crate) fn body_hir(db: &impl HirDatabase, def_id: DefId) -> Arc<Body> { | |||
440 | struct ExprCollector { | 442 | struct ExprCollector { |
441 | exprs: Arena<ExprId, Expr>, | 443 | exprs: Arena<ExprId, Expr>, |
442 | pats: Arena<PatId, Pat>, | 444 | pats: Arena<PatId, Pat>, |
443 | expr_syntax_mapping: FxHashMap<LocalSyntaxPtr, ExprId>, | 445 | expr_syntax_mapping: FxHashMap<SyntaxNodePtr, ExprId>, |
444 | expr_syntax_mapping_back: ArenaMap<ExprId, LocalSyntaxPtr>, | 446 | expr_syntax_mapping_back: ArenaMap<ExprId, SyntaxNodePtr>, |
445 | pat_syntax_mapping: FxHashMap<LocalSyntaxPtr, PatId>, | 447 | pat_syntax_mapping: FxHashMap<SyntaxNodePtr, PatId>, |
446 | pat_syntax_mapping_back: ArenaMap<PatId, LocalSyntaxPtr>, | 448 | pat_syntax_mapping_back: ArenaMap<PatId, SyntaxNodePtr>, |
447 | } | 449 | } |
448 | 450 | ||
449 | impl ExprCollector { | 451 | impl ExprCollector { |
@@ -458,14 +460,14 @@ impl ExprCollector { | |||
458 | } | 460 | } |
459 | } | 461 | } |
460 | 462 | ||
461 | fn alloc_expr(&mut self, expr: Expr, syntax_ptr: LocalSyntaxPtr) -> ExprId { | 463 | fn alloc_expr(&mut self, expr: Expr, syntax_ptr: SyntaxNodePtr) -> ExprId { |
462 | let id = self.exprs.alloc(expr); | 464 | let id = self.exprs.alloc(expr); |
463 | self.expr_syntax_mapping.insert(syntax_ptr, id); | 465 | self.expr_syntax_mapping.insert(syntax_ptr, id); |
464 | self.expr_syntax_mapping_back.insert(id, syntax_ptr); | 466 | self.expr_syntax_mapping_back.insert(id, syntax_ptr); |
465 | id | 467 | id |
466 | } | 468 | } |
467 | 469 | ||
468 | fn alloc_pat(&mut self, pat: Pat, syntax_ptr: LocalSyntaxPtr) -> PatId { | 470 | fn alloc_pat(&mut self, pat: Pat, syntax_ptr: SyntaxNodePtr) -> PatId { |
469 | let id = self.pats.alloc(pat); | 471 | let id = self.pats.alloc(pat); |
470 | self.pat_syntax_mapping.insert(syntax_ptr, id); | 472 | self.pat_syntax_mapping.insert(syntax_ptr, id); |
471 | self.pat_syntax_mapping_back.insert(id, syntax_ptr); | 473 | self.pat_syntax_mapping_back.insert(id, syntax_ptr); |
@@ -481,7 +483,7 @@ impl ExprCollector { | |||
481 | } | 483 | } |
482 | 484 | ||
483 | fn collect_expr(&mut self, expr: &ast::Expr) -> ExprId { | 485 | fn collect_expr(&mut self, expr: &ast::Expr) -> ExprId { |
484 | let syntax_ptr = LocalSyntaxPtr::new(expr.syntax()); | 486 | let syntax_ptr = SyntaxNodePtr::new(expr.syntax()); |
485 | match expr.kind() { | 487 | match expr.kind() { |
486 | ast::ExprKind::IfExpr(e) => { | 488 | ast::ExprKind::IfExpr(e) => { |
487 | if let Some(pat) = e.condition().and_then(|c| c.pat()) { | 489 | if let Some(pat) = e.condition().and_then(|c| c.pat()) { |
@@ -643,9 +645,9 @@ impl ExprCollector { | |||
643 | // field shorthand | 645 | // field shorthand |
644 | let id = self.exprs.alloc(Expr::Path(Path::from_name_ref(nr))); | 646 | let id = self.exprs.alloc(Expr::Path(Path::from_name_ref(nr))); |
645 | self.expr_syntax_mapping | 647 | self.expr_syntax_mapping |
646 | .insert(LocalSyntaxPtr::new(nr.syntax()), id); | 648 | .insert(SyntaxNodePtr::new(nr.syntax()), id); |
647 | self.expr_syntax_mapping_back | 649 | self.expr_syntax_mapping_back |
648 | .insert(id, LocalSyntaxPtr::new(nr.syntax())); | 650 | .insert(id, SyntaxNodePtr::new(nr.syntax())); |
649 | id | 651 | id |
650 | } else { | 652 | } else { |
651 | self.exprs.alloc(Expr::Missing) | 653 | self.exprs.alloc(Expr::Missing) |
@@ -806,7 +808,7 @@ impl ExprCollector { | |||
806 | let tail = block.expr().map(|e| self.collect_expr(e)); | 808 | let tail = block.expr().map(|e| self.collect_expr(e)); |
807 | self.alloc_expr( | 809 | self.alloc_expr( |
808 | Expr::Block { statements, tail }, | 810 | Expr::Block { statements, tail }, |
809 | LocalSyntaxPtr::new(block.syntax()), | 811 | SyntaxNodePtr::new(block.syntax()), |
810 | ) | 812 | ) |
811 | } | 813 | } |
812 | 814 | ||
@@ -883,7 +885,7 @@ impl ExprCollector { | |||
883 | // TODO: implement | 885 | // TODO: implement |
884 | ast::PatKind::SlicePat(_) | ast::PatKind::RangePat(_) => Pat::Missing, | 886 | ast::PatKind::SlicePat(_) | ast::PatKind::RangePat(_) => Pat::Missing, |
885 | }; | 887 | }; |
886 | let syntax_ptr = LocalSyntaxPtr::new(pat.syntax()); | 888 | let syntax_ptr = SyntaxNodePtr::new(pat.syntax()); |
887 | self.alloc_pat(pattern, syntax_ptr) | 889 | self.alloc_pat(pattern, syntax_ptr) |
888 | } | 890 | } |
889 | 891 | ||
@@ -919,7 +921,7 @@ pub(crate) fn collect_fn_body_syntax(node: &ast::FnDef) -> BodySyntaxMapping { | |||
919 | let mut params = Vec::new(); | 921 | let mut params = Vec::new(); |
920 | 922 | ||
921 | if let Some(self_param) = param_list.self_param() { | 923 | if let Some(self_param) = param_list.self_param() { |
922 | let self_param = LocalSyntaxPtr::new( | 924 | let self_param = SyntaxNodePtr::new( |
923 | self_param | 925 | self_param |
924 | .self_kw() | 926 | .self_kw() |
925 | .expect("self param without self keyword") | 927 | .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 @@ | |||
9 | /// those yet, so all macros are string based at the moment! | 9 | /// those yet, so all macros are string based at the moment! |
10 | use std::sync::Arc; | 10 | use std::sync::Arc; |
11 | 11 | ||
12 | use ra_db::LocalSyntaxPtr; | ||
13 | use ra_syntax::{ | 12 | use ra_syntax::{ |
14 | TextRange, TextUnit, SourceFile, AstNode, SyntaxNode, TreeArc, | 13 | TextRange, TextUnit, SourceFile, AstNode, SyntaxNode, TreeArc, SyntaxNodePtr, |
15 | ast::{self, NameOwner}, | 14 | ast::{self, NameOwner}, |
16 | }; | 15 | }; |
17 | 16 | ||
@@ -80,7 +79,7 @@ impl MacroDef { | |||
80 | let file = SourceFile::parse(&text); | 79 | let file = SourceFile::parse(&text); |
81 | let match_expr = file.syntax().descendants().find_map(ast::MatchExpr::cast)?; | 80 | let match_expr = file.syntax().descendants().find_map(ast::MatchExpr::cast)?; |
82 | let match_arg = match_expr.expr()?; | 81 | let match_arg = match_expr.expr()?; |
83 | let ptr = LocalSyntaxPtr::new(match_arg.syntax()); | 82 | let ptr = SyntaxNodePtr::new(match_arg.syntax()); |
84 | let src_range = TextRange::offset_len(0.into(), TextUnit::of_str(&input.text)); | 83 | let src_range = TextRange::offset_len(0.into(), TextUnit::of_str(&input.text)); |
85 | let ranges_map = vec![(src_range, match_arg.syntax().range())]; | 84 | let ranges_map = vec![(src_range, match_arg.syntax().range())]; |
86 | let res = MacroExpansion { | 85 | let res = MacroExpansion { |
@@ -94,7 +93,7 @@ impl MacroDef { | |||
94 | let text = format!(r"fn dummy() {{ {}; }}", input.text); | 93 | let text = format!(r"fn dummy() {{ {}; }}", input.text); |
95 | let file = SourceFile::parse(&text); | 94 | let file = SourceFile::parse(&text); |
96 | let array_expr = file.syntax().descendants().find_map(ast::ArrayExpr::cast)?; | 95 | let array_expr = file.syntax().descendants().find_map(ast::ArrayExpr::cast)?; |
97 | let ptr = LocalSyntaxPtr::new(array_expr.syntax()); | 96 | let ptr = SyntaxNodePtr::new(array_expr.syntax()); |
98 | let src_range = TextRange::offset_len(0.into(), TextUnit::of_str(&input.text)); | 97 | let src_range = TextRange::offset_len(0.into(), TextUnit::of_str(&input.text)); |
99 | let ranges_map = vec![(src_range, array_expr.syntax().range())]; | 98 | let ranges_map = vec![(src_range, array_expr.syntax().range())]; |
100 | let res = MacroExpansion { | 99 | let res = MacroExpansion { |
@@ -119,7 +118,7 @@ impl MacroDef { | |||
119 | let file = SourceFile::parse(&text); | 118 | let file = SourceFile::parse(&text); |
120 | let trait_def = file.syntax().descendants().find_map(ast::TraitDef::cast)?; | 119 | let trait_def = file.syntax().descendants().find_map(ast::TraitDef::cast)?; |
121 | let name = trait_def.name()?; | 120 | let name = trait_def.name()?; |
122 | let ptr = LocalSyntaxPtr::new(trait_def.syntax()); | 121 | let ptr = SyntaxNodePtr::new(trait_def.syntax()); |
123 | let ranges_map = vec![(src_range, name.syntax().range())]; | 122 | let ranges_map = vec![(src_range, name.syntax().range())]; |
124 | let res = MacroExpansion { | 123 | let res = MacroExpansion { |
125 | text, | 124 | text, |
@@ -146,7 +145,7 @@ pub struct MacroExpansion { | |||
146 | /// Implementation detail: internally, a macro is expanded to the whole file, | 145 | /// Implementation detail: internally, a macro is expanded to the whole file, |
147 | /// even if it is an expression. This `ptr` selects the actual expansion from | 146 | /// even if it is an expression. This `ptr` selects the actual expansion from |
148 | /// the expanded file. | 147 | /// the expanded file. |
149 | ptr: LocalSyntaxPtr, | 148 | ptr: SyntaxNodePtr, |
150 | } | 149 | } |
151 | 150 | ||
152 | impl MacroExpansion { | 151 | impl MacroExpansion { |
@@ -157,7 +156,7 @@ impl MacroExpansion { | |||
157 | } | 156 | } |
158 | 157 | ||
159 | pub fn syntax(&self) -> TreeArc<SyntaxNode> { | 158 | pub fn syntax(&self) -> TreeArc<SyntaxNode> { |
160 | self.ptr.resolve(&self.file()) | 159 | self.ptr.to_node(&self.file()).to_owned() |
161 | } | 160 | } |
162 | /// Maps range in the source code to the range in the expanded code. | 161 | /// Maps range in the source code to the range in the expanded code. |
163 | pub fn map_range_forward(&self, src_range: TextRange) -> Option<TextRange> { | 162 | pub fn map_range_forward(&self, src_range: TextRange) -> Option<TextRange> { |
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 @@ | |||
1 | use std::sync::Arc; | 1 | use std::sync::Arc; |
2 | 2 | ||
3 | use ra_syntax::{ | 3 | use ra_syntax::{ |
4 | SyntaxKind, AstNode, SourceFile, TreeArc, | 4 | SyntaxKind, AstNode, SourceFile, TreeArc, SyntaxNodePtr, |
5 | ast::{self, ModuleItemOwner}, | 5 | ast::{self, ModuleItemOwner}, |
6 | }; | 6 | }; |
7 | use ra_db::{SourceRootId, LocalSyntaxPtr}; | 7 | use ra_db::{SourceRootId}; |
8 | use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap}; | 8 | use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap}; |
9 | 9 | ||
10 | use crate::{ | 10 | use crate::{ |
@@ -72,13 +72,13 @@ pub struct LoweredModule { | |||
72 | 72 | ||
73 | #[derive(Debug, Default, PartialEq, Eq)] | 73 | #[derive(Debug, Default, PartialEq, Eq)] |
74 | pub struct ImportSourceMap { | 74 | pub struct ImportSourceMap { |
75 | map: ArenaMap<ImportId, LocalSyntaxPtr>, | 75 | map: ArenaMap<ImportId, SyntaxNodePtr>, |
76 | } | 76 | } |
77 | 77 | ||
78 | impl ImportSourceMap { | 78 | impl ImportSourceMap { |
79 | fn insert(&mut self, import: ImportId, segment: &ast::PathSegment) { | 79 | fn insert(&mut self, import: ImportId, segment: &ast::PathSegment) { |
80 | self.map | 80 | self.map |
81 | .insert(import, LocalSyntaxPtr::new(segment.syntax())) | 81 | .insert(import, SyntaxNodePtr::new(segment.syntax())) |
82 | } | 82 | } |
83 | 83 | ||
84 | pub fn get(&self, source: &ModuleSource, import: ImportId) -> TreeArc<ast::PathSegment> { | 84 | pub fn get(&self, source: &ModuleSource, import: ImportId) -> TreeArc<ast::PathSegment> { |
@@ -87,7 +87,7 @@ impl ImportSourceMap { | |||
87 | ModuleSource::Module(m) => m.syntax().ancestors().find_map(SourceFile::cast).unwrap(), | 87 | ModuleSource::Module(m) => m.syntax().ancestors().find_map(SourceFile::cast).unwrap(), |
88 | }; | 88 | }; |
89 | 89 | ||
90 | ast::PathSegment::cast(&self.map[import].resolve(file)) | 90 | ast::PathSegment::cast(self.map[import].to_node(file)) |
91 | .unwrap() | 91 | .unwrap() |
92 | .to_owned() | 92 | .to_owned() |
93 | } | 93 | } |
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 { | |||
562 | // sort ranges for consistency | 562 | // sort ranges for consistency |
563 | types.sort_by_key(|(ptr, _)| (ptr.range().start(), ptr.range().end())); | 563 | types.sort_by_key(|(ptr, _)| (ptr.range().start(), ptr.range().end())); |
564 | for (syntax_ptr, ty) in &types { | 564 | for (syntax_ptr, ty) in &types { |
565 | let node = syntax_ptr.resolve(&source_file); | 565 | let node = syntax_ptr.to_node(&source_file); |
566 | write!( | 566 | write!( |
567 | acc, | 567 | acc, |
568 | "{} '{}': {}\n", | 568 | "{} '{}': {}\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<Cal | |||
23 | .into_iter() | 23 | .into_iter() |
24 | .find(|it| it.ptr.kind() == FN_DEF)?; | 24 | .find(|it| it.ptr.kind() == FN_DEF)?; |
25 | let fn_file = db.source_file(symbol.file_id); | 25 | let fn_file = db.source_file(symbol.file_id); |
26 | let fn_def = symbol.ptr.resolve(&fn_file); | 26 | let fn_def = symbol.ptr.to_node(&fn_file); |
27 | let fn_def = ast::FnDef::cast(&fn_def).unwrap(); | 27 | let fn_def = ast::FnDef::cast(fn_def).unwrap(); |
28 | let mut call_info = CallInfo::new(fn_def)?; | 28 | let mut call_info = CallInfo::new(fn_def)?; |
29 | // If we have a calling expression let's find which argument we are on | 29 | // If we have a calling expression let's find which argument we are on |
30 | let num_params = call_info.parameters.len(); | 30 | let num_params = call_info.parameters.len(); |
diff --git a/crates/ra_ide_api/src/imp.rs b/crates/ra_ide_api/src/imp.rs index fa79908a1..ddd9354ec 100644 --- a/crates/ra_ide_api/src/imp.rs +++ b/crates/ra_ide_api/src/imp.rs | |||
@@ -153,7 +153,7 @@ impl db::RootDatabase { | |||
153 | source_binder::function_from_child_node(db, position.file_id, name_ref.syntax())?; | 153 | source_binder::function_from_child_node(db, position.file_id, name_ref.syntax())?; |
154 | let scope = descr.scopes(db); | 154 | let scope = descr.scopes(db); |
155 | let resolved = scope.resolve_local_name(name_ref)?; | 155 | let resolved = scope.resolve_local_name(name_ref)?; |
156 | let resolved = resolved.ptr().resolve(source_file); | 156 | let resolved = resolved.ptr().to_node(source_file); |
157 | let binding = find_node_at_offset::<ast::BindPat>(syntax, resolved.range().end())?; | 157 | let binding = find_node_at_offset::<ast::BindPat>(syntax, resolved.range().end())?; |
158 | Some((binding, descr)) | 158 | Some((binding, descr)) |
159 | } | 159 | } |
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::{ | |||
27 | 27 | ||
28 | use fst::{self, Streamer}; | 28 | use fst::{self, Streamer}; |
29 | use ra_syntax::{ | 29 | use ra_syntax::{ |
30 | SyntaxNode, SourceFile, SmolStr, TreeArc, AstNode, | 30 | SyntaxNode, SyntaxNodePtr, SourceFile, SmolStr, TreeArc, AstNode, |
31 | algo::{visit::{visitor, Visitor}, find_covering_node}, | 31 | algo::{visit::{visitor, Visitor}, find_covering_node}, |
32 | SyntaxKind::{self, *}, | 32 | SyntaxKind::{self, *}, |
33 | ast::{self, NameOwner}, | 33 | ast::{self, NameOwner}, |
34 | }; | 34 | }; |
35 | use ra_db::{ | 35 | use ra_db::{ |
36 | SourceRootId, FilesDatabase, LocalSyntaxPtr, | 36 | SourceRootId, FilesDatabase, |
37 | salsa::{self, ParallelDatabase}, | 37 | salsa::{self, ParallelDatabase}, |
38 | }; | 38 | }; |
39 | use rayon::prelude::*; | 39 | use rayon::prelude::*; |
@@ -62,7 +62,7 @@ fn file_symbols(db: &impl SymbolsDatabase, file_id: FileId) -> Arc<SymbolIndex> | |||
62 | 62 | ||
63 | for (name, text_range) in hir::source_binder::macro_symbols(db, file_id) { | 63 | for (name, text_range) in hir::source_binder::macro_symbols(db, file_id) { |
64 | let node = find_covering_node(source_file.syntax(), text_range); | 64 | let node = find_covering_node(source_file.syntax(), text_range); |
65 | let ptr = LocalSyntaxPtr::new(node); | 65 | let ptr = SyntaxNodePtr::new(node); |
66 | symbols.push(FileSymbol { file_id, name, ptr }) | 66 | symbols.push(FileSymbol { file_id, name, ptr }) |
67 | } | 67 | } |
68 | 68 | ||
@@ -196,13 +196,13 @@ fn is_type(kind: SyntaxKind) -> bool { | |||
196 | pub(crate) struct FileSymbol { | 196 | pub(crate) struct FileSymbol { |
197 | pub(crate) file_id: FileId, | 197 | pub(crate) file_id: FileId, |
198 | pub(crate) name: SmolStr, | 198 | pub(crate) name: SmolStr, |
199 | pub(crate) ptr: LocalSyntaxPtr, | 199 | pub(crate) ptr: SyntaxNodePtr, |
200 | } | 200 | } |
201 | 201 | ||
202 | fn to_symbol(node: &SyntaxNode) -> Option<(SmolStr, LocalSyntaxPtr)> { | 202 | fn to_symbol(node: &SyntaxNode) -> Option<(SmolStr, SyntaxNodePtr)> { |
203 | fn decl<N: NameOwner>(node: &N) -> Option<(SmolStr, LocalSyntaxPtr)> { | 203 | fn decl<N: NameOwner>(node: &N) -> Option<(SmolStr, SyntaxNodePtr)> { |
204 | let name = node.name()?.text().clone(); | 204 | let name = node.name()?.text().clone(); |
205 | let ptr = LocalSyntaxPtr::new(node.syntax()); | 205 | let ptr = SyntaxNodePtr::new(node.syntax()); |
206 | Some((name, ptr)) | 206 | Some((name, ptr)) |
207 | } | 207 | } |
208 | visitor() | 208 | 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; | |||
35 | pub mod utils; | 35 | pub mod utils; |
36 | mod validation; | 36 | mod validation; |
37 | mod yellow; | 37 | mod yellow; |
38 | mod ptr; | ||
38 | 39 | ||
39 | pub use rowan::{SmolStr, TextRange, TextUnit}; | 40 | pub use rowan::{SmolStr, TextRange, TextUnit}; |
40 | pub use crate::{ | 41 | pub use crate::{ |
@@ -42,6 +43,7 @@ pub use crate::{ | |||
42 | lexer::{tokenize, Token}, | 43 | lexer::{tokenize, Token}, |
43 | syntax_kinds::SyntaxKind, | 44 | syntax_kinds::SyntaxKind, |
44 | yellow::{Direction, SyntaxError, SyntaxNode, WalkEvent, Location, TreeArc}, | 45 | yellow::{Direction, SyntaxError, SyntaxNode, WalkEvent, Location, TreeArc}, |
46 | ptr::SyntaxNodePtr, | ||
45 | }; | 47 | }; |
46 | 48 | ||
47 | use ra_text_edit::AtomTextEdit; | 49 | 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 @@ | |||
1 | use crate::{ | ||
2 | AstNode, SourceFile, SyntaxKind, SyntaxNode, TextRange, | ||
3 | algo::generate, | ||
4 | }; | ||
5 | |||
6 | /// A pointer to a syntax node inside a file. It can be used to remember a | ||
7 | /// specific node across reparses of the same file. | ||
8 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
9 | pub struct SyntaxNodePtr { | ||
10 | range: TextRange, | ||
11 | kind: SyntaxKind, | ||
12 | } | ||
13 | |||
14 | impl SyntaxNodePtr { | ||
15 | pub fn new(node: &SyntaxNode) -> SyntaxNodePtr { | ||
16 | SyntaxNodePtr { | ||
17 | range: node.range(), | ||
18 | kind: node.kind(), | ||
19 | } | ||
20 | } | ||
21 | |||
22 | pub fn to_node(self, source_file: &SourceFile) -> &SyntaxNode { | ||
23 | generate(Some(source_file.syntax()), |&node| { | ||
24 | node.children() | ||
25 | .find(|it| self.range.is_subrange(&it.range())) | ||
26 | }) | ||
27 | .find(|it| it.range() == self.range && it.kind() == self.kind) | ||
28 | .unwrap_or_else(|| panic!("can't resolve local ptr to SyntaxNode: {:?}", self)) | ||
29 | } | ||
30 | |||
31 | pub fn range(self) -> TextRange { | ||
32 | self.range | ||
33 | } | ||
34 | |||
35 | pub fn kind(self) -> SyntaxKind { | ||
36 | self.kind | ||
37 | } | ||
38 | } | ||
39 | |||
40 | #[test] | ||
41 | fn test_local_syntax_ptr() { | ||
42 | use crate::{ast, AstNode}; | ||
43 | |||
44 | let file = SourceFile::parse("struct Foo { f: u32, }"); | ||
45 | let field = file | ||
46 | .syntax() | ||
47 | .descendants() | ||
48 | .find_map(ast::NamedFieldDef::cast) | ||
49 | .unwrap(); | ||
50 | let ptr = SyntaxNodePtr::new(field.syntax()); | ||
51 | let field_syntax = ptr.to_node(&file); | ||
52 | assert_eq!(field.syntax(), &*field_syntax); | ||
53 | } | ||