dont store body inside source map

This commit is contained in:
Aleksey Kladov 2019-03-02 16:18:40 +03:00
parent eaf1df26e9
commit f4c5383103
5 changed files with 54 additions and 61 deletions

View File

@ -484,7 +484,7 @@ impl Function {
} }
pub fn body_source_map(&self, db: &impl HirDatabase) -> Arc<BodySourceMap> { pub fn body_source_map(&self, db: &impl HirDatabase) -> Arc<BodySourceMap> {
db.body_source_map(*self) db.body_with_source_map(*self).1
} }
pub fn body(&self, db: &impl HirDatabase) -> Arc<Body> { pub fn body(&self, db: &impl HirDatabase) -> Arc<Body> {
@ -497,7 +497,7 @@ impl Function {
pub fn scopes(&self, db: &impl HirDatabase) -> ScopesWithSyntaxMapping { pub fn scopes(&self, db: &impl HirDatabase) -> ScopesWithSyntaxMapping {
let scopes = db.expr_scopes(*self); let scopes = db.expr_scopes(*self);
let syntax_mapping = db.body_source_map(*self); let syntax_mapping = db.body_with_source_map(*self).1;
ScopesWithSyntaxMapping { scopes, syntax_mapping } ScopesWithSyntaxMapping { scopes, syntax_mapping }
} }

View File

@ -105,11 +105,14 @@ pub trait HirDatabase: PersistentHirDatabase {
#[salsa::invoke(crate::ty::type_for_field)] #[salsa::invoke(crate::ty::type_for_field)]
fn type_for_field(&self, field: StructField) -> Ty; fn type_for_field(&self, field: StructField) -> Ty;
#[salsa::invoke(crate::expr::body_hir)] #[salsa::invoke(crate::expr::body_with_source_map_query)]
fn body_hir(&self, func: Function) -> Arc<crate::expr::Body>; fn body_with_source_map(
&self,
func: Function,
) -> (Arc<crate::expr::Body>, Arc<crate::expr::BodySourceMap>);
#[salsa::invoke(crate::expr::body_source_map)] #[salsa::invoke(crate::expr::body_hir_query)]
fn body_source_map(&self, func: Function) -> Arc<crate::expr::BodySourceMap>; fn body_hir(&self, func: Function) -> Arc<crate::expr::Body>;
#[salsa::invoke(crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query)] #[salsa::invoke(crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query)]
fn impls_in_crate(&self, krate: Crate) -> Arc<CrateImplBlocks>; fn impls_in_crate(&self, krate: Crate) -> Arc<CrateImplBlocks>;

View File

@ -48,13 +48,13 @@ pub struct Body {
/// expression containing it; but for type inference etc., we want to operate on /// expression containing it; but for type inference etc., we want to operate on
/// a structure that is agnostic to the actual positions of expressions in the /// a structure that is agnostic to the actual positions of expressions in the
/// file, so that we don't recompute types whenever some whitespace is typed. /// file, so that we don't recompute types whenever some whitespace is typed.
#[derive(Debug, Eq, PartialEq)] #[derive(Default, Debug, Eq, PartialEq)]
pub struct BodySourceMap { pub struct BodySourceMap {
body: Arc<Body>, // body: Arc<Body>,
expr_syntax_mapping: FxHashMap<SyntaxNodePtr, ExprId>, expr_map: FxHashMap<SyntaxNodePtr, ExprId>,
expr_syntax_mapping_back: ArenaMap<ExprId, SyntaxNodePtr>, expr_map_back: ArenaMap<ExprId, SyntaxNodePtr>,
pat_syntax_mapping: FxHashMap<SyntaxNodePtr, PatId>, pat_map: FxHashMap<SyntaxNodePtr, PatId>,
pat_syntax_mapping_back: ArenaMap<PatId, SyntaxNodePtr>, pat_map_back: ArenaMap<PatId, SyntaxNodePtr>,
} }
impl Body { impl Body {
@ -79,7 +79,7 @@ impl Body {
} }
pub fn syntax_mapping(&self, db: &impl HirDatabase) -> Arc<BodySourceMap> { pub fn syntax_mapping(&self, db: &impl HirDatabase) -> Arc<BodySourceMap> {
db.body_source_map(self.owner) db.body_with_source_map(self.owner).1
} }
} }
@ -121,31 +121,27 @@ impl Index<PatId> for Body {
impl BodySourceMap { impl BodySourceMap {
pub fn expr_syntax(&self, expr: ExprId) -> Option<SyntaxNodePtr> { pub fn expr_syntax(&self, expr: ExprId) -> Option<SyntaxNodePtr> {
self.expr_syntax_mapping_back.get(expr).cloned() self.expr_map_back.get(expr).cloned()
} }
pub fn syntax_expr(&self, ptr: SyntaxNodePtr) -> Option<ExprId> { pub fn syntax_expr(&self, ptr: SyntaxNodePtr) -> Option<ExprId> {
self.expr_syntax_mapping.get(&ptr).cloned() self.expr_map.get(&ptr).cloned()
} }
pub fn node_expr(&self, node: &ast::Expr) -> Option<ExprId> { pub fn node_expr(&self, node: &ast::Expr) -> Option<ExprId> {
self.expr_syntax_mapping.get(&SyntaxNodePtr::new(node.syntax())).cloned() self.expr_map.get(&SyntaxNodePtr::new(node.syntax())).cloned()
} }
pub fn pat_syntax(&self, pat: PatId) -> Option<SyntaxNodePtr> { pub fn pat_syntax(&self, pat: PatId) -> Option<SyntaxNodePtr> {
self.pat_syntax_mapping_back.get(pat).cloned() self.pat_map_back.get(pat).cloned()
} }
pub fn syntax_pat(&self, ptr: SyntaxNodePtr) -> Option<PatId> { pub fn syntax_pat(&self, ptr: SyntaxNodePtr) -> Option<PatId> {
self.pat_syntax_mapping.get(&ptr).cloned() self.pat_map.get(&ptr).cloned()
} }
pub fn node_pat(&self, node: &ast::Pat) -> Option<PatId> { pub fn node_pat(&self, node: &ast::Pat) -> Option<PatId> {
self.pat_syntax_mapping.get(&SyntaxNodePtr::new(node.syntax())).cloned() self.pat_map.get(&SyntaxNodePtr::new(node.syntax())).cloned()
}
pub fn body(&self) -> &Arc<Body> {
&self.body
} }
} }
@ -467,18 +463,11 @@ impl Pat {
// Queries // Queries
pub(crate) fn body_hir(db: &impl HirDatabase, func: Function) -> Arc<Body> {
Arc::clone(&body_source_map(db, func).body)
}
struct ExprCollector { struct ExprCollector {
owner: Function, owner: Function,
exprs: Arena<ExprId, Expr>, exprs: Arena<ExprId, Expr>,
pats: Arena<PatId, Pat>, pats: Arena<PatId, Pat>,
expr_syntax_mapping: FxHashMap<SyntaxNodePtr, ExprId>, source_map: BodySourceMap,
expr_syntax_mapping_back: ArenaMap<ExprId, SyntaxNodePtr>,
pat_syntax_mapping: FxHashMap<SyntaxNodePtr, PatId>,
pat_syntax_mapping_back: ArenaMap<PatId, SyntaxNodePtr>,
params: Vec<PatId>, params: Vec<PatId>,
body_expr: Option<ExprId>, body_expr: Option<ExprId>,
} }
@ -489,10 +478,7 @@ impl ExprCollector {
owner, owner,
exprs: Arena::default(), exprs: Arena::default(),
pats: Arena::default(), pats: Arena::default(),
expr_syntax_mapping: FxHashMap::default(), source_map: BodySourceMap::default(),
expr_syntax_mapping_back: ArenaMap::default(),
pat_syntax_mapping: FxHashMap::default(),
pat_syntax_mapping_back: ArenaMap::default(),
params: Vec::new(), params: Vec::new(),
body_expr: None, body_expr: None,
} }
@ -500,15 +486,15 @@ impl ExprCollector {
fn alloc_expr(&mut self, expr: Expr, syntax_ptr: SyntaxNodePtr) -> ExprId { fn alloc_expr(&mut self, expr: Expr, syntax_ptr: SyntaxNodePtr) -> ExprId {
let id = self.exprs.alloc(expr); let id = self.exprs.alloc(expr);
self.expr_syntax_mapping.insert(syntax_ptr, id); self.source_map.expr_map.insert(syntax_ptr, id);
self.expr_syntax_mapping_back.insert(id, syntax_ptr); self.source_map.expr_map_back.insert(id, syntax_ptr);
id id
} }
fn alloc_pat(&mut self, pat: Pat, syntax_ptr: SyntaxNodePtr) -> PatId { fn alloc_pat(&mut self, pat: Pat, syntax_ptr: SyntaxNodePtr) -> PatId {
let id = self.pats.alloc(pat); let id = self.pats.alloc(pat);
self.pat_syntax_mapping.insert(syntax_ptr, id); self.source_map.pat_map.insert(syntax_ptr, id);
self.pat_syntax_mapping_back.insert(id, syntax_ptr); self.source_map.pat_map_back.insert(id, syntax_ptr);
id id
} }
@ -639,7 +625,7 @@ impl ExprCollector {
ast::ExprKind::ParenExpr(e) => { ast::ExprKind::ParenExpr(e) => {
let inner = self.collect_expr_opt(e.expr()); let inner = self.collect_expr_opt(e.expr());
// make the paren expr point to the inner expression as well // make the paren expr point to the inner expression as well
self.expr_syntax_mapping.insert(syntax_ptr, inner); self.source_map.expr_map.insert(syntax_ptr, inner);
inner inner
} }
ast::ExprKind::ReturnExpr(e) => { ast::ExprKind::ReturnExpr(e) => {
@ -660,9 +646,11 @@ impl ExprCollector {
} else if let Some(nr) = field.name_ref() { } else if let Some(nr) = field.name_ref() {
// field shorthand // field shorthand
let id = self.exprs.alloc(Expr::Path(Path::from_name_ref(nr))); let id = self.exprs.alloc(Expr::Path(Path::from_name_ref(nr)));
self.expr_syntax_mapping self.source_map
.expr_map
.insert(SyntaxNodePtr::new(nr.syntax()), id); .insert(SyntaxNodePtr::new(nr.syntax()), id);
self.expr_syntax_mapping_back self.source_map
.expr_map_back
.insert(id, SyntaxNodePtr::new(nr.syntax())); .insert(id, SyntaxNodePtr::new(nr.syntax()));
id id
} else { } else {
@ -910,7 +898,7 @@ impl ExprCollector {
self.body_expr = Some(body); self.body_expr = Some(body);
} }
fn into_body_source_map(self) -> BodySourceMap { fn finish(self) -> (Body, BodySourceMap) {
let body = Body { let body = Body {
owner: self.owner, owner: self.owner,
exprs: self.exprs, exprs: self.exprs,
@ -918,28 +906,30 @@ impl ExprCollector {
params: self.params, params: self.params,
body_expr: self.body_expr.expect("A body should have been collected"), body_expr: self.body_expr.expect("A body should have been collected"),
}; };
BodySourceMap { (body, self.source_map)
body: Arc::new(body),
expr_syntax_mapping: self.expr_syntax_mapping,
expr_syntax_mapping_back: self.expr_syntax_mapping_back,
pat_syntax_mapping: self.pat_syntax_mapping,
pat_syntax_mapping_back: self.pat_syntax_mapping_back,
}
} }
} }
pub(crate) fn body_source_map(db: &impl HirDatabase, func: Function) -> Arc<BodySourceMap> { pub(crate) fn body_with_source_map_query(
db: &impl HirDatabase,
func: Function,
) -> (Arc<Body>, Arc<BodySourceMap>) {
let mut collector = ExprCollector::new(func); let mut collector = ExprCollector::new(func);
// TODO: consts, etc. // TODO: consts, etc.
collector.collect_fn_body(&func.source(db).1); collector.collect_fn_body(&func.source(db).1);
Arc::new(collector.into_body_source_map()) let (body, source_map) = collector.finish();
(Arc::new(body), Arc::new(source_map))
}
pub(crate) fn body_hir_query(db: &impl HirDatabase, func: Function) -> Arc<Body> {
db.body_with_source_map(func).0
} }
#[cfg(test)] #[cfg(test)]
pub(crate) fn collect_fn_body_syntax(function: Function, node: &ast::FnDef) -> BodySourceMap { fn collect_fn_body_syntax(function: Function, node: &ast::FnDef) -> (Body, BodySourceMap) {
let mut collector = ExprCollector::new(function); let mut collector = ExprCollector::new(function);
collector.collect_fn_body(node); collector.collect_fn_body(node);
collector.into_body_source_map() collector.finish()
} }

View File

@ -316,11 +316,11 @@ mod tests {
let marker: &ast::PathExpr = find_node_at_offset(file.syntax(), off).unwrap(); let marker: &ast::PathExpr = find_node_at_offset(file.syntax(), off).unwrap();
let fn_def: &ast::FnDef = find_node_at_offset(file.syntax(), off).unwrap(); let fn_def: &ast::FnDef = find_node_at_offset(file.syntax(), off).unwrap();
let irrelevant_function = Function { id: crate::ids::FunctionId::from_raw(0.into()) }; let irrelevant_function = Function { id: crate::ids::FunctionId::from_raw(0.into()) };
let body_hir = expr::collect_fn_body_syntax(irrelevant_function, fn_def); let (body, syntax_mapping) = expr::collect_fn_body_syntax(irrelevant_function, fn_def);
let scopes = ExprScopes::new(Arc::clone(body_hir.body())); let scopes = ExprScopes::new(Arc::new(body));
let scopes = ScopesWithSyntaxMapping { let scopes = ScopesWithSyntaxMapping {
scopes: Arc::new(scopes), scopes: Arc::new(scopes),
syntax_mapping: Arc::new(body_hir), syntax_mapping: Arc::new(syntax_mapping),
}; };
let actual = scopes let actual = scopes
.scope_chain(marker.syntax()) .scope_chain(marker.syntax())
@ -417,11 +417,11 @@ mod tests {
let name_ref: &ast::NameRef = find_node_at_offset(file.syntax(), off).unwrap(); let name_ref: &ast::NameRef = find_node_at_offset(file.syntax(), off).unwrap();
let irrelevant_function = Function { id: crate::ids::FunctionId::from_raw(0.into()) }; let irrelevant_function = Function { id: crate::ids::FunctionId::from_raw(0.into()) };
let body_hir = expr::collect_fn_body_syntax(irrelevant_function, fn_def); let (body, syntax_mapping) = expr::collect_fn_body_syntax(irrelevant_function, fn_def);
let scopes = ExprScopes::new(Arc::clone(body_hir.body())); let scopes = ExprScopes::new(Arc::new(body));
let scopes = ScopesWithSyntaxMapping { let scopes = ScopesWithSyntaxMapping {
scopes: Arc::new(scopes), scopes: Arc::new(scopes),
syntax_mapping: Arc::new(body_hir), syntax_mapping: Arc::new(syntax_mapping),
}; };
let local_name_entry = scopes.resolve_local_name(name_ref).unwrap(); let local_name_entry = scopes.resolve_local_name(name_ref).unwrap();
let local_name = local_name_entry.ptr(); let local_name = local_name_entry.ptr();

View File

@ -225,6 +225,6 @@ impl RootDatabase {
self.query(hir::db::LowerModuleQuery).sweep(sweep); self.query(hir::db::LowerModuleQuery).sweep(sweep);
self.query(hir::db::LowerModuleSourceMapQuery).sweep(sweep); self.query(hir::db::LowerModuleSourceMapQuery).sweep(sweep);
self.query(hir::db::BodySourceMapQuery).sweep(sweep); self.query(hir::db::BodyWithSourceMapQuery).sweep(sweep);
} }
} }