From bd8af6a413bb2f762bb696d20727e21cb2d4cb62 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 16 Nov 2019 00:05:10 +0300 Subject: [PATCH 1/2] Sourcify some more --- crates/ra_hir/src/source_binder.rs | 34 ++++++++++++++++++------------ crates/ra_hir_expand/src/lib.rs | 2 ++ 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index f08827ed3d0..f3bccd8ed75 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -141,13 +141,16 @@ impl SourceAnalyzer { node: &SyntaxNode, offset: Option, ) -> SourceAnalyzer { - let def_with_body = def_with_body_from_child_node(db, Source::new(file_id.into(), node)); + let node_source = Source::new(file_id.into(), node); + let def_with_body = def_with_body_from_child_node(db, node_source); if let Some(def) = def_with_body { let source_map = def.body_source_map(db); let scopes = def.expr_scopes(db); let scope = match offset { - None => scope_for(&scopes, &source_map, file_id.into(), &node), - Some(offset) => scope_for_offset(&scopes, &source_map, file_id.into(), offset), + None => scope_for(&scopes, &source_map, node_source), + Some(offset) => { + scope_for_offset(&scopes, &source_map, Source::new(file_id.into(), offset)) + } }; let resolver = expr::resolver_for_scope(db, def, scope); SourceAnalyzer { @@ -287,7 +290,8 @@ impl SourceAnalyzer { let name = name_ref.as_name(); let source_map = self.body_source_map.as_ref()?; let scopes = self.scopes.as_ref()?; - let scope = scope_for(scopes, source_map, self.file_id.into(), name_ref.syntax())?; + let scope = + scope_for(scopes, source_map, Source::new(self.file_id.into(), name_ref.syntax()))?; let entry = scopes.resolve_name_in_scope(scope, &name)?; Some(ScopeEntryWithSyntax { name: entry.name().clone(), @@ -408,20 +412,19 @@ impl SourceAnalyzer { fn scope_for( scopes: &ExprScopes, source_map: &BodySourceMap, - file_id: HirFileId, - node: &SyntaxNode, + node: Source<&SyntaxNode>, ) -> Option { - node.ancestors() + node.ast + .ancestors() .filter_map(ast::Expr::cast) - .filter_map(|it| source_map.node_expr(Source { file_id, ast: &it })) + .filter_map(|it| source_map.node_expr(Source::new(node.file_id, &it))) .find_map(|it| scopes.scope_for(it)) } fn scope_for_offset( scopes: &ExprScopes, source_map: &BodySourceMap, - file_id: HirFileId, - offset: TextUnit, + offset: Source, ) -> Option { scopes .scope_by_expr() @@ -429,7 +432,7 @@ fn scope_for_offset( .filter_map(|(id, scope)| { let source = source_map.expr_syntax(*id)?; // FIXME: correctly handle macro expansion - if source.file_id != file_id { + if source.file_id != offset.file_id { return None; } let syntax_node_ptr = @@ -438,9 +441,14 @@ fn scope_for_offset( }) // find containing scope .min_by_key(|(ptr, _scope)| { - (!(ptr.range().start() <= offset && offset <= ptr.range().end()), ptr.range().len()) + ( + !(ptr.range().start() <= offset.ast && offset.ast <= ptr.range().end()), + ptr.range().len(), + ) + }) + .map(|(ptr, scope)| { + adjust(scopes, source_map, ptr, offset.file_id, offset.ast).unwrap_or(*scope) }) - .map(|(ptr, scope)| adjust(scopes, source_map, ptr, file_id, offset).unwrap_or(*scope)) } // XXX: during completion, cursor might be outside of any particular diff --git a/crates/ra_hir_expand/src/lib.rs b/crates/ra_hir_expand/src/lib.rs index 437d73e94df..6c2cc3af3ea 100644 --- a/crates/ra_hir_expand/src/lib.rs +++ b/crates/ra_hir_expand/src/lib.rs @@ -226,6 +226,8 @@ impl AstId { #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)] pub struct Source { pub file_id: HirFileId, + // FIXME: this stores all kind of things, not only `ast`. + // There should be a better name... pub ast: T, } From 0404e647e69f758ac84c742b06dddefb01cc4ad6 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 16 Nov 2019 00:40:54 +0300 Subject: [PATCH 2/2] Prepare SourceAnalyzer for macros --- crates/ra_hir/src/source_binder.rs | 13 ++++++------- crates/ra_hir_expand/src/lib.rs | 10 ++++++++-- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index f3bccd8ed75..540ddd0b5de 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -91,7 +91,7 @@ fn def_with_body_from_child_node( #[derive(Debug)] pub struct SourceAnalyzer { // FIXME: this doesn't handle macros at all - file_id: FileId, + file_id: HirFileId, resolver: Resolver, body_owner: Option, body_source_map: Option>, @@ -159,7 +159,7 @@ impl SourceAnalyzer { body_source_map: Some(source_map), infer: Some(def.infer(db)), scopes: Some(scopes), - file_id, + file_id: file_id.into(), } } else { SourceAnalyzer { @@ -171,18 +171,18 @@ impl SourceAnalyzer { body_source_map: None, infer: None, scopes: None, - file_id, + file_id: file_id.into(), } } } fn expr_id(&self, expr: &ast::Expr) -> Option { - let src = Source { file_id: self.file_id.into(), ast: expr }; + let src = Source { file_id: self.file_id, ast: expr }; self.body_source_map.as_ref()?.node_expr(src) } fn pat_id(&self, pat: &ast::Pat) -> Option { - let src = Source { file_id: self.file_id.into(), ast: pat }; + let src = Source { file_id: self.file_id, ast: pat }; self.body_source_map.as_ref()?.node_pat(src) } @@ -290,8 +290,7 @@ impl SourceAnalyzer { let name = name_ref.as_name(); let source_map = self.body_source_map.as_ref()?; let scopes = self.scopes.as_ref()?; - let scope = - scope_for(scopes, source_map, Source::new(self.file_id.into(), name_ref.syntax()))?; + let scope = scope_for(scopes, source_map, Source::new(self.file_id, name_ref.syntax()))?; let entry = scopes.resolve_name_in_scope(scope, &name)?; Some(ScopeEntryWithSyntax { name: entry.name().clone(), diff --git a/crates/ra_hir_expand/src/lib.rs b/crates/ra_hir_expand/src/lib.rs index 6c2cc3af3ea..26531cb05e0 100644 --- a/crates/ra_hir_expand/src/lib.rs +++ b/crates/ra_hir_expand/src/lib.rs @@ -223,6 +223,7 @@ impl AstId { } } +/// FIXME: https://github.com/matklad/with ? #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)] pub struct Source { pub file_id: HirFileId, @@ -236,11 +237,16 @@ impl Source { Source { file_id, ast } } + // Similarly, naming here is stupid... + pub fn with_ast(&self, ast: U) -> Source { + Source::new(self.file_id, ast) + } + pub fn map U, U>(self, f: F) -> Source { - Source { file_id: self.file_id, ast: f(self.ast) } + Source::new(self.file_id, f(self.ast)) } pub fn as_ref(&self) -> Source<&T> { - Source { file_id: self.file_id, ast: &self.ast } + self.with_ast(&self.ast) } pub fn file_syntax(&self, db: &impl db::AstDatabase) -> SyntaxNode { db.parse_or_expand(self.file_id).expect("source created from invalid file")