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_def/src/body/lower.rs | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) (limited to 'crates/ra_hir_def/src/body') 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_def/src/body/lower.rs | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'crates/ra_hir_def/src/body') 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/lower.rs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'crates/ra_hir_def/src/body') 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/lower.rs | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) (limited to 'crates/ra_hir_def/src/body') 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/lower.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'crates/ra_hir_def/src/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/lower.rs | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'crates/ra_hir_def/src/body') 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/lower.rs | 32 +++++++------------------------- 1 file changed, 7 insertions(+), 25 deletions(-) (limited to 'crates/ra_hir_def/src/body') 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_def/src/body/lower.rs | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) (limited to 'crates/ra_hir_def/src/body') 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) => { -- cgit v1.2.3 From 4efd345b09ca6e06fc0580d91a6c13f30b6b7f23 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 14 Nov 2019 11:33:18 +0300 Subject: Slightly better naming --- crates/ra_hir_def/src/body/lower.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crates/ra_hir_def/src/body') diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index f6d79ddf0..a5bb60e85 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -430,7 +430,7 @@ 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) => match self.expander.expand(self.db, e) { + ast::Expr::MacroCall(e) => match self.expander.enter_expand(self.db, e) { Some((mark, expansion)) => { let id = self.collect_expr(expansion); self.expander.exit(self.db, mark); -- cgit v1.2.3 From f924ae3b86dc5e978071b6f8308b9f357415780b Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 14 Nov 2019 11:56:13 +0300 Subject: Move scopes to hir_def --- crates/ra_hir_def/src/body/scope.rs | 157 ++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 crates/ra_hir_def/src/body/scope.rs (limited to 'crates/ra_hir_def/src/body') diff --git a/crates/ra_hir_def/src/body/scope.rs b/crates/ra_hir_def/src/body/scope.rs new file mode 100644 index 000000000..dd8d06d11 --- /dev/null +++ b/crates/ra_hir_def/src/body/scope.rs @@ -0,0 +1,157 @@ +//! FIXME: write short doc here + +use hir_expand::name::Name; +use ra_arena::{impl_arena_id, Arena, RawId}; +use rustc_hash::FxHashMap; + +use crate::{ + body::Body, + expr::{Expr, ExprId, Pat, PatId, Statement}, +}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct ScopeId(RawId); +impl_arena_id!(ScopeId); + +#[derive(Debug, PartialEq, Eq)] +pub struct ExprScopes { + scopes: Arena, + scope_by_expr: FxHashMap, +} + +#[derive(Debug, PartialEq, Eq)] +pub struct ScopeEntry { + name: Name, + pat: PatId, +} + +impl ScopeEntry { + pub fn name(&self) -> &Name { + &self.name + } + + pub fn pat(&self) -> PatId { + self.pat + } +} + +#[derive(Debug, PartialEq, Eq)] +pub struct ScopeData { + parent: Option, + entries: Vec, +} + +impl ExprScopes { + pub fn new(body: &Body) -> ExprScopes { + let mut scopes = + ExprScopes { scopes: Arena::default(), scope_by_expr: FxHashMap::default() }; + let root = scopes.root_scope(); + scopes.add_params_bindings(body, root, body.params()); + compute_expr_scopes(body.body_expr(), body, &mut scopes, root); + scopes + } + + pub fn entries(&self, scope: ScopeId) -> &[ScopeEntry] { + &self.scopes[scope].entries + } + + pub fn scope_chain(&self, scope: Option) -> impl Iterator + '_ { + std::iter::successors(scope, move |&scope| self.scopes[scope].parent) + } + + pub fn scope_for(&self, expr: ExprId) -> Option { + self.scope_by_expr.get(&expr).copied() + } + + pub fn scope_by_expr(&self) -> &FxHashMap { + &self.scope_by_expr + } + + fn root_scope(&mut self) -> ScopeId { + self.scopes.alloc(ScopeData { parent: None, entries: vec![] }) + } + + fn new_scope(&mut self, parent: ScopeId) -> ScopeId { + self.scopes.alloc(ScopeData { parent: Some(parent), entries: vec![] }) + } + + fn add_bindings(&mut self, body: &Body, scope: ScopeId, pat: PatId) { + match &body[pat] { + Pat::Bind { name, .. } => { + // bind can have a sub pattern, but it's actually not allowed + // to bind to things in there + let entry = ScopeEntry { name: name.clone(), pat }; + self.scopes[scope].entries.push(entry) + } + p => p.walk_child_pats(|pat| self.add_bindings(body, scope, pat)), + } + } + + fn add_params_bindings(&mut self, body: &Body, scope: ScopeId, params: &[PatId]) { + params.iter().for_each(|pat| self.add_bindings(body, scope, *pat)); + } + + fn set_scope(&mut self, node: ExprId, scope: ScopeId) { + self.scope_by_expr.insert(node, scope); + } +} + +fn compute_block_scopes( + statements: &[Statement], + tail: Option, + body: &Body, + scopes: &mut ExprScopes, + mut scope: ScopeId, +) { + for stmt in statements { + match stmt { + Statement::Let { pat, initializer, .. } => { + if let Some(expr) = initializer { + scopes.set_scope(*expr, scope); + compute_expr_scopes(*expr, body, scopes, scope); + } + scope = scopes.new_scope(scope); + scopes.add_bindings(body, scope, *pat); + } + Statement::Expr(expr) => { + scopes.set_scope(*expr, scope); + compute_expr_scopes(*expr, body, scopes, scope); + } + } + } + if let Some(expr) = tail { + compute_expr_scopes(expr, body, scopes, scope); + } +} + +fn compute_expr_scopes(expr: ExprId, body: &Body, scopes: &mut ExprScopes, scope: ScopeId) { + scopes.set_scope(expr, scope); + match &body[expr] { + Expr::Block { statements, tail } => { + compute_block_scopes(&statements, *tail, body, scopes, scope); + } + Expr::For { iterable, pat, body: body_expr } => { + compute_expr_scopes(*iterable, body, scopes, scope); + let scope = scopes.new_scope(scope); + scopes.add_bindings(body, scope, *pat); + compute_expr_scopes(*body_expr, body, scopes, scope); + } + Expr::Lambda { args, body: body_expr, .. } => { + let scope = scopes.new_scope(scope); + scopes.add_params_bindings(body, scope, &args); + compute_expr_scopes(*body_expr, body, scopes, scope); + } + Expr::Match { expr, arms } => { + compute_expr_scopes(*expr, body, scopes, scope); + for arm in arms { + let scope = scopes.new_scope(scope); + for pat in &arm.pats { + scopes.add_bindings(body, scope, *pat); + } + scopes.set_scope(arm.expr, scope); + compute_expr_scopes(arm.expr, body, scopes, scope); + } + } + e => e.walk_child_exprs(|e| compute_expr_scopes(e, body, scopes, scope)), + }; +} -- cgit v1.2.3 From 1583ab1558022d0fdbbc10d3a440a2d3daa4a840 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 14 Nov 2019 17:37:22 +0300 Subject: Move body queries to hir_def --- crates/ra_hir_def/src/body/scope.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'crates/ra_hir_def/src/body') diff --git a/crates/ra_hir_def/src/body/scope.rs b/crates/ra_hir_def/src/body/scope.rs index dd8d06d11..09a39e721 100644 --- a/crates/ra_hir_def/src/body/scope.rs +++ b/crates/ra_hir_def/src/body/scope.rs @@ -1,4 +1,5 @@ //! FIXME: write short doc here +use std::sync::Arc; use hir_expand::name::Name; use ra_arena::{impl_arena_id, Arena, RawId}; @@ -6,7 +7,9 @@ use rustc_hash::FxHashMap; use crate::{ body::Body, + db::DefDatabase2, expr::{Expr, ExprId, Pat, PatId, Statement}, + DefWithBodyId, }; #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -42,7 +45,12 @@ pub struct ScopeData { } impl ExprScopes { - pub fn new(body: &Body) -> ExprScopes { + pub(crate) fn expr_scopes_query(db: &impl DefDatabase2, def: DefWithBodyId) -> Arc { + let body = db.body(def); + Arc::new(ExprScopes::new(&*body)) + } + + fn new(body: &Body) -> ExprScopes { let mut scopes = ExprScopes { scopes: Arena::default(), scope_by_expr: FxHashMap::default() }; let root = scopes.root_scope(); -- cgit v1.2.3