mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-09 13:33:43 +00:00
Use pre-stored macro file
This commit is contained in:
parent
16156d766d
commit
12cc2ed557
@ -17,7 +17,7 @@ use hir_def::{
|
|||||||
nameres::ModuleSource,
|
nameres::ModuleSource,
|
||||||
path::path,
|
path::path,
|
||||||
resolver::{self, resolver_for_scope, HasResolver, Resolver, TypeNs, ValueNs},
|
resolver::{self, resolver_for_scope, HasResolver, Resolver, TypeNs, ValueNs},
|
||||||
AssocItemId, DefWithBodyId, Expander,
|
AssocItemId, DefWithBodyId,
|
||||||
};
|
};
|
||||||
use hir_expand::{
|
use hir_expand::{
|
||||||
hygiene::Hygiene, name::AsName, AstId, HirFileId, InFile, MacroCallId, MacroCallKind,
|
hygiene::Hygiene, name::AsName, AstId, HirFileId, InFile, MacroCallId, MacroCallKind,
|
||||||
@ -215,10 +215,27 @@ impl SourceAnalyzer {
|
|||||||
self.body_source_map.as_ref()?.node_pat(src)
|
self.body_source_map.as_ref()?.node_pat(src)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn expand_expr(
|
||||||
|
&self,
|
||||||
|
db: &impl HirDatabase,
|
||||||
|
expr: InFile<&ast::Expr>,
|
||||||
|
) -> Option<InFile<ast::Expr>> {
|
||||||
|
let macro_call = ast::MacroCall::cast(expr.value.syntax().clone())?;
|
||||||
|
let macro_file =
|
||||||
|
self.body_source_map.as_ref()?.node_macro_file(expr.with_value(¯o_call))?;
|
||||||
|
let expanded = db.parse_or_expand(macro_file)?;
|
||||||
|
let kind = expanded.kind();
|
||||||
|
let expr = InFile::new(macro_file, ast::Expr::cast(expanded)?);
|
||||||
|
|
||||||
|
if ast::MacroCall::can_cast(kind) {
|
||||||
|
self.expand_expr(db, expr.as_ref())
|
||||||
|
} else {
|
||||||
|
Some(expr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn type_of(&self, db: &impl HirDatabase, expr: &ast::Expr) -> Option<Type> {
|
pub fn type_of(&self, db: &impl HirDatabase, expr: &ast::Expr) -> Option<Type> {
|
||||||
let expr_id = if let Some(macro_call) = ast::MacroCall::cast(expr.syntax().clone()) {
|
let expr_id = if let Some(expr) = self.expand_expr(db, InFile::new(self.file_id, expr)) {
|
||||||
let mut expander = Expander::new(db, self.file_id, self.body_owner?.module(db).id);
|
|
||||||
let expr = expand_macro_call_to_expr(db, &mut expander, macro_call)?;
|
|
||||||
self.body_source_map.as_ref()?.node_expr(expr.as_ref())?
|
self.body_source_map.as_ref()?.node_expr(expr.as_ref())?
|
||||||
} else {
|
} else {
|
||||||
self.expr_id(expr)?
|
self.expr_id(expr)?
|
||||||
@ -508,21 +525,6 @@ fn scope_for_offset(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expand_macro_call_to_expr(
|
|
||||||
db: &impl HirDatabase,
|
|
||||||
expander: &mut Expander,
|
|
||||||
macro_call: ast::MacroCall,
|
|
||||||
) -> Option<InFile<ast::Expr>> {
|
|
||||||
let (mark, expr): (_, ast::Expr) = expander.enter_expand(db, macro_call)?;
|
|
||||||
let expr = if let Some(child) = ast::MacroCall::cast(expr.syntax().clone()) {
|
|
||||||
expand_macro_call_to_expr(db, expander, child)
|
|
||||||
} else {
|
|
||||||
Some(expander.to_source(expr))
|
|
||||||
};
|
|
||||||
expander.exit(db, mark);
|
|
||||||
expr
|
|
||||||
}
|
|
||||||
|
|
||||||
// XXX: during completion, cursor might be outside of any particular
|
// XXX: during completion, cursor might be outside of any particular
|
||||||
// expression. Try to figure out the correct scope...
|
// expression. Try to figure out the correct scope...
|
||||||
fn adjust(
|
fn adjust(
|
||||||
|
@ -26,7 +26,7 @@ use crate::{
|
|||||||
DefWithBodyId, HasModule, Lookup, ModuleId,
|
DefWithBodyId, HasModule, Lookup, ModuleId,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct Expander {
|
pub(crate) struct Expander {
|
||||||
crate_def_map: Arc<CrateDefMap>,
|
crate_def_map: Arc<CrateDefMap>,
|
||||||
current_file_id: HirFileId,
|
current_file_id: HirFileId,
|
||||||
hygiene: Hygiene,
|
hygiene: Hygiene,
|
||||||
@ -35,14 +35,18 @@ pub struct Expander {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Expander {
|
impl Expander {
|
||||||
pub fn new(db: &impl DefDatabase, current_file_id: HirFileId, module: ModuleId) -> Expander {
|
pub(crate) fn new(
|
||||||
|
db: &impl DefDatabase,
|
||||||
|
current_file_id: HirFileId,
|
||||||
|
module: ModuleId,
|
||||||
|
) -> Expander {
|
||||||
let crate_def_map = db.crate_def_map(module.krate);
|
let crate_def_map = db.crate_def_map(module.krate);
|
||||||
let hygiene = Hygiene::new(db, current_file_id);
|
let hygiene = Hygiene::new(db, current_file_id);
|
||||||
let ast_id_map = db.ast_id_map(current_file_id);
|
let ast_id_map = db.ast_id_map(current_file_id);
|
||||||
Expander { crate_def_map, current_file_id, hygiene, ast_id_map, module }
|
Expander { crate_def_map, current_file_id, hygiene, ast_id_map, module }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn enter_expand<T: ast::AstNode, DB: DefDatabase>(
|
pub(crate) fn enter_expand<T: ast::AstNode, DB: DefDatabase>(
|
||||||
&mut self,
|
&mut self,
|
||||||
db: &DB,
|
db: &DB,
|
||||||
macro_call: ast::MacroCall,
|
macro_call: ast::MacroCall,
|
||||||
@ -80,14 +84,14 @@ impl Expander {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn exit(&mut self, db: &impl DefDatabase, mut mark: Mark) {
|
pub(crate) fn exit(&mut self, db: &impl DefDatabase, mut mark: Mark) {
|
||||||
self.hygiene = Hygiene::new(db, mark.file_id);
|
self.hygiene = Hygiene::new(db, mark.file_id);
|
||||||
self.current_file_id = mark.file_id;
|
self.current_file_id = mark.file_id;
|
||||||
self.ast_id_map = mem::take(&mut mark.ast_id_map);
|
self.ast_id_map = mem::take(&mut mark.ast_id_map);
|
||||||
mark.bomb.defuse();
|
mark.bomb.defuse();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_source<T>(&self, value: T) -> InFile<T> {
|
pub(crate) fn to_source<T>(&self, value: T) -> InFile<T> {
|
||||||
InFile { file_id: self.current_file_id, value }
|
InFile { file_id: self.current_file_id, value }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,7 +116,7 @@ impl Expander {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Mark {
|
pub(crate) struct Mark {
|
||||||
file_id: HirFileId,
|
file_id: HirFileId,
|
||||||
ast_id_map: Arc<AstIdMap>,
|
ast_id_map: Arc<AstIdMap>,
|
||||||
bomb: DropBomb,
|
bomb: DropBomb,
|
||||||
@ -159,6 +163,7 @@ pub struct BodySourceMap {
|
|||||||
pat_map: FxHashMap<PatSource, PatId>,
|
pat_map: FxHashMap<PatSource, PatId>,
|
||||||
pat_map_back: ArenaMap<PatId, PatSource>,
|
pat_map_back: ArenaMap<PatId, PatSource>,
|
||||||
field_map: FxHashMap<(ExprId, usize), AstPtr<ast::RecordField>>,
|
field_map: FxHashMap<(ExprId, usize), AstPtr<ast::RecordField>>,
|
||||||
|
expansions: FxHashMap<InFile<AstPtr<ast::MacroCall>>, HirFileId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Body {
|
impl Body {
|
||||||
@ -233,6 +238,11 @@ impl BodySourceMap {
|
|||||||
self.expr_map.get(&src).cloned()
|
self.expr_map.get(&src).cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn node_macro_file(&self, node: InFile<&ast::MacroCall>) -> Option<HirFileId> {
|
||||||
|
let src = node.map(|it| AstPtr::new(it));
|
||||||
|
self.expansions.get(&src).cloned()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn field_init_shorthand_expr(&self, node: InFile<&ast::RecordField>) -> Option<ExprId> {
|
pub fn field_init_shorthand_expr(&self, node: InFile<&ast::RecordField>) -> Option<ExprId> {
|
||||||
let src = node.map(|it| Either::Right(AstPtr::new(it)));
|
let src = node.map(|it| Either::Right(AstPtr::new(it)));
|
||||||
self.expr_map.get(&src).cloned()
|
self.expr_map.get(&src).cloned()
|
||||||
|
@ -446,14 +446,20 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// FIXME expand to statements in statement position
|
// FIXME expand to statements in statement position
|
||||||
ast::Expr::MacroCall(e) => match self.expander.enter_expand(self.db, e) {
|
ast::Expr::MacroCall(e) => {
|
||||||
Some((mark, expansion)) => {
|
let macro_call = self.expander.to_source(AstPtr::new(&e));
|
||||||
let id = self.collect_expr(expansion);
|
match self.expander.enter_expand(self.db, e.clone()) {
|
||||||
self.expander.exit(self.db, mark);
|
Some((mark, expansion)) => {
|
||||||
id
|
self.source_map
|
||||||
|
.expansions
|
||||||
|
.insert(macro_call, self.expander.current_file_id);
|
||||||
|
let id = self.collect_expr(expansion);
|
||||||
|
self.expander.exit(self.db, mark);
|
||||||
|
id
|
||||||
|
}
|
||||||
|
None => self.alloc_expr(Expr::Missing, syntax_ptr),
|
||||||
}
|
}
|
||||||
None => self.alloc_expr(Expr::Missing, syntax_ptr),
|
}
|
||||||
},
|
|
||||||
|
|
||||||
// FIXME implement HIR for these:
|
// FIXME implement HIR for these:
|
||||||
ast::Expr::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
|
ast::Expr::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
|
||||||
|
@ -48,7 +48,7 @@ use ra_arena::{impl_arena_id, RawId};
|
|||||||
use ra_db::{impl_intern_key, salsa, CrateId};
|
use ra_db::{impl_intern_key, salsa, CrateId};
|
||||||
use ra_syntax::{ast, AstNode};
|
use ra_syntax::{ast, AstNode};
|
||||||
|
|
||||||
pub use crate::body::Expander;
|
use crate::body::Expander;
|
||||||
use crate::builtin_type::BuiltinType;
|
use crate::builtin_type::BuiltinType;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
Loading…
Reference in New Issue
Block a user