strongy-typed ids for macros

This commit is contained in:
Aleksey Kladov 2019-03-26 18:03:17 +03:00
parent fb8b354dcc
commit 071a19537d
4 changed files with 19 additions and 33 deletions

View File

@ -10,7 +10,7 @@ use ra_arena::{RawId, ArenaId, impl_arena_id};
use mbe::MacroRules;
use crate::{
Module, DefDatabase, SourceItemId, SourceFileItemId,
Module, DefDatabase, SourceItemId, SourceFileItemId, AstId,
};
#[derive(Debug, Default)]
@ -68,7 +68,7 @@ impl HirFileId {
HirFileIdRepr::File(file_id) => file_id,
HirFileIdRepr::Macro(macro_call_id) => {
let loc = macro_call_id.loc(db);
loc.source_item_id.file_id.original_file(db)
loc.ast_id.file_id().original_file(db)
}
}
}
@ -96,8 +96,7 @@ impl HirFileId {
fn parse_macro(db: &impl DefDatabase, macro_call_id: MacroCallId) -> Option<TreeArc<SourceFile>> {
let loc = macro_call_id.loc(db);
let syntax = db.file_item(loc.source_item_id);
let macro_call = ast::MacroCall::cast(&syntax).unwrap();
let macro_call = loc.ast_id.to_node(db);
let (macro_arg, _) = macro_call.token_tree().and_then(mbe::ast_to_token_tree)?;
let macro_rules = db.macro_def(loc.def)?;
@ -124,15 +123,10 @@ impl From<MacroCallId> for HirFileId {
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum MacroDefId {
MacroByExample { source_item_id: SourceItemId },
}
pub struct MacroDefId(pub(crate) AstId<ast::MacroCall>);
pub(crate) fn macro_def_query(db: &impl DefDatabase, id: MacroDefId) -> Option<Arc<MacroRules>> {
let syntax_node = match id {
MacroDefId::MacroByExample { source_item_id } => db.file_item(source_item_id),
};
let macro_call = ast::MacroCall::cast(&syntax_node).unwrap();
let macro_call = id.0.to_node(db);
let arg = macro_call.token_tree()?;
let (tt, _) = mbe::ast_to_token_tree(arg)?;
let rules = MacroRules::parse(&tt).ok()?;
@ -148,7 +142,7 @@ impl_arena_id!(MacroCallId);
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct MacroCallLoc {
pub(crate) def: MacroDefId,
pub(crate) source_item_id: SourceItemId,
pub(crate) ast_id: AstId<ast::MacroCall>,
}
impl MacroCallId {

View File

@ -7,7 +7,7 @@ use ra_syntax::ast;
use crate::{
Function, Module, Struct, Enum, Const, Static, Trait, TypeAlias,
DefDatabase, HirFileId, Name, Path, SourceItemId,
DefDatabase, HirFileId, Name, Path,
KnownName,
nameres::{
Resolution, PerNs, ModuleDef, ReachedFixedPoint, ResolveMode,
@ -53,7 +53,7 @@ struct DefCollector<DB> {
def_map: CrateDefMap,
glob_imports: FxHashMap<CrateModuleId, Vec<(CrateModuleId, raw::ImportId)>>,
unresolved_imports: Vec<(CrateModuleId, raw::ImportId, raw::ImportData)>,
unexpanded_macros: Vec<(CrateModuleId, SourceItemId, Path)>,
unexpanded_macros: Vec<(CrateModuleId, AstId<ast::MacroCall>, Path)>,
global_macro_scope: FxHashMap<Name, MacroDefId>,
}
@ -295,7 +295,7 @@ where
let mut macros = std::mem::replace(&mut self.unexpanded_macros, Vec::new());
let mut resolved = Vec::new();
let mut res = ReachedFixedPoint::Yes;
macros.retain(|(module_id, source_item_id, path)| {
macros.retain(|(module_id, ast_id, path)| {
if path.segments.len() != 2 {
return true;
}
@ -311,8 +311,7 @@ where
res = ReachedFixedPoint::No;
let def_map = self.db.crate_def_map(krate);
if let Some(macro_id) = def_map.public_macros.get(&path.segments[1].name).cloned() {
let call_id =
MacroCallLoc { def: macro_id, source_item_id: *source_item_id }.id(self.db);
let call_id = MacroCallLoc { def: macro_id, ast_id: *ast_id }.id(self.db);
resolved.push((*module_id, call_id));
}
false
@ -456,34 +455,27 @@ where
// Case 1: macro rules, define a macro in crate-global mutable scope
if is_macro_rules(&mac.path) {
if let Some(name) = &mac.name {
let macro_id = MacroDefId::MacroByExample {
source_item_id: mac.source_item_id.with_file_id(self.file_id),
};
let macro_id = MacroDefId(mac.ast_id.with_file_id(self.file_id));
self.def_collector.define_macro(name.clone(), macro_id, mac.export)
}
return;
}
let source_item_id = SourceItemId { file_id: self.file_id, item_id: mac.source_item_id };
let ast_id = mac.ast_id.with_file_id(self.file_id);
// Case 2: try to expand macro_rules from this crate, triggering
// recursive item collection.
if let Some(&macro_id) =
mac.path.as_ident().and_then(|name| self.def_collector.global_macro_scope.get(name))
{
let macro_call_id =
MacroCallLoc { def: macro_id, source_item_id }.id(self.def_collector.db);
let macro_call_id = MacroCallLoc { def: macro_id, ast_id }.id(self.def_collector.db);
self.def_collector.collect_macro_expansion(self.module_id, macro_call_id);
return;
}
// Case 3: path to a macro from another crate, expand during name resolution
self.def_collector.unexpanded_macros.push((
self.module_id,
source_item_id,
mac.path.clone(),
))
self.def_collector.unexpanded_macros.push((self.module_id, ast_id, mac.path.clone()))
}
}

View File

@ -160,7 +160,7 @@ impl_arena_id!(Macro);
#[derive(Debug, PartialEq, Eq)]
pub(super) struct MacroData {
pub(super) source_item_id: SourceFileItemId,
pub(super) ast_id: FileAstId<ast::MacroCall>,
pub(super) path: Path,
pub(super) name: Option<Name>,
pub(super) export: bool,
@ -285,9 +285,9 @@ impl RawItemsCollector {
};
let name = m.name().map(|it| it.as_name());
let source_item_id = self.source_file_items.id_of_unchecked(m.syntax());
let ast_id = self.source_file_items.ast_id(m);
let export = m.has_atom_attr("macro_export");
let m = self.raw_items.macros.alloc(MacroData { source_item_id, path, name, export });
let m = self.raw_items.macros.alloc(MacroData { ast_id, path, name, export });
self.push_item(current_module, RawItem::Macro(m));
}

View File

@ -5,7 +5,7 @@ use ra_syntax::{SyntaxNodePtr, TreeArc, SyntaxNode, SourceFile, AstNode, ast};
use crate::{HirFileId, DefDatabase};
#[derive(Debug, PartialEq, Eq)]
#[derive(Debug, PartialEq, Eq, Hash)]
pub(crate) struct AstId<N: AstNode> {
file_id: HirFileId,
file_ast_id: FileAstId<N>,
@ -30,7 +30,7 @@ impl<N: AstNode> AstId<N> {
}
}
#[derive(Debug, PartialEq, Eq)]
#[derive(Debug, PartialEq, Eq, Hash)]
pub(crate) struct FileAstId<N: AstNode> {
raw: SourceFileItemId,
_ty: PhantomData<N>,