mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-15 14:43:58 +00:00
Rename textual_macro
-> legacy_macro
Add comments
This commit is contained in:
parent
f7f7c2aff8
commit
92c07803cc
4 changed files with 39 additions and 29 deletions
|
@ -138,8 +138,21 @@ pub(crate) struct ModuleData {
|
||||||
#[derive(Debug, Default, PartialEq, Eq, Clone)]
|
#[derive(Debug, Default, PartialEq, Eq, Clone)]
|
||||||
pub struct ModuleScope {
|
pub struct ModuleScope {
|
||||||
items: FxHashMap<Name, Resolution>,
|
items: FxHashMap<Name, Resolution>,
|
||||||
|
/// Macros in current module scoped
|
||||||
|
///
|
||||||
|
/// This scope works exactly the same way that item scoping does.
|
||||||
|
/// Macro invocation with quantified path will search in it.
|
||||||
|
/// See details below.
|
||||||
macros: FxHashMap<Name, MacroDef>,
|
macros: FxHashMap<Name, MacroDef>,
|
||||||
textual_macros: FxHashMap<Name, MacroDef>,
|
/// Macros visable in current module in legacy textual scope
|
||||||
|
///
|
||||||
|
/// For macros invoked by an unquatified identifier like `bar!()`, `legacy_macros` will be searched in first.
|
||||||
|
/// If it yields no result, then it turns to module scoped `macros`.
|
||||||
|
/// It macros with name quatified with a path like `crate::foo::bar!()`, `legacy_macros` will be skipped,
|
||||||
|
/// and only normal scoped `macros` will be searched in.
|
||||||
|
///
|
||||||
|
/// Note that this automatically inherit macros defined textually before the definition of module itself.
|
||||||
|
legacy_macros: FxHashMap<Name, MacroDef>,
|
||||||
}
|
}
|
||||||
|
|
||||||
static BUILTIN_SCOPE: Lazy<FxHashMap<Name, Resolution>> = Lazy::new(|| {
|
static BUILTIN_SCOPE: Lazy<FxHashMap<Name, Resolution>> = Lazy::new(|| {
|
||||||
|
@ -173,8 +186,8 @@ impl ModuleScope {
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn get_textual_macro(&self, name: &Name) -> Option<MacroDef> {
|
fn get_legacy_macro(&self, name: &Name) -> Option<MacroDef> {
|
||||||
self.textual_macros.get(name).copied()
|
self.legacy_macros.get(name).copied()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -489,13 +502,13 @@ impl CrateDefMap {
|
||||||
name: &Name,
|
name: &Name,
|
||||||
) -> ItemOrMacro {
|
) -> ItemOrMacro {
|
||||||
// Resolve in:
|
// Resolve in:
|
||||||
// - textual scoped macros
|
// - legacy scope
|
||||||
// - current module / scope
|
// - current module / scope
|
||||||
// - extern prelude
|
// - extern prelude
|
||||||
// - std prelude
|
// - std prelude
|
||||||
let from_textual_mcro = self[module]
|
let from_legacy_macro = self[module]
|
||||||
.scope
|
.scope
|
||||||
.get_textual_macro(name)
|
.get_legacy_macro(name)
|
||||||
.map_or_else(|| Either::A(PerNs::none()), Either::B);
|
.map_or_else(|| Either::A(PerNs::none()), Either::B);
|
||||||
let from_scope =
|
let from_scope =
|
||||||
self[module].scope.get_item_or_macro(name).unwrap_or_else(|| Either::A(PerNs::none()));
|
self[module].scope.get_item_or_macro(name).unwrap_or_else(|| Either::A(PerNs::none()));
|
||||||
|
@ -503,7 +516,7 @@ impl CrateDefMap {
|
||||||
self.extern_prelude.get(name).map_or(PerNs::none(), |&it| PerNs::types(it));
|
self.extern_prelude.get(name).map_or(PerNs::none(), |&it| PerNs::types(it));
|
||||||
let from_prelude = self.resolve_in_prelude(db, name);
|
let from_prelude = self.resolve_in_prelude(db, name);
|
||||||
|
|
||||||
or(from_textual_mcro, or(from_scope, or(Either::A(from_extern_prelude), from_prelude)))
|
or(from_legacy_macro, or(from_scope, or(Either::A(from_extern_prelude), from_prelude)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_name_in_extern_prelude(&self, name: &Name) -> PerNs<ModuleDef> {
|
fn resolve_name_in_extern_prelude(&self, name: &Name) -> PerNs<ModuleDef> {
|
||||||
|
|
|
@ -146,22 +146,19 @@ where
|
||||||
self.def_map.exported_macros.insert(name.clone(), macro_id);
|
self.def_map.exported_macros.insert(name.clone(), macro_id);
|
||||||
}
|
}
|
||||||
self.update(module_id, None, &[(name.clone(), def)]);
|
self.update(module_id, None, &[(name.clone(), def)]);
|
||||||
self.define_textual_macro(module_id, name.clone(), macro_id);
|
self.define_legacy_macro(module_id, name.clone(), macro_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Define a macro in current textual scope.
|
/// Define a legacy textual scoped macro in module
|
||||||
///
|
///
|
||||||
/// We use a map `textual_macros` to store all textual macros visable per module.
|
/// We use a map `legacy_macros` to store all legacy textual scoped macros visable per module.
|
||||||
/// It will clone all macros from parent textual scope, whose definition is prior to
|
/// It will clone all macros from parent legacy scope, whose definition is prior to
|
||||||
/// the definition of current module.
|
/// the definition of current module.
|
||||||
/// And also, `macro_use` on a module will import all textual macros visable inside to
|
/// And also, `macro_use` on a module will import all legacy macros visable inside to
|
||||||
/// current textual scope, with possible shadowing.
|
/// current legacy scope, with possible shadowing.
|
||||||
fn define_textual_macro(&mut self, module_id: CrateModuleId, name: Name, macro_id: MacroDefId) {
|
fn define_legacy_macro(&mut self, module_id: CrateModuleId, name: Name, macro_id: MacroDefId) {
|
||||||
// Always shadowing
|
// Always shadowing
|
||||||
self.def_map.modules[module_id]
|
self.def_map.modules[module_id].scope.legacy_macros.insert(name, MacroDef { id: macro_id });
|
||||||
.scope
|
|
||||||
.textual_macros
|
|
||||||
.insert(name, MacroDef { id: macro_id });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Import macros from `#[macro_use] extern crate`.
|
/// Import macros from `#[macro_use] extern crate`.
|
||||||
|
@ -194,7 +191,7 @@ where
|
||||||
fn import_all_macros_exported(&mut self, current_module_id: CrateModuleId, module: Module) {
|
fn import_all_macros_exported(&mut self, current_module_id: CrateModuleId, module: Module) {
|
||||||
let item_map = self.db.crate_def_map(module.krate);
|
let item_map = self.db.crate_def_map(module.krate);
|
||||||
for (name, ¯o_id) in &item_map.exported_macros {
|
for (name, ¯o_id) in &item_map.exported_macros {
|
||||||
self.define_textual_macro(current_module_id, name.clone(), macro_id);
|
self.define_legacy_macro(current_module_id, name.clone(), macro_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -578,7 +575,7 @@ where
|
||||||
}
|
}
|
||||||
.collect(&*items);
|
.collect(&*items);
|
||||||
if *is_macro_use {
|
if *is_macro_use {
|
||||||
self.import_all_textual_macros(module_id);
|
self.import_all_legacy_macros(module_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// out of line module, resolve, parse and recurse
|
// out of line module, resolve, parse and recurse
|
||||||
|
@ -605,7 +602,7 @@ where
|
||||||
}
|
}
|
||||||
.collect(raw_items.items());
|
.collect(raw_items.items());
|
||||||
if *is_macro_use {
|
if *is_macro_use {
|
||||||
self.import_all_textual_macros(module_id);
|
self.import_all_legacy_macros(module_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(candidate) => self.def_collector.def_map.diagnostics.push(
|
Err(candidate) => self.def_collector.def_map.diagnostics.push(
|
||||||
|
@ -631,7 +628,7 @@ where
|
||||||
modules[res].parent = Some(self.module_id);
|
modules[res].parent = Some(self.module_id);
|
||||||
modules[res].declaration = Some(declaration);
|
modules[res].declaration = Some(declaration);
|
||||||
modules[res].definition = definition;
|
modules[res].definition = definition;
|
||||||
modules[res].scope.textual_macros = modules[self.module_id].scope.textual_macros.clone();
|
modules[res].scope.legacy_macros = modules[self.module_id].scope.legacy_macros.clone();
|
||||||
modules[self.module_id].children.insert(name.clone(), res);
|
modules[self.module_id].children.insert(name.clone(), res);
|
||||||
let resolution = Resolution {
|
let resolution = Resolution {
|
||||||
def: PerNs::types(
|
def: PerNs::types(
|
||||||
|
@ -685,10 +682,10 @@ where
|
||||||
|
|
||||||
let ast_id = mac.ast_id.with_file_id(self.file_id);
|
let ast_id = mac.ast_id.with_file_id(self.file_id);
|
||||||
|
|
||||||
// Case 2: try to resolve in textual scope and expand macro_rules, triggering
|
// Case 2: try to resolve in legacy scope and expand macro_rules, triggering
|
||||||
// recursive item collection.
|
// recursive item collection.
|
||||||
if let Some(macro_def) = mac.path.as_ident().and_then(|name| {
|
if let Some(macro_def) = mac.path.as_ident().and_then(|name| {
|
||||||
self.def_collector.def_map[self.module_id].scope.get_textual_macro(&name)
|
self.def_collector.def_map[self.module_id].scope.get_legacy_macro(&name)
|
||||||
}) {
|
}) {
|
||||||
let def = macro_def.id;
|
let def = macro_def.id;
|
||||||
let macro_call_id = MacroCallLoc { def, ast_id }.id(self.def_collector.db);
|
let macro_call_id = MacroCallLoc { def, ast_id }.id(self.def_collector.db);
|
||||||
|
@ -706,10 +703,10 @@ where
|
||||||
self.def_collector.unexpanded_macros.push((self.module_id, ast_id, path));
|
self.def_collector.unexpanded_macros.push((self.module_id, ast_id, path));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn import_all_textual_macros(&mut self, module_id: CrateModuleId) {
|
fn import_all_legacy_macros(&mut self, module_id: CrateModuleId) {
|
||||||
let macros = self.def_collector.def_map[module_id].scope.textual_macros.clone();
|
let macros = self.def_collector.def_map[module_id].scope.legacy_macros.clone();
|
||||||
for (name, macro_) in macros {
|
for (name, macro_) in macros {
|
||||||
self.def_collector.define_textual_macro(self.module_id, name.clone(), macro_.id);
|
self.def_collector.define_legacy_macro(self.module_id, name.clone(), macro_.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -279,7 +279,7 @@ fn prelude_cycle() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn plain_macros_are_textual_scoped() {
|
fn plain_macros_are_legacy_textual_scoped() {
|
||||||
let map = def_map(
|
let map = def_map(
|
||||||
r#"
|
r#"
|
||||||
//- /main.rs
|
//- /main.rs
|
||||||
|
|
|
@ -2804,7 +2804,7 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn infer_textual_scoped_macros_expanded() {
|
fn infer_legacy_textual_scoped_macros_expanded() {
|
||||||
assert_snapshot!(
|
assert_snapshot!(
|
||||||
infer(r#"
|
infer(r#"
|
||||||
struct Foo(Vec<i32>);
|
struct Foo(Vec<i32>);
|
||||||
|
|
Loading…
Reference in a new issue