From debf95eb1b79a54ed482ea01f1716e5ff1faf0b6 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 14 Nov 2019 09:24:39 +0300 Subject: Reduce visibility --- crates/ra_hir_def/src/body.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs index ac8f8261b..269501221 100644 --- a/crates/ra_hir_def/src/body.rs +++ b/crates/ra_hir_def/src/body.rs @@ -26,11 +26,7 @@ impl MacroResolver { MacroResolver { crate_def_map: db.crate_def_map(module.krate), module } } - pub(crate) fn resolve_path_as_macro( - &self, - db: &impl DefDatabase2, - path: &Path, - ) -> Option { + fn resolve_path_as_macro(&self, db: &impl DefDatabase2, path: &Path) -> Option { self.crate_def_map.resolve_path(db, self.module.module_id, path).0.get_macros() } } -- cgit v1.2.3 From b3175b7077129ca4b6c52e05f0491e65617ae423 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 14 Nov 2019 09:37:33 +0300 Subject: Move current file to MacroResolver --- crates/ra_hir/src/expr.rs | 4 ++-- crates/ra_hir_def/src/body.rs | 13 +++++++++---- crates/ra_hir_def/src/body/lower.rs | 31 ++++++++++++++++--------------- 3 files changed, 27 insertions(+), 21 deletions(-) diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 82955fa55..d1af8ee39 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs @@ -40,8 +40,8 @@ pub(crate) fn body_with_source_map_query( (src.file_id, src.ast.body()) } }; - let resolver = hir_def::body::MacroResolver::new(db, def.module(db).id); - let (body, source_map) = Body::new(db, resolver, file_id, params, body); + let resolver = hir_def::body::MacroResolver::new(db, file_id, def.module(db).id); + let (body, source_map) = Body::new(db, resolver, params, body); (Arc::new(body), Arc::new(source_map)) } diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs index 269501221..7e84e9113 100644 --- a/crates/ra_hir_def/src/body.rs +++ b/crates/ra_hir_def/src/body.rs @@ -18,12 +18,18 @@ use crate::{ pub struct MacroResolver { crate_def_map: Arc, + current_file_id: HirFileId, module: ModuleId, } impl MacroResolver { - pub fn new(db: &impl DefDatabase2, module: ModuleId) -> MacroResolver { - MacroResolver { crate_def_map: db.crate_def_map(module.krate), module } + pub fn new( + db: &impl DefDatabase2, + current_file_id: HirFileId, + module: ModuleId, + ) -> MacroResolver { + let crate_def_map = db.crate_def_map(module.krate); + MacroResolver { crate_def_map, current_file_id, module } } fn resolve_path_as_macro(&self, db: &impl DefDatabase2, path: &Path) -> Option { @@ -77,11 +83,10 @@ impl Body { pub fn new( db: &impl DefDatabase2, resolver: MacroResolver, - file_id: HirFileId, params: Option, body: Option, ) -> (Body, BodySourceMap) { - lower::lower(db, resolver, file_id, params, body) + lower::lower(db, resolver, params, body) } pub fn params(&self) -> &[PatId] { diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index 2aa863c9e..1a990101f 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -31,15 +31,15 @@ use crate::{ pub(super) fn lower( db: &impl DefDatabase2, resolver: MacroResolver, - file_id: HirFileId, params: Option, body: Option, ) -> (Body, BodySourceMap) { + let original_file_id = resolver.current_file_id; + ExprCollector { resolver, db, - original_file_id: file_id, - current_file_id: file_id, + original_file_id, source_map: BodySourceMap::default(), body: Body { exprs: Arena::default(), @@ -55,7 +55,6 @@ struct ExprCollector { db: DB, resolver: MacroResolver, original_file_id: HirFileId, - current_file_id: HirFileId, body: Body, source_map: BodySourceMap, @@ -101,12 +100,12 @@ where fn alloc_expr(&mut self, expr: Expr, ptr: AstPtr) -> ExprId { let ptr = Either::A(ptr); let id = self.body.exprs.alloc(expr); - if self.current_file_id == self.original_file_id { + if self.resolver.current_file_id == self.original_file_id { self.source_map.expr_map.insert(ptr, id); } self.source_map .expr_map_back - .insert(id, Source { file_id: self.current_file_id, ast: ptr }); + .insert(id, Source { file_id: self.resolver.current_file_id, ast: ptr }); id } // desugared exprs don't have ptr, that's wrong and should be fixed @@ -117,20 +116,22 @@ where fn alloc_expr_field_shorthand(&mut self, expr: Expr, ptr: AstPtr) -> ExprId { let ptr = Either::B(ptr); let id = self.body.exprs.alloc(expr); - if self.current_file_id == self.original_file_id { + if self.resolver.current_file_id == self.original_file_id { self.source_map.expr_map.insert(ptr, id); } self.source_map .expr_map_back - .insert(id, Source { file_id: self.current_file_id, ast: ptr }); + .insert(id, Source { file_id: self.resolver.current_file_id, ast: ptr }); id } fn alloc_pat(&mut self, pat: Pat, ptr: PatPtr) -> PatId { let id = self.body.pats.alloc(pat); - if self.current_file_id == self.original_file_id { + if self.resolver.current_file_id == self.original_file_id { self.source_map.pat_map.insert(ptr, id); } - self.source_map.pat_map_back.insert(id, Source { file_id: self.current_file_id, ast: ptr }); + self.source_map + .pat_map_back + .insert(id, Source { file_id: self.resolver.current_file_id, ast: ptr }); id } @@ -445,8 +446,8 @@ where ast::Expr::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), ast::Expr::MacroCall(e) => { let ast_id = AstId::new( - self.current_file_id, - self.db.ast_id_map(self.current_file_id).ast_id(&e), + self.resolver.current_file_id, + self.db.ast_id_map(self.resolver.current_file_id).ast_id(&e), ); if let Some(path) = e.path().and_then(|path| self.parse_path(path)) { @@ -457,9 +458,9 @@ where if let Some(expr) = ast::Expr::cast(node) { log::debug!("macro expansion {:#?}", expr.syntax()); let old_file_id = - std::mem::replace(&mut self.current_file_id, file_id); + std::mem::replace(&mut self.resolver.current_file_id, file_id); let id = self.collect_expr(expr); - self.current_file_id = old_file_id; + self.resolver.current_file_id = old_file_id; return id; } } @@ -581,7 +582,7 @@ where } fn parse_path(&mut self, path: ast::Path) -> Option { - let hygiene = Hygiene::new(self.db, self.current_file_id); + let hygiene = Hygiene::new(self.db, self.resolver.current_file_id); Path::from_src(path, &hygiene) } } -- cgit v1.2.3 From 8c8ef1432e1891809f48ff691f949047d6527c07 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 14 Nov 2019 09:38:25 +0300 Subject: Rename MacroResolver -> Expander --- crates/ra_hir/src/expr.rs | 4 ++-- crates/ra_hir_def/src/body.rs | 16 ++++++---------- crates/ra_hir_def/src/body/lower.rs | 34 +++++++++++++++++----------------- 3 files changed, 25 insertions(+), 29 deletions(-) diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index d1af8ee39..d19f5d14c 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs @@ -40,8 +40,8 @@ pub(crate) fn body_with_source_map_query( (src.file_id, src.ast.body()) } }; - let resolver = hir_def::body::MacroResolver::new(db, file_id, def.module(db).id); - let (body, source_map) = Body::new(db, resolver, params, body); + let expander = hir_def::body::Expander::new(db, file_id, def.module(db).id); + let (body, source_map) = Body::new(db, expander, params, body); (Arc::new(body), Arc::new(source_map)) } diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs index 7e84e9113..5d8c299ba 100644 --- a/crates/ra_hir_def/src/body.rs +++ b/crates/ra_hir_def/src/body.rs @@ -16,20 +16,16 @@ use crate::{ ModuleId, }; -pub struct MacroResolver { +pub struct Expander { crate_def_map: Arc, current_file_id: HirFileId, module: ModuleId, } -impl MacroResolver { - pub fn new( - db: &impl DefDatabase2, - current_file_id: HirFileId, - module: ModuleId, - ) -> MacroResolver { +impl Expander { + pub fn new(db: &impl DefDatabase2, current_file_id: HirFileId, module: ModuleId) -> Expander { let crate_def_map = db.crate_def_map(module.krate); - MacroResolver { crate_def_map, current_file_id, module } + Expander { crate_def_map, current_file_id, module } } fn resolve_path_as_macro(&self, db: &impl DefDatabase2, path: &Path) -> Option { @@ -82,11 +78,11 @@ pub struct BodySourceMap { impl Body { pub fn new( db: &impl DefDatabase2, - resolver: MacroResolver, + expander: Expander, params: Option, body: Option, ) -> (Body, BodySourceMap) { - lower::lower(db, resolver, params, body) + lower::lower(db, expander, params, body) } pub fn params(&self) -> &[PatId] { diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index 1a990101f..cc4bbe11a 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -16,7 +16,7 @@ use ra_syntax::{ }; use crate::{ - body::{Body, BodySourceMap, MacroResolver, PatPtr}, + body::{Body, BodySourceMap, Expander, PatPtr}, builtin_type::{BuiltinFloat, BuiltinInt}, db::DefDatabase2, expr::{ @@ -30,14 +30,14 @@ use crate::{ pub(super) fn lower( db: &impl DefDatabase2, - resolver: MacroResolver, + expander: Expander, params: Option, body: Option, ) -> (Body, BodySourceMap) { - let original_file_id = resolver.current_file_id; + let original_file_id = expander.current_file_id; ExprCollector { - resolver, + expander, db, original_file_id, source_map: BodySourceMap::default(), @@ -53,7 +53,7 @@ pub(super) fn lower( struct ExprCollector { db: DB, - resolver: MacroResolver, + expander: Expander, original_file_id: HirFileId, body: Body, @@ -100,12 +100,12 @@ where fn alloc_expr(&mut self, expr: Expr, ptr: AstPtr) -> ExprId { let ptr = Either::A(ptr); let id = self.body.exprs.alloc(expr); - if self.resolver.current_file_id == self.original_file_id { + if self.expander.current_file_id == self.original_file_id { self.source_map.expr_map.insert(ptr, id); } self.source_map .expr_map_back - .insert(id, Source { file_id: self.resolver.current_file_id, ast: ptr }); + .insert(id, Source { file_id: self.expander.current_file_id, ast: ptr }); id } // desugared exprs don't have ptr, that's wrong and should be fixed @@ -116,22 +116,22 @@ where fn alloc_expr_field_shorthand(&mut self, expr: Expr, ptr: AstPtr) -> ExprId { let ptr = Either::B(ptr); let id = self.body.exprs.alloc(expr); - if self.resolver.current_file_id == self.original_file_id { + if self.expander.current_file_id == self.original_file_id { self.source_map.expr_map.insert(ptr, id); } self.source_map .expr_map_back - .insert(id, Source { file_id: self.resolver.current_file_id, ast: ptr }); + .insert(id, Source { file_id: self.expander.current_file_id, ast: ptr }); id } fn alloc_pat(&mut self, pat: Pat, ptr: PatPtr) -> PatId { let id = self.body.pats.alloc(pat); - if self.resolver.current_file_id == self.original_file_id { + if self.expander.current_file_id == self.original_file_id { self.source_map.pat_map.insert(ptr, id); } self.source_map .pat_map_back - .insert(id, Source { file_id: self.resolver.current_file_id, ast: ptr }); + .insert(id, Source { file_id: self.expander.current_file_id, ast: ptr }); id } @@ -446,21 +446,21 @@ where ast::Expr::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), ast::Expr::MacroCall(e) => { let ast_id = AstId::new( - self.resolver.current_file_id, - self.db.ast_id_map(self.resolver.current_file_id).ast_id(&e), + self.expander.current_file_id, + self.db.ast_id_map(self.expander.current_file_id).ast_id(&e), ); if let Some(path) = e.path().and_then(|path| self.parse_path(path)) { - if let Some(def) = self.resolver.resolve_path_as_macro(self.db, &path) { + if let Some(def) = self.expander.resolve_path_as_macro(self.db, &path) { let call_id = self.db.intern_macro(MacroCallLoc { def, ast_id }); let file_id = call_id.as_file(MacroFileKind::Expr); if let Some(node) = self.db.parse_or_expand(file_id) { if let Some(expr) = ast::Expr::cast(node) { log::debug!("macro expansion {:#?}", expr.syntax()); let old_file_id = - std::mem::replace(&mut self.resolver.current_file_id, file_id); + std::mem::replace(&mut self.expander.current_file_id, file_id); let id = self.collect_expr(expr); - self.resolver.current_file_id = old_file_id; + self.expander.current_file_id = old_file_id; return id; } } @@ -582,7 +582,7 @@ where } fn parse_path(&mut self, path: ast::Path) -> Option { - let hygiene = Hygiene::new(self.db, self.resolver.current_file_id); + let hygiene = Hygiene::new(self.db, self.expander.current_file_id); Path::from_src(path, &hygiene) } } -- cgit v1.2.3 From e7e85c60d2c225eacc80184a7918ecf6c8ab0563 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 14 Nov 2019 09:41:46 +0300 Subject: Move original_file to Expander --- crates/ra_hir_def/src/body.rs | 8 +++++++- crates/ra_hir_def/src/body/lower.rs | 12 ++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs index 5d8c299ba..1c9c86449 100644 --- a/crates/ra_hir_def/src/body.rs +++ b/crates/ra_hir_def/src/body.rs @@ -18,6 +18,7 @@ use crate::{ pub struct Expander { crate_def_map: Arc, + original_file_id: HirFileId, current_file_id: HirFileId, module: ModuleId, } @@ -25,7 +26,12 @@ pub struct Expander { impl Expander { pub fn new(db: &impl DefDatabase2, current_file_id: HirFileId, module: ModuleId) -> Expander { let crate_def_map = db.crate_def_map(module.krate); - Expander { crate_def_map, current_file_id, module } + Expander { crate_def_map, original_file_id: current_file_id, current_file_id, module } + } + + // FIXME: remove this. + fn is_in_expansion(&self) -> bool { + self.original_file_id != self.current_file_id } fn resolve_path_as_macro(&self, db: &impl DefDatabase2, path: &Path) -> Option { diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index cc4bbe11a..602bcb220 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -4,7 +4,7 @@ use hir_expand::{ either::Either, hygiene::Hygiene, name::{self, AsName, Name}, - AstId, HirFileId, MacroCallLoc, MacroFileKind, Source, + AstId, MacroCallLoc, MacroFileKind, Source, }; use ra_arena::Arena; use ra_syntax::{ @@ -34,12 +34,9 @@ pub(super) fn lower( params: Option, body: Option, ) -> (Body, BodySourceMap) { - let original_file_id = expander.current_file_id; - ExprCollector { expander, db, - original_file_id, source_map: BodySourceMap::default(), body: Body { exprs: Arena::default(), @@ -54,7 +51,6 @@ pub(super) fn lower( struct ExprCollector { db: DB, expander: Expander, - original_file_id: HirFileId, body: Body, source_map: BodySourceMap, @@ -100,7 +96,7 @@ where fn alloc_expr(&mut self, expr: Expr, ptr: AstPtr) -> ExprId { let ptr = Either::A(ptr); let id = self.body.exprs.alloc(expr); - if self.expander.current_file_id == self.original_file_id { + if !self.expander.is_in_expansion() { self.source_map.expr_map.insert(ptr, id); } self.source_map @@ -116,7 +112,7 @@ where fn alloc_expr_field_shorthand(&mut self, expr: Expr, ptr: AstPtr) -> ExprId { let ptr = Either::B(ptr); let id = self.body.exprs.alloc(expr); - if self.expander.current_file_id == self.original_file_id { + if !self.expander.is_in_expansion() { self.source_map.expr_map.insert(ptr, id); } self.source_map @@ -126,7 +122,7 @@ where } fn alloc_pat(&mut self, pat: Pat, ptr: PatPtr) -> PatId { let id = self.body.pats.alloc(pat); - if self.expander.current_file_id == self.original_file_id { + if !self.expander.is_in_expansion() { self.source_map.pat_map.insert(ptr, id); } self.source_map -- cgit v1.2.3 From c89010df2d586eec33b50f3afcc4b2226da32672 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 14 Nov 2019 09:43:59 +0300 Subject: Add Expader::to_source --- crates/ra_hir_def/src/body.rs | 4 ++++ crates/ra_hir_def/src/body/lower.rs | 14 ++++---------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs index 1c9c86449..622c836d1 100644 --- a/crates/ra_hir_def/src/body.rs +++ b/crates/ra_hir_def/src/body.rs @@ -34,6 +34,10 @@ impl Expander { self.original_file_id != self.current_file_id } + fn to_source(&self, ast: T) -> Source { + Source { file_id: self.current_file_id, ast } + } + fn resolve_path_as_macro(&self, db: &impl DefDatabase2, path: &Path) -> Option { self.crate_def_map.resolve_path(db, self.module.module_id, path).0.get_macros() } diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index 602bcb220..1ea8ce249 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -4,7 +4,7 @@ use hir_expand::{ either::Either, hygiene::Hygiene, name::{self, AsName, Name}, - AstId, MacroCallLoc, MacroFileKind, Source, + AstId, MacroCallLoc, MacroFileKind, }; use ra_arena::Arena; use ra_syntax::{ @@ -99,9 +99,7 @@ where if !self.expander.is_in_expansion() { self.source_map.expr_map.insert(ptr, id); } - self.source_map - .expr_map_back - .insert(id, Source { file_id: self.expander.current_file_id, ast: ptr }); + self.source_map.expr_map_back.insert(id, self.expander.to_source(ptr)); id } // desugared exprs don't have ptr, that's wrong and should be fixed @@ -115,9 +113,7 @@ where if !self.expander.is_in_expansion() { self.source_map.expr_map.insert(ptr, id); } - self.source_map - .expr_map_back - .insert(id, Source { file_id: self.expander.current_file_id, ast: ptr }); + self.source_map.expr_map_back.insert(id, self.expander.to_source(ptr)); id } fn alloc_pat(&mut self, pat: Pat, ptr: PatPtr) -> PatId { @@ -125,9 +121,7 @@ where if !self.expander.is_in_expansion() { self.source_map.pat_map.insert(ptr, id); } - self.source_map - .pat_map_back - .insert(id, Source { file_id: self.expander.current_file_id, ast: ptr }); + self.source_map.pat_map_back.insert(id, self.expander.to_source(ptr)); id } -- cgit v1.2.3 From e7880db1d0f75c639ee561b586219648bd05c21c Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 14 Nov 2019 09:52:03 +0300 Subject: Expansion stack scaffold --- crates/ra_hir_def/src/body.rs | 37 +++++++++++++++++++++++++++++++++++-- crates/ra_hir_def/src/body/lower.rs | 9 +++------ 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs index 622c836d1..3b262e3bd 100644 --- a/crates/ra_hir_def/src/body.rs +++ b/crates/ra_hir_def/src/body.rs @@ -3,7 +3,7 @@ mod lower; use std::{ops::Index, sync::Arc}; -use hir_expand::{either::Either, HirFileId, MacroDefId, Source}; +use hir_expand::{either::Either, hygiene::Hygiene, HirFileId, MacroDefId, Source}; use ra_arena::{map::ArenaMap, Arena}; use ra_syntax::{ast, AstPtr}; use rustc_hash::FxHashMap; @@ -20,13 +20,34 @@ pub struct Expander { crate_def_map: Arc, original_file_id: HirFileId, current_file_id: HirFileId, + hygiene: Hygiene, module: ModuleId, } impl Expander { pub fn new(db: &impl DefDatabase2, current_file_id: HirFileId, module: ModuleId) -> Expander { let crate_def_map = db.crate_def_map(module.krate); - Expander { crate_def_map, original_file_id: current_file_id, current_file_id, module } + let hygiene = Hygiene::new(db, current_file_id); + Expander { + crate_def_map, + original_file_id: current_file_id, + current_file_id, + hygiene, + module, + } + } + + fn enter(&mut self, db: &impl DefDatabase2, file_id: HirFileId) -> Mark { + let mark = Mark { file_id: self.current_file_id }; + self.hygiene = Hygiene::new(db, file_id); + self.current_file_id = file_id; + mark + } + + fn exit(&mut self, db: &impl DefDatabase2, mark: Mark) { + self.hygiene = Hygiene::new(db, mark.file_id); + self.current_file_id = mark.file_id; + std::mem::forget(mark); } // FIXME: remove this. @@ -43,6 +64,18 @@ impl Expander { } } +struct Mark { + file_id: HirFileId, +} + +impl Drop for Mark { + fn drop(&mut self) { + if !std::thread::panicking() { + panic!("dropped mark") + } + } +} + /// The body of an item (function, const etc.). #[derive(Debug, Eq, PartialEq)] pub struct Body { diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index 1ea8ce249..5c291421a 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -2,7 +2,6 @@ use hir_expand::{ either::Either, - hygiene::Hygiene, name::{self, AsName, Name}, AstId, MacroCallLoc, MacroFileKind, }; @@ -447,10 +446,9 @@ where if let Some(node) = self.db.parse_or_expand(file_id) { if let Some(expr) = ast::Expr::cast(node) { log::debug!("macro expansion {:#?}", expr.syntax()); - let old_file_id = - std::mem::replace(&mut self.expander.current_file_id, file_id); + let mark = self.expander.enter(self.db, file_id); let id = self.collect_expr(expr); - self.expander.current_file_id = old_file_id; + self.expander.exit(self.db, mark); return id; } } @@ -572,8 +570,7 @@ where } fn parse_path(&mut self, path: ast::Path) -> Option { - let hygiene = Hygiene::new(self.db, self.expander.current_file_id); - Path::from_src(path, &hygiene) + Path::from_src(path, &self.expander.hygiene) } } -- cgit v1.2.3 From 5c720b256f5d73434250072cc65fead746250d87 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 14 Nov 2019 09:58:39 +0300 Subject: Move parse_path to Expander --- crates/ra_hir_def/src/body.rs | 4 ++++ crates/ra_hir_def/src/body/lower.rs | 16 ++++++---------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs index 3b262e3bd..afceeb8de 100644 --- a/crates/ra_hir_def/src/body.rs +++ b/crates/ra_hir_def/src/body.rs @@ -59,6 +59,10 @@ impl Expander { Source { file_id: self.current_file_id, ast } } + fn parse_path(&mut self, path: ast::Path) -> Option { + Path::from_src(path, &self.hygiene) + } + fn resolve_path_as_macro(&self, db: &impl DefDatabase2, path: &Path) -> Option { self.crate_def_map.resolve_path(db, self.module.module_id, path).0.get_macros() } diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index 5c291421a..29c1ec2a1 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -262,7 +262,7 @@ where ast::Expr::PathExpr(e) => { let path = e .path() - .and_then(|path| self.parse_path(path)) + .and_then(|path| self.expander.parse_path(path)) .map(Expr::Path) .unwrap_or(Expr::Missing); self.alloc_expr(path, syntax_ptr) @@ -286,7 +286,7 @@ where self.alloc_expr(Expr::Return { expr }, syntax_ptr) } ast::Expr::RecordLit(e) => { - let path = e.path().and_then(|path| self.parse_path(path)); + let path = e.path().and_then(|path| self.expander.parse_path(path)); let mut field_ptrs = Vec::new(); let record_lit = if let Some(nfl) = e.record_field_list() { let fields = nfl @@ -439,7 +439,7 @@ where self.db.ast_id_map(self.expander.current_file_id).ast_id(&e), ); - if let Some(path) = e.path().and_then(|path| self.parse_path(path)) { + if let Some(path) = e.path().and_then(|path| self.expander.parse_path(path)) { if let Some(def) = self.expander.resolve_path_as_macro(self.db, &path) { let call_id = self.db.intern_macro(MacroCallLoc { def, ast_id }); let file_id = call_id.as_file(MacroFileKind::Expr); @@ -508,7 +508,7 @@ where Pat::Bind { name, mode: annotation, subpat } } ast::Pat::TupleStructPat(p) => { - let path = p.path().and_then(|path| self.parse_path(path)); + let path = p.path().and_then(|path| self.expander.parse_path(path)); let args = p.args().map(|p| self.collect_pat(p)).collect(); Pat::TupleStruct { path, args } } @@ -518,7 +518,7 @@ where Pat::Ref { pat, mutability } } ast::Pat::PathPat(p) => { - let path = p.path().and_then(|path| self.parse_path(path)); + let path = p.path().and_then(|path| self.expander.parse_path(path)); path.map(Pat::Path).unwrap_or(Pat::Missing) } ast::Pat::TuplePat(p) => { @@ -527,7 +527,7 @@ where } ast::Pat::PlaceholderPat(_) => Pat::Wild, ast::Pat::RecordPat(p) => { - let path = p.path().and_then(|path| self.parse_path(path)); + let path = p.path().and_then(|path| self.expander.parse_path(path)); let record_field_pat_list = p.record_field_pat_list().expect("every struct should have a field list"); let mut fields: Vec<_> = record_field_pat_list @@ -568,10 +568,6 @@ where self.missing_pat() } } - - fn parse_path(&mut self, path: ast::Path) -> Option { - Path::from_src(path, &self.expander.hygiene) - } } impl From for BinaryOp { -- cgit v1.2.3 From a73b7bb3f6af134c781cba1126350749c5a91144 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 14 Nov 2019 10:04:39 +0300 Subject: Move expansion to Expander --- crates/ra_hir_def/src/body.rs | 36 ++++++++++++++++++++++++++++++++++-- crates/ra_hir_def/src/body/lower.rs | 32 +++++++------------------------- 2 files changed, 41 insertions(+), 27 deletions(-) diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs index afceeb8de..65fefd912 100644 --- a/crates/ra_hir_def/src/body.rs +++ b/crates/ra_hir_def/src/body.rs @@ -3,9 +3,12 @@ mod lower; use std::{ops::Index, sync::Arc}; -use hir_expand::{either::Either, hygiene::Hygiene, HirFileId, MacroDefId, Source}; +use hir_expand::{ + either::Either, hygiene::Hygiene, AstId, HirFileId, MacroCallLoc, MacroDefId, MacroFileKind, + Source, +}; use ra_arena::{map::ArenaMap, Arena}; -use ra_syntax::{ast, AstPtr}; +use ra_syntax::{ast, AstNode, AstPtr}; use rustc_hash::FxHashMap; use crate::{ @@ -37,6 +40,35 @@ impl Expander { } } + fn expand( + &mut self, + db: &impl DefDatabase2, + macro_call: ast::MacroCall, + ) -> Option<(Mark, ast::Expr)> { + let ast_id = AstId::new( + self.current_file_id, + db.ast_id_map(self.current_file_id).ast_id(¯o_call), + ); + + if let Some(path) = macro_call.path().and_then(|path| self.parse_path(path)) { + if let Some(def) = self.resolve_path_as_macro(db, &path) { + let call_id = db.intern_macro(MacroCallLoc { def, ast_id }); + let file_id = call_id.as_file(MacroFileKind::Expr); + if let Some(node) = db.parse_or_expand(file_id) { + if let Some(expr) = ast::Expr::cast(node) { + log::debug!("macro expansion {:#?}", expr.syntax()); + let mark = self.enter(db, file_id); + return Some((mark, expr)); + } + } + } + } + + // FIXME: Instead of just dropping the error from expansion + // report it + None + } + fn enter(&mut self, db: &impl DefDatabase2, file_id: HirFileId) -> Mark { let mark = Mark { file_id: self.current_file_id }; self.hygiene = Hygiene::new(db, file_id); diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index 29c1ec2a1..c45500195 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -3,7 +3,6 @@ use hir_expand::{ either::Either, name::{self, AsName, Name}, - AstId, MacroCallLoc, MacroFileKind, }; use ra_arena::Arena; use ra_syntax::{ @@ -433,31 +432,14 @@ where // FIXME implement HIR for these: ast::Expr::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), ast::Expr::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), - ast::Expr::MacroCall(e) => { - let ast_id = AstId::new( - self.expander.current_file_id, - self.db.ast_id_map(self.expander.current_file_id).ast_id(&e), - ); - - if let Some(path) = e.path().and_then(|path| self.expander.parse_path(path)) { - if let Some(def) = self.expander.resolve_path_as_macro(self.db, &path) { - let call_id = self.db.intern_macro(MacroCallLoc { def, ast_id }); - let file_id = call_id.as_file(MacroFileKind::Expr); - if let Some(node) = self.db.parse_or_expand(file_id) { - if let Some(expr) = ast::Expr::cast(node) { - log::debug!("macro expansion {:#?}", expr.syntax()); - let mark = self.expander.enter(self.db, file_id); - let id = self.collect_expr(expr); - self.expander.exit(self.db, mark); - return id; - } - } - } + ast::Expr::MacroCall(e) => match self.expander.expand(self.db, e) { + Some((mark, expansion)) => { + let id = self.collect_expr(expansion); + self.expander.exit(self.db, mark); + id } - // FIXME: Instead of just dropping the error from expansion - // report it - self.alloc_expr(Expr::Missing, syntax_ptr) - } + None => self.alloc_expr(Expr::Missing, syntax_ptr), + }, } } -- cgit v1.2.3 From da2ca01ebaaaaa47aa09c5848c53b145a68af8fa Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 14 Nov 2019 10:30:30 +0300 Subject: Handle macro-generated expressions slightly less wrong --- crates/ra_hir/src/expr/scope.rs | 6 ++++- crates/ra_hir/src/from_source.rs | 3 ++- crates/ra_hir/src/source_binder.rs | 44 ++++++++++++++++++++++++++----------- crates/ra_hir_def/src/body.rs | 28 ++++++++--------------- crates/ra_hir_def/src/body/lower.rs | 24 ++++++++++---------- crates/ra_hir_expand/src/lib.rs | 5 ++++- 6 files changed, 62 insertions(+), 48 deletions(-) diff --git a/crates/ra_hir/src/expr/scope.rs b/crates/ra_hir/src/expr/scope.rs index fe5e836f2..afba66069 100644 --- a/crates/ra_hir/src/expr/scope.rs +++ b/crates/ra_hir/src/expr/scope.rs @@ -166,6 +166,7 @@ fn compute_expr_scopes(expr: ExprId, body: &Body, scopes: &mut ExprScopes, scope #[cfg(test)] mod tests { + use hir_expand::Source; use ra_db::{fixture::WithFixture, SourceDatabase}; use ra_syntax::{algo::find_node_at_offset, ast, AstNode}; use test_utils::{assert_eq_text, extract_offset}; @@ -189,7 +190,10 @@ mod tests { let analyzer = SourceAnalyzer::new(&db, file_id, marker.syntax(), None); let scopes = analyzer.scopes(); - let expr_id = analyzer.body_source_map().node_expr(&marker.into()).unwrap(); + let expr_id = analyzer + .body_source_map() + .node_expr(Source { file_id: file_id.into(), ast: &marker.into() }) + .unwrap(); let scope = scopes.scope_for(expr_id); let actual = scopes diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs index 2c441b0f4..4b561c63d 100644 --- a/crates/ra_hir/src/from_source.rs +++ b/crates/ra_hir/src/from_source.rs @@ -145,7 +145,8 @@ impl Local { Some(res) })?; let (_body, source_map) = db.body_with_source_map(parent); - let pat_id = source_map.node_pat(&src.ast.into())?; + let src = src.map(ast::Pat::from); + let pat_id = source_map.node_pat(src.as_ref())?; Some(Local { parent, pat_id }) } } diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index f28e9c931..88eed1137 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -7,8 +7,11 @@ //! purely for "IDE needs". use std::sync::Arc; -use hir_def::path::known; -use hir_expand::name::AsName; +use hir_def::{ + expr::{ExprId, PatId}, + path::known, +}; +use hir_expand::{name::AsName, Source}; use ra_db::FileId; use ra_syntax::{ ast::{self, AstNode}, @@ -93,6 +96,8 @@ fn def_with_body_from_child_node( /// original source files. It should not be used inside the HIR itself. #[derive(Debug)] pub struct SourceAnalyzer { + // FIXME: this doesn't handle macros at all + file_id: FileId, resolver: Resolver, body_owner: Option, body_source_map: Option>, @@ -147,7 +152,7 @@ impl SourceAnalyzer { let source_map = def.body_source_map(db); let scopes = db.expr_scopes(def); let scope = match offset { - None => scope_for(&scopes, &source_map, &node), + None => scope_for(&scopes, &source_map, file_id.into(), &node), Some(offset) => scope_for_offset(&scopes, &source_map, file_id.into(), offset), }; let resolver = expr::resolver_for_scope(db, def, scope); @@ -157,6 +162,7 @@ impl SourceAnalyzer { body_source_map: Some(source_map), infer: Some(def.infer(db)), scopes: Some(scopes), + file_id, } } else { SourceAnalyzer { @@ -168,17 +174,28 @@ impl SourceAnalyzer { body_source_map: None, infer: None, scopes: None, + file_id, } } } + fn expr_id(&self, expr: &ast::Expr) -> Option { + let src = Source { file_id: self.file_id.into(), 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 }; + self.body_source_map.as_ref()?.node_pat(src) + } + pub fn type_of(&self, _db: &impl HirDatabase, expr: &ast::Expr) -> Option { - let expr_id = self.body_source_map.as_ref()?.node_expr(expr)?; + let expr_id = self.expr_id(expr)?; Some(self.infer.as_ref()?[expr_id].clone()) } pub fn type_of_pat(&self, _db: &impl HirDatabase, pat: &ast::Pat) -> Option { - let pat_id = self.body_source_map.as_ref()?.node_pat(pat)?; + let pat_id = self.pat_id(pat)?; Some(self.infer.as_ref()?[pat_id].clone()) } @@ -191,22 +208,22 @@ impl SourceAnalyzer { } pub fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option { - let expr_id = self.body_source_map.as_ref()?.node_expr(&call.clone().into())?; + let expr_id = self.expr_id(&call.clone().into())?; self.infer.as_ref()?.method_resolution(expr_id) } pub fn resolve_field(&self, field: &ast::FieldExpr) -> Option { - let expr_id = self.body_source_map.as_ref()?.node_expr(&field.clone().into())?; + let expr_id = self.expr_id(&field.clone().into())?; self.infer.as_ref()?.field_resolution(expr_id) } pub fn resolve_record_literal(&self, record_lit: &ast::RecordLit) -> Option { - let expr_id = self.body_source_map.as_ref()?.node_expr(&record_lit.clone().into())?; + let expr_id = self.expr_id(&record_lit.clone().into())?; self.infer.as_ref()?.variant_resolution_for_expr(expr_id) } pub fn resolve_record_pattern(&self, record_pat: &ast::RecordPat) -> Option { - let pat_id = self.body_source_map.as_ref()?.node_pat(&record_pat.clone().into())?; + let pat_id = self.pat_id(&record_pat.clone().into())?; self.infer.as_ref()?.variant_resolution_for_pat(pat_id) } @@ -264,13 +281,13 @@ impl SourceAnalyzer { pub fn resolve_path(&self, db: &impl HirDatabase, path: &ast::Path) -> Option { if let Some(path_expr) = path.syntax().parent().and_then(ast::PathExpr::cast) { - let expr_id = self.body_source_map.as_ref()?.node_expr(&path_expr.into())?; + let expr_id = self.expr_id(&path_expr.into())?; if let Some(assoc) = self.infer.as_ref()?.assoc_resolutions_for_expr(expr_id) { return Some(PathResolution::AssocItem(assoc)); } } if let Some(path_pat) = path.syntax().parent().and_then(ast::PathPat::cast) { - let pat_id = self.body_source_map.as_ref()?.node_pat(&path_pat.into())?; + let pat_id = self.pat_id(&path_pat.into())?; if let Some(assoc) = self.infer.as_ref()?.assoc_resolutions_for_pat(pat_id) { return Some(PathResolution::AssocItem(assoc)); } @@ -285,7 +302,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, name_ref.syntax()); + let scope = scope_for(scopes, source_map, self.file_id.into(), name_ref.syntax()); let ret = scopes .scope_chain(scope) .flat_map(|scope| scopes.entries(scope).iter()) @@ -418,11 +435,12 @@ impl SourceAnalyzer { fn scope_for( scopes: &ExprScopes, source_map: &BodySourceMap, + file_id: HirFileId, node: &SyntaxNode, ) -> Option { node.ancestors() .filter_map(ast::Expr::cast) - .filter_map(|it| source_map.node_expr(&it)) + .filter_map(|it| source_map.node_expr(Source { file_id, ast: &it })) .find_map(|it| scopes.scope_for(it)) } diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs index 65fefd912..75bba31c2 100644 --- a/crates/ra_hir_def/src/body.rs +++ b/crates/ra_hir_def/src/body.rs @@ -21,7 +21,6 @@ use crate::{ pub struct Expander { crate_def_map: Arc, - original_file_id: HirFileId, current_file_id: HirFileId, hygiene: Hygiene, module: ModuleId, @@ -31,13 +30,7 @@ impl Expander { pub fn new(db: &impl DefDatabase2, current_file_id: HirFileId, module: ModuleId) -> Expander { let crate_def_map = db.crate_def_map(module.krate); let hygiene = Hygiene::new(db, current_file_id); - Expander { - crate_def_map, - original_file_id: current_file_id, - current_file_id, - hygiene, - module, - } + Expander { crate_def_map, current_file_id, hygiene, module } } fn expand( @@ -82,11 +75,6 @@ impl Expander { std::mem::forget(mark); } - // FIXME: remove this. - fn is_in_expansion(&self) -> bool { - self.original_file_id != self.current_file_id - } - fn to_source(&self, ast: T) -> Source { Source { file_id: self.current_file_id, ast } } @@ -147,9 +135,9 @@ pub type PatSource = Source; /// this properly for macros. #[derive(Default, Debug, Eq, PartialEq)] pub struct BodySourceMap { - expr_map: FxHashMap, + expr_map: FxHashMap, expr_map_back: ArenaMap, - pat_map: FxHashMap, + pat_map: FxHashMap, pat_map_back: ArenaMap, field_map: FxHashMap<(ExprId, usize), AstPtr>, } @@ -202,16 +190,18 @@ impl BodySourceMap { self.expr_map_back.get(expr).copied() } - pub fn node_expr(&self, node: &ast::Expr) -> Option { - self.expr_map.get(&Either::A(AstPtr::new(node))).cloned() + pub fn node_expr(&self, node: Source<&ast::Expr>) -> Option { + let src = node.map(|it| Either::A(AstPtr::new(it))); + self.expr_map.get(&src).cloned() } pub fn pat_syntax(&self, pat: PatId) -> Option { self.pat_map_back.get(pat).copied() } - pub fn node_pat(&self, node: &ast::Pat) -> Option { - self.pat_map.get(&Either::A(AstPtr::new(node))).cloned() + pub fn node_pat(&self, node: Source<&ast::Pat>) -> Option { + let src = node.map(|it| Either::A(AstPtr::new(it))); + self.pat_map.get(&src).cloned() } pub fn field_syntax(&self, expr: ExprId, field: usize) -> AstPtr { diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index c45500195..f6d79ddf0 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -94,10 +94,9 @@ where fn alloc_expr(&mut self, expr: Expr, ptr: AstPtr) -> ExprId { let ptr = Either::A(ptr); let id = self.body.exprs.alloc(expr); - if !self.expander.is_in_expansion() { - self.source_map.expr_map.insert(ptr, id); - } - self.source_map.expr_map_back.insert(id, self.expander.to_source(ptr)); + let src = self.expander.to_source(ptr); + self.source_map.expr_map.insert(src, id); + self.source_map.expr_map_back.insert(id, src); id } // desugared exprs don't have ptr, that's wrong and should be fixed @@ -108,18 +107,16 @@ where fn alloc_expr_field_shorthand(&mut self, expr: Expr, ptr: AstPtr) -> ExprId { let ptr = Either::B(ptr); let id = self.body.exprs.alloc(expr); - if !self.expander.is_in_expansion() { - self.source_map.expr_map.insert(ptr, id); - } - self.source_map.expr_map_back.insert(id, self.expander.to_source(ptr)); + let src = self.expander.to_source(ptr); + self.source_map.expr_map.insert(src, id); + self.source_map.expr_map_back.insert(id, src); id } fn alloc_pat(&mut self, pat: Pat, ptr: PatPtr) -> PatId { let id = self.body.pats.alloc(pat); - if !self.expander.is_in_expansion() { - self.source_map.pat_map.insert(ptr, id); - } - self.source_map.pat_map_back.insert(id, self.expander.to_source(ptr)); + let src = self.expander.to_source(ptr); + self.source_map.pat_map.insert(src, id); + self.source_map.pat_map_back.insert(id, src); id } @@ -277,7 +274,8 @@ where ast::Expr::ParenExpr(e) => { let inner = self.collect_expr_opt(e.expr()); // make the paren expr point to the inner expression as well - self.source_map.expr_map.insert(Either::A(syntax_ptr), inner); + let src = self.expander.to_source(Either::A(syntax_ptr)); + self.source_map.expr_map.insert(src, inner); inner } ast::Expr::ReturnExpr(e) => { diff --git a/crates/ra_hir_expand/src/lib.rs b/crates/ra_hir_expand/src/lib.rs index c6ffa2c6f..930789b0f 100644 --- a/crates/ra_hir_expand/src/lib.rs +++ b/crates/ra_hir_expand/src/lib.rs @@ -223,7 +223,7 @@ impl AstId { } } -#[derive(Debug, PartialEq, Eq, Clone, Copy)] +#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)] pub struct Source { pub file_id: HirFileId, pub ast: T, @@ -233,6 +233,9 @@ impl Source { pub fn map U, U>(self, f: F) -> Source { Source { file_id: self.file_id, ast: f(self.ast) } } + pub fn as_ref(&self) -> Source<&T> { + Source { file_id: self.file_id, 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") } -- cgit v1.2.3