mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-02 06:41:48 +00:00
Merge #11663
11663: Internal: Add hir_def::MacroId, add Macro{Id} to ModuleDef{Id} r=Veykril a=Veykril With this we can now handle macros like we handle ModuleDefs making them work more like other definitions and allowing us to remove a bunch of special cases. This also enables us to track the modules these macros are defined in, instead of only recording the crate they come from. Introduces a new class of `MacroId`s (for each of the 3 macro kinds) into `hir_def`. We can't reuse `MacroDefId` as that is defined in `hir_expand` which doesn't know of modules, so now we have two different macro ids, this unfortunately requires some back and forth mapping between the two via database accesses which I hope won't be too expensive. Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
This commit is contained in:
commit
d70ea759b3
61 changed files with 1108 additions and 796 deletions
|
@ -1,6 +1,5 @@
|
||||||
//! Attributes & documentation for hir types.
|
//! Attributes & documentation for hir types.
|
||||||
|
|
||||||
use either::Either;
|
|
||||||
use hir_def::{
|
use hir_def::{
|
||||||
attr::{AttrsWithOwner, Documentation},
|
attr::{AttrsWithOwner, Documentation},
|
||||||
item_scope::ItemInNs,
|
item_scope::ItemInNs,
|
||||||
|
@ -9,13 +8,13 @@ use hir_def::{
|
||||||
resolver::HasResolver,
|
resolver::HasResolver,
|
||||||
AttrDefId, GenericParamId, ModuleDefId,
|
AttrDefId, GenericParamId, ModuleDefId,
|
||||||
};
|
};
|
||||||
use hir_expand::{hygiene::Hygiene, MacroDefId};
|
use hir_expand::hygiene::Hygiene;
|
||||||
use hir_ty::db::HirDatabase;
|
use hir_ty::db::HirDatabase;
|
||||||
use syntax::{ast, AstNode};
|
use syntax::{ast, AstNode};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Adt, AssocItem, Const, ConstParam, Enum, Field, Function, GenericParam, Impl, LifetimeParam,
|
Adt, AssocItem, Const, ConstParam, Enum, Field, Function, GenericParam, Impl, LifetimeParam,
|
||||||
MacroDef, Module, ModuleDef, Static, Struct, Trait, TypeAlias, TypeParam, Union, Variant,
|
Macro, Module, ModuleDef, Static, Struct, Trait, TypeAlias, TypeParam, Union, Variant,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait HasAttrs {
|
pub trait HasAttrs {
|
||||||
|
@ -26,7 +25,7 @@ pub trait HasAttrs {
|
||||||
db: &dyn HirDatabase,
|
db: &dyn HirDatabase,
|
||||||
link: &str,
|
link: &str,
|
||||||
ns: Option<Namespace>,
|
ns: Option<Namespace>,
|
||||||
) -> Option<Either<ModuleDef, MacroDef>>;
|
) -> Option<ModuleDef>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)]
|
#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)]
|
||||||
|
@ -47,9 +46,9 @@ macro_rules! impl_has_attrs {
|
||||||
let def = AttrDefId::$def_id(self.into());
|
let def = AttrDefId::$def_id(self.into());
|
||||||
db.attrs(def).docs()
|
db.attrs(def).docs()
|
||||||
}
|
}
|
||||||
fn resolve_doc_path(self, db: &dyn HirDatabase, link: &str, ns: Option<Namespace>) -> Option<Either<ModuleDef, MacroDef>> {
|
fn resolve_doc_path(self, db: &dyn HirDatabase, link: &str, ns: Option<Namespace>) -> Option<ModuleDef> {
|
||||||
let def = AttrDefId::$def_id(self.into());
|
let def = AttrDefId::$def_id(self.into());
|
||||||
resolve_doc_path(db, def, link, ns).map(|it| it.map_left(ModuleDef::from).map_right(MacroDef::from))
|
resolve_doc_path(db, def, link, ns).map(ModuleDef::from)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)*};
|
)*};
|
||||||
|
@ -62,7 +61,7 @@ impl_has_attrs![
|
||||||
(Const, ConstId),
|
(Const, ConstId),
|
||||||
(Trait, TraitId),
|
(Trait, TraitId),
|
||||||
(TypeAlias, TypeAliasId),
|
(TypeAlias, TypeAliasId),
|
||||||
(MacroDef, MacroDefId),
|
(Macro, MacroId),
|
||||||
(Function, FunctionId),
|
(Function, FunctionId),
|
||||||
(Adt, AdtId),
|
(Adt, AdtId),
|
||||||
(Module, ModuleId),
|
(Module, ModuleId),
|
||||||
|
@ -79,7 +78,7 @@ macro_rules! impl_has_attrs_enum {
|
||||||
fn docs(self, db: &dyn HirDatabase) -> Option<Documentation> {
|
fn docs(self, db: &dyn HirDatabase) -> Option<Documentation> {
|
||||||
$enum::$variant(self).docs(db)
|
$enum::$variant(self).docs(db)
|
||||||
}
|
}
|
||||||
fn resolve_doc_path(self, db: &dyn HirDatabase, link: &str, ns: Option<Namespace>) -> Option<Either<ModuleDef, MacroDef>> {
|
fn resolve_doc_path(self, db: &dyn HirDatabase, link: &str, ns: Option<Namespace>) -> Option<ModuleDef> {
|
||||||
$enum::$variant(self).resolve_doc_path(db, link, ns)
|
$enum::$variant(self).resolve_doc_path(db, link, ns)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,7 +110,7 @@ impl HasAttrs for AssocItem {
|
||||||
db: &dyn HirDatabase,
|
db: &dyn HirDatabase,
|
||||||
link: &str,
|
link: &str,
|
||||||
ns: Option<Namespace>,
|
ns: Option<Namespace>,
|
||||||
) -> Option<Either<ModuleDef, MacroDef>> {
|
) -> Option<ModuleDef> {
|
||||||
match self {
|
match self {
|
||||||
AssocItem::Function(it) => it.resolve_doc_path(db, link, ns),
|
AssocItem::Function(it) => it.resolve_doc_path(db, link, ns),
|
||||||
AssocItem::Const(it) => it.resolve_doc_path(db, link, ns),
|
AssocItem::Const(it) => it.resolve_doc_path(db, link, ns),
|
||||||
|
@ -125,7 +124,7 @@ fn resolve_doc_path(
|
||||||
def: AttrDefId,
|
def: AttrDefId,
|
||||||
link: &str,
|
link: &str,
|
||||||
ns: Option<Namespace>,
|
ns: Option<Namespace>,
|
||||||
) -> Option<Either<ModuleDefId, MacroDefId>> {
|
) -> Option<ModuleDefId> {
|
||||||
let resolver = match def {
|
let resolver = match def {
|
||||||
AttrDefId::ModuleId(it) => it.resolver(db.upcast()),
|
AttrDefId::ModuleId(it) => it.resolver(db.upcast()),
|
||||||
AttrDefId::FieldId(it) => it.parent.resolver(db.upcast()),
|
AttrDefId::FieldId(it) => it.parent.resolver(db.upcast()),
|
||||||
|
@ -138,14 +137,13 @@ fn resolve_doc_path(
|
||||||
AttrDefId::TypeAliasId(it) => it.resolver(db.upcast()),
|
AttrDefId::TypeAliasId(it) => it.resolver(db.upcast()),
|
||||||
AttrDefId::ImplId(it) => it.resolver(db.upcast()),
|
AttrDefId::ImplId(it) => it.resolver(db.upcast()),
|
||||||
AttrDefId::ExternBlockId(it) => it.resolver(db.upcast()),
|
AttrDefId::ExternBlockId(it) => it.resolver(db.upcast()),
|
||||||
|
AttrDefId::MacroId(it) => it.resolver(db.upcast()),
|
||||||
AttrDefId::GenericParamId(it) => match it {
|
AttrDefId::GenericParamId(it) => match it {
|
||||||
GenericParamId::TypeParamId(it) => it.parent(),
|
GenericParamId::TypeParamId(it) => it.parent(),
|
||||||
GenericParamId::ConstParamId(it) => it.parent(),
|
GenericParamId::ConstParamId(it) => it.parent(),
|
||||||
GenericParamId::LifetimeParamId(it) => it.parent,
|
GenericParamId::LifetimeParamId(it) => it.parent,
|
||||||
}
|
}
|
||||||
.resolver(db.upcast()),
|
.resolver(db.upcast()),
|
||||||
// FIXME
|
|
||||||
AttrDefId::MacroDefId(_) => return None,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let modpath = {
|
let modpath = {
|
||||||
|
@ -167,13 +165,13 @@ fn resolve_doc_path(
|
||||||
resolved
|
resolved
|
||||||
};
|
};
|
||||||
match ns {
|
match ns {
|
||||||
Some(Namespace::Types) => resolved.take_types().map(Either::Left),
|
Some(Namespace::Types) => resolved.take_types(),
|
||||||
Some(Namespace::Values) => resolved.take_values().map(Either::Left),
|
Some(Namespace::Values) => resolved.take_values(),
|
||||||
Some(Namespace::Macros) => resolved.take_macros().map(Either::Right),
|
Some(Namespace::Macros) => resolved.take_macros().map(ModuleDefId::MacroId),
|
||||||
None => resolved.iter_items().next().map(|it| match it {
|
None => resolved.iter_items().next().map(|it| match it {
|
||||||
ItemInNs::Types(it) => Either::Left(it),
|
ItemInNs::Types(it) => it,
|
||||||
ItemInNs::Values(it) => Either::Left(it),
|
ItemInNs::Values(it) => it,
|
||||||
ItemInNs::Macros(it) => Either::Right(it),
|
ItemInNs::Macros(it) => ModuleDefId::MacroId(it),
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ from_id![
|
||||||
(hir_def::TypeParamId, crate::TypeParam),
|
(hir_def::TypeParamId, crate::TypeParam),
|
||||||
(hir_def::ConstParamId, crate::ConstParam),
|
(hir_def::ConstParamId, crate::ConstParam),
|
||||||
(hir_def::LifetimeParamId, crate::LifetimeParam),
|
(hir_def::LifetimeParamId, crate::LifetimeParam),
|
||||||
(hir_expand::MacroDefId, crate::MacroDef)
|
(hir_def::MacroId, crate::Macro)
|
||||||
];
|
];
|
||||||
|
|
||||||
impl From<AdtId> for Adt {
|
impl From<AdtId> for Adt {
|
||||||
|
@ -112,6 +112,7 @@ impl From<ModuleDefId> for ModuleDef {
|
||||||
ModuleDefId::TraitId(it) => ModuleDef::Trait(it.into()),
|
ModuleDefId::TraitId(it) => ModuleDef::Trait(it.into()),
|
||||||
ModuleDefId::TypeAliasId(it) => ModuleDef::TypeAlias(it.into()),
|
ModuleDefId::TypeAliasId(it) => ModuleDef::TypeAlias(it.into()),
|
||||||
ModuleDefId::BuiltinType(it) => ModuleDef::BuiltinType(it.into()),
|
ModuleDefId::BuiltinType(it) => ModuleDef::BuiltinType(it.into()),
|
||||||
|
ModuleDefId::MacroId(it) => ModuleDef::Macro(it.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,6 +129,7 @@ impl From<ModuleDef> for ModuleDefId {
|
||||||
ModuleDef::Trait(it) => ModuleDefId::TraitId(it.into()),
|
ModuleDef::Trait(it) => ModuleDefId::TraitId(it.into()),
|
||||||
ModuleDef::TypeAlias(it) => ModuleDefId::TypeAliasId(it.into()),
|
ModuleDef::TypeAlias(it) => ModuleDefId::TypeAliasId(it.into()),
|
||||||
ModuleDef::BuiltinType(it) => ModuleDefId::BuiltinType(it.into()),
|
ModuleDef::BuiltinType(it) => ModuleDefId::BuiltinType(it.into()),
|
||||||
|
ModuleDef::Macro(it) => ModuleDefId::MacroId(it.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,13 +4,13 @@ use either::Either;
|
||||||
use hir_def::{
|
use hir_def::{
|
||||||
nameres::{ModuleOrigin, ModuleSource},
|
nameres::{ModuleOrigin, ModuleSource},
|
||||||
src::{HasChildSource, HasSource as _},
|
src::{HasChildSource, HasSource as _},
|
||||||
Lookup, VariantId,
|
Lookup, MacroId, VariantId,
|
||||||
};
|
};
|
||||||
use hir_expand::InFile;
|
use hir_expand::InFile;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
db::HirDatabase, Adt, Const, Enum, Field, FieldSource, Function, Impl, LifetimeParam, MacroDef,
|
db::HirDatabase, Adt, Const, Enum, Field, FieldSource, Function, Impl, LifetimeParam, Macro,
|
||||||
Module, Static, Struct, Trait, TypeAlias, TypeOrConstParam, Union, Variant,
|
Module, Static, Struct, Trait, TypeAlias, TypeOrConstParam, Union, Variant,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -123,13 +123,26 @@ impl HasSource for TypeAlias {
|
||||||
Some(self.id.lookup(db.upcast()).source(db.upcast()))
|
Some(self.id.lookup(db.upcast()).source(db.upcast()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl HasSource for MacroDef {
|
impl HasSource for Macro {
|
||||||
type Ast = Either<ast::Macro, ast::Fn>;
|
type Ast = Either<ast::Macro, ast::Fn>;
|
||||||
fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> {
|
fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> {
|
||||||
Some(self.id.ast_id().either(
|
match self.id {
|
||||||
|id| id.with_value(Either::Left(id.to_node(db.upcast()))),
|
MacroId::Macro2Id(it) => Some(
|
||||||
|id| id.with_value(Either::Right(id.to_node(db.upcast()))),
|
it.lookup(db.upcast())
|
||||||
))
|
.source(db.upcast())
|
||||||
|
.map(ast::Macro::MacroDef)
|
||||||
|
.map(Either::Left),
|
||||||
|
),
|
||||||
|
MacroId::MacroRulesId(it) => Some(
|
||||||
|
it.lookup(db.upcast())
|
||||||
|
.source(db.upcast())
|
||||||
|
.map(ast::Macro::MacroRules)
|
||||||
|
.map(Either::Left),
|
||||||
|
),
|
||||||
|
MacroId::ProcMacroId(it) => {
|
||||||
|
Some(it.lookup(db.upcast()).source(db.upcast()).map(Either::Right))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl HasSource for Impl {
|
impl HasSource for Impl {
|
||||||
|
|
|
@ -35,7 +35,7 @@ mod display;
|
||||||
use std::{collections::HashMap, iter, ops::ControlFlow, sync::Arc};
|
use std::{collections::HashMap, iter, ops::ControlFlow, sync::Arc};
|
||||||
|
|
||||||
use arrayvec::ArrayVec;
|
use arrayvec::ArrayVec;
|
||||||
use base_db::{CrateDisplayName, CrateId, CrateOrigin, Edition, FileId};
|
use base_db::{CrateDisplayName, CrateId, CrateOrigin, Edition, FileId, ProcMacroKind};
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use hir_def::{
|
use hir_def::{
|
||||||
adt::{ReprKind, VariantData},
|
adt::{ReprKind, VariantData},
|
||||||
|
@ -49,10 +49,10 @@ use hir_def::{
|
||||||
src::HasSource as _,
|
src::HasSource as _,
|
||||||
AdtId, AssocItemId, AssocItemLoc, AttrDefId, ConstId, ConstParamId, DefWithBodyId, EnumId,
|
AdtId, AssocItemId, AssocItemLoc, AttrDefId, ConstId, ConstParamId, DefWithBodyId, EnumId,
|
||||||
FunctionId, GenericDefId, HasModule, ImplId, ItemContainerId, LifetimeParamId,
|
FunctionId, GenericDefId, HasModule, ImplId, ItemContainerId, LifetimeParamId,
|
||||||
LocalEnumVariantId, LocalFieldId, Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId,
|
LocalEnumVariantId, LocalFieldId, Lookup, MacroExpander, MacroId, ModuleId, StaticId, StructId,
|
||||||
TypeOrConstParamId, TypeParamId, UnionId,
|
TraitId, TypeAliasId, TypeOrConstParamId, TypeParamId, UnionId,
|
||||||
};
|
};
|
||||||
use hir_expand::{name::name, MacroCallKind, MacroDefId, MacroDefKind};
|
use hir_expand::{name::name, MacroCallKind};
|
||||||
use hir_ty::{
|
use hir_ty::{
|
||||||
autoderef,
|
autoderef,
|
||||||
consteval::{eval_const, ComputedExpr, ConstEvalCtx, ConstEvalError, ConstExt},
|
consteval::{eval_const, ComputedExpr, ConstEvalCtx, ConstEvalError, ConstExt},
|
||||||
|
@ -207,7 +207,7 @@ impl Crate {
|
||||||
self,
|
self,
|
||||||
db: &dyn DefDatabase,
|
db: &dyn DefDatabase,
|
||||||
query: import_map::Query,
|
query: import_map::Query,
|
||||||
) -> impl Iterator<Item = Either<ModuleDef, MacroDef>> {
|
) -> impl Iterator<Item = Either<ModuleDef, Macro>> {
|
||||||
let _p = profile::span("query_external_importables");
|
let _p = profile::span("query_external_importables");
|
||||||
import_map::search_dependencies(db, self.into(), query).into_iter().map(|item| {
|
import_map::search_dependencies(db, self.into(), query).into_iter().map(|item| {
|
||||||
match ItemInNs::from(item) {
|
match ItemInNs::from(item) {
|
||||||
|
@ -272,6 +272,7 @@ pub enum ModuleDef {
|
||||||
Trait(Trait),
|
Trait(Trait),
|
||||||
TypeAlias(TypeAlias),
|
TypeAlias(TypeAlias),
|
||||||
BuiltinType(BuiltinType),
|
BuiltinType(BuiltinType),
|
||||||
|
Macro(Macro),
|
||||||
}
|
}
|
||||||
impl_from!(
|
impl_from!(
|
||||||
Module,
|
Module,
|
||||||
|
@ -282,7 +283,8 @@ impl_from!(
|
||||||
Static,
|
Static,
|
||||||
Trait,
|
Trait,
|
||||||
TypeAlias,
|
TypeAlias,
|
||||||
BuiltinType
|
BuiltinType,
|
||||||
|
Macro
|
||||||
for ModuleDef
|
for ModuleDef
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -307,6 +309,7 @@ impl ModuleDef {
|
||||||
ModuleDef::Static(it) => Some(it.module(db)),
|
ModuleDef::Static(it) => Some(it.module(db)),
|
||||||
ModuleDef::Trait(it) => Some(it.module(db)),
|
ModuleDef::Trait(it) => Some(it.module(db)),
|
||||||
ModuleDef::TypeAlias(it) => Some(it.module(db)),
|
ModuleDef::TypeAlias(it) => Some(it.module(db)),
|
||||||
|
ModuleDef::Macro(it) => Some(it.module(db)),
|
||||||
ModuleDef::BuiltinType(_) => None,
|
ModuleDef::BuiltinType(_) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -337,6 +340,7 @@ impl ModuleDef {
|
||||||
ModuleDef::Variant(it) => it.name(db),
|
ModuleDef::Variant(it) => it.name(db),
|
||||||
ModuleDef::TypeAlias(it) => it.name(db),
|
ModuleDef::TypeAlias(it) => it.name(db),
|
||||||
ModuleDef::Static(it) => it.name(db),
|
ModuleDef::Static(it) => it.name(db),
|
||||||
|
ModuleDef::Macro(it) => it.name(db),
|
||||||
ModuleDef::BuiltinType(it) => it.name(),
|
ModuleDef::BuiltinType(it) => it.name(),
|
||||||
};
|
};
|
||||||
Some(name)
|
Some(name)
|
||||||
|
@ -390,6 +394,7 @@ impl ModuleDef {
|
||||||
| ModuleDef::Variant(_)
|
| ModuleDef::Variant(_)
|
||||||
| ModuleDef::Trait(_)
|
| ModuleDef::Trait(_)
|
||||||
| ModuleDef::TypeAlias(_)
|
| ModuleDef::TypeAlias(_)
|
||||||
|
| ModuleDef::Macro(_)
|
||||||
| ModuleDef::BuiltinType(_) => None,
|
| ModuleDef::BuiltinType(_) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -404,6 +409,7 @@ impl ModuleDef {
|
||||||
ModuleDef::Static(it) => it.attrs(db),
|
ModuleDef::Static(it) => it.attrs(db),
|
||||||
ModuleDef::Trait(it) => it.attrs(db),
|
ModuleDef::Trait(it) => it.attrs(db),
|
||||||
ModuleDef::TypeAlias(it) => it.attrs(db),
|
ModuleDef::TypeAlias(it) => it.attrs(db),
|
||||||
|
ModuleDef::Macro(it) => it.attrs(db),
|
||||||
ModuleDef::BuiltinType(_) => return None,
|
ModuleDef::BuiltinType(_) => return None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -420,6 +426,7 @@ impl HasVisibility for ModuleDef {
|
||||||
ModuleDef::Trait(it) => it.visibility(db),
|
ModuleDef::Trait(it) => it.visibility(db),
|
||||||
ModuleDef::TypeAlias(it) => it.visibility(db),
|
ModuleDef::TypeAlias(it) => it.visibility(db),
|
||||||
ModuleDef::Variant(it) => it.visibility(db),
|
ModuleDef::Variant(it) => it.visibility(db),
|
||||||
|
ModuleDef::Macro(it) => it.visibility(db),
|
||||||
ModuleDef::BuiltinType(_) => Visibility::Public,
|
ModuleDef::BuiltinType(_) => Visibility::Public,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1376,9 +1383,10 @@ impl Function {
|
||||||
db.function_data(self.id).has_body()
|
db.function_data(self.id).has_body()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_proc_macro(self, db: &dyn HirDatabase) -> Option<MacroDef> {
|
pub fn as_proc_macro(self, db: &dyn HirDatabase) -> Option<Macro> {
|
||||||
let function_data = db.function_data(self.id);
|
let function_data = db.function_data(self.id);
|
||||||
let attrs = &function_data.attrs;
|
let attrs = &function_data.attrs;
|
||||||
|
// FIXME: Store this in FunctionData flags?
|
||||||
if !(attrs.is_proc_macro()
|
if !(attrs.is_proc_macro()
|
||||||
|| attrs.is_proc_macro_attribute()
|
|| attrs.is_proc_macro_attribute()
|
||||||
|| attrs.is_proc_macro_derive())
|
|| attrs.is_proc_macro_derive())
|
||||||
|
@ -1386,15 +1394,8 @@ impl Function {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let loc = self.id.lookup(db.upcast());
|
let loc = self.id.lookup(db.upcast());
|
||||||
let krate = loc.krate(db);
|
let def_map = db.crate_def_map(loc.krate(db).into());
|
||||||
let def_map = db.crate_def_map(krate.into());
|
def_map.fn_as_proc_macro(self.id).map(|id| Macro { id: id.into() })
|
||||||
let ast_id =
|
|
||||||
InFile::new(loc.id.file_id(), loc.id.item_tree(db.upcast())[loc.id.value].ast_id);
|
|
||||||
|
|
||||||
let mut exported_proc_macros = def_map.exported_proc_macros();
|
|
||||||
exported_proc_macros
|
|
||||||
.find(|&(id, _)| matches!(id.kind, MacroDefKind::ProcMacro(_, _, id) if id == ast_id))
|
|
||||||
.map(|(id, _)| MacroDef { id })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A textual representation of the HIR of this function for debugging purposes.
|
/// A textual representation of the HIR of this function for debugging purposes.
|
||||||
|
@ -1747,61 +1748,82 @@ pub enum MacroKind {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
pub struct MacroDef {
|
pub struct Macro {
|
||||||
pub(crate) id: MacroDefId,
|
pub(crate) id: MacroId,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MacroDef {
|
impl Macro {
|
||||||
/// FIXME: right now, this just returns the root module of the crate that
|
pub fn module(self, db: &dyn HirDatabase) -> Module {
|
||||||
/// defines this macro. The reasons for this is that macros are expanded
|
Module { id: self.id.module(db.upcast()) }
|
||||||
/// early, in `hir_expand`, where modules simply do not exist yet.
|
|
||||||
pub fn module(self, db: &dyn HirDatabase) -> Option<Module> {
|
|
||||||
let krate = self.id.krate;
|
|
||||||
let def_map = db.crate_def_map(krate);
|
|
||||||
let module_id = def_map.root();
|
|
||||||
Some(Module { id: def_map.module_id(module_id) })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// XXX: this parses the file
|
pub fn name(self, db: &dyn HirDatabase) -> Name {
|
||||||
pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
|
match self.id {
|
||||||
match self.source(db)?.value {
|
MacroId::Macro2Id(id) => db.macro2_data(id).name.clone(),
|
||||||
Either::Left(it) => it.name().map(|it| it.as_name()),
|
MacroId::MacroRulesId(id) => db.macro_rules_data(id).name.clone(),
|
||||||
Either::Right(_) => {
|
MacroId::ProcMacroId(id) => db.proc_macro_data(id).name.clone(),
|
||||||
let krate = self.id.krate;
|
|
||||||
let def_map = db.crate_def_map(krate);
|
|
||||||
let (_, name) = def_map.exported_proc_macros().find(|&(id, _)| id == self.id)?;
|
|
||||||
Some(name)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn kind(&self) -> MacroKind {
|
pub fn kind(&self, db: &dyn HirDatabase) -> MacroKind {
|
||||||
match self.id.kind {
|
match self.id {
|
||||||
MacroDefKind::Declarative(_) => MacroKind::Declarative,
|
MacroId::Macro2Id(it) => match it.lookup(db.upcast()).expander {
|
||||||
MacroDefKind::BuiltIn(_, _) | MacroDefKind::BuiltInEager(_, _) => MacroKind::BuiltIn,
|
MacroExpander::Declarative => MacroKind::Declarative,
|
||||||
MacroDefKind::BuiltInDerive(_, _) => MacroKind::Derive,
|
MacroExpander::BuiltIn(_) | MacroExpander::BuiltInEager(_) => MacroKind::BuiltIn,
|
||||||
MacroDefKind::BuiltInAttr(_, _) => MacroKind::Attr,
|
MacroExpander::BuiltInAttr(_) => MacroKind::Attr,
|
||||||
MacroDefKind::ProcMacro(_, base_db::ProcMacroKind::CustomDerive, _) => {
|
MacroExpander::BuiltInDerive(_) => MacroKind::Derive,
|
||||||
MacroKind::Derive
|
},
|
||||||
}
|
MacroId::MacroRulesId(it) => match it.lookup(db.upcast()).expander {
|
||||||
MacroDefKind::ProcMacro(_, base_db::ProcMacroKind::Attr, _) => MacroKind::Attr,
|
MacroExpander::Declarative => MacroKind::Declarative,
|
||||||
MacroDefKind::ProcMacro(_, base_db::ProcMacroKind::FuncLike, _) => MacroKind::ProcMacro,
|
MacroExpander::BuiltIn(_) | MacroExpander::BuiltInEager(_) => MacroKind::BuiltIn,
|
||||||
|
MacroExpander::BuiltInAttr(_) => MacroKind::Attr,
|
||||||
|
MacroExpander::BuiltInDerive(_) => MacroKind::Derive,
|
||||||
|
},
|
||||||
|
MacroId::ProcMacroId(it) => match it.lookup(db.upcast()).kind {
|
||||||
|
ProcMacroKind::CustomDerive => MacroKind::Derive,
|
||||||
|
ProcMacroKind::FuncLike => MacroKind::ProcMacro,
|
||||||
|
ProcMacroKind::Attr => MacroKind::Attr,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_fn_like(&self) -> bool {
|
pub fn is_fn_like(&self, db: &dyn HirDatabase) -> bool {
|
||||||
match self.kind() {
|
match self.kind(db) {
|
||||||
MacroKind::Declarative | MacroKind::BuiltIn | MacroKind::ProcMacro => true,
|
MacroKind::Declarative | MacroKind::BuiltIn | MacroKind::ProcMacro => true,
|
||||||
MacroKind::Attr | MacroKind::Derive => false,
|
MacroKind::Attr | MacroKind::Derive => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_builtin_derive(&self) -> bool {
|
pub fn is_builtin_derive(&self, db: &dyn HirDatabase) -> bool {
|
||||||
matches!(self.id.kind, MacroDefKind::BuiltInAttr(exp, _) if exp.is_derive())
|
match self.id {
|
||||||
|
MacroId::Macro2Id(it) => match it.lookup(db.upcast()).expander {
|
||||||
|
MacroExpander::BuiltInDerive(_) => true,
|
||||||
|
_ => false,
|
||||||
|
},
|
||||||
|
MacroId::MacroRulesId(it) => match it.lookup(db.upcast()).expander {
|
||||||
|
MacroExpander::BuiltInDerive(_) => true,
|
||||||
|
_ => false,
|
||||||
|
},
|
||||||
|
MacroId::ProcMacroId(_) => false,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_attr(&self) -> bool {
|
pub fn is_attr(&self, db: &dyn HirDatabase) -> bool {
|
||||||
matches!(self.kind(), MacroKind::Attr)
|
matches!(self.kind(db), MacroKind::Attr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HasVisibility for Macro {
|
||||||
|
fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
|
||||||
|
match self.id {
|
||||||
|
MacroId::Macro2Id(id) => {
|
||||||
|
let data = db.macro2_data(id);
|
||||||
|
let visibility = &data.visibility;
|
||||||
|
visibility.resolve(db.upcast(), &self.id.resolver(db.upcast()))
|
||||||
|
}
|
||||||
|
MacroId::MacroRulesId(_) => Visibility::Public,
|
||||||
|
MacroId::ProcMacroId(_) => Visibility::Public,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1809,11 +1831,11 @@ impl MacroDef {
|
||||||
pub enum ItemInNs {
|
pub enum ItemInNs {
|
||||||
Types(ModuleDef),
|
Types(ModuleDef),
|
||||||
Values(ModuleDef),
|
Values(ModuleDef),
|
||||||
Macros(MacroDef),
|
Macros(Macro),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<MacroDef> for ItemInNs {
|
impl From<Macro> for ItemInNs {
|
||||||
fn from(it: MacroDef) -> Self {
|
fn from(it: Macro) -> Self {
|
||||||
Self::Macros(it)
|
Self::Macros(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1841,7 +1863,7 @@ impl ItemInNs {
|
||||||
pub fn krate(&self, db: &dyn HirDatabase) -> Option<Crate> {
|
pub fn krate(&self, db: &dyn HirDatabase) -> Option<Crate> {
|
||||||
match self {
|
match self {
|
||||||
ItemInNs::Types(did) | ItemInNs::Values(did) => did.module(db).map(|m| m.krate()),
|
ItemInNs::Types(did) | ItemInNs::Values(did) => did.module(db).map(|m| m.krate()),
|
||||||
ItemInNs::Macros(id) => id.module(db).map(|m| m.krate()),
|
ItemInNs::Macros(id) => Some(id.module(db).krate()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3224,7 +3246,6 @@ impl Callable {
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
pub enum ScopeDef {
|
pub enum ScopeDef {
|
||||||
ModuleDef(ModuleDef),
|
ModuleDef(ModuleDef),
|
||||||
MacroDef(MacroDef),
|
|
||||||
GenericParam(GenericParam),
|
GenericParam(GenericParam),
|
||||||
ImplSelfType(Impl),
|
ImplSelfType(Impl),
|
||||||
AdtSelfType(Adt),
|
AdtSelfType(Adt),
|
||||||
|
@ -3255,7 +3276,7 @@ impl ScopeDef {
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(macro_def_id) = def.take_macros() {
|
if let Some(macro_def_id) = def.take_macros() {
|
||||||
items.push(ScopeDef::MacroDef(macro_def_id.into()));
|
items.push(ScopeDef::ModuleDef(ModuleDef::Macro(macro_def_id.into())));
|
||||||
}
|
}
|
||||||
|
|
||||||
if items.is_empty() {
|
if items.is_empty() {
|
||||||
|
@ -3268,7 +3289,6 @@ impl ScopeDef {
|
||||||
pub fn attrs(&self, db: &dyn HirDatabase) -> Option<AttrsWithOwner> {
|
pub fn attrs(&self, db: &dyn HirDatabase) -> Option<AttrsWithOwner> {
|
||||||
match self {
|
match self {
|
||||||
ScopeDef::ModuleDef(it) => it.attrs(db),
|
ScopeDef::ModuleDef(it) => it.attrs(db),
|
||||||
ScopeDef::MacroDef(it) => Some(it.attrs(db)),
|
|
||||||
ScopeDef::GenericParam(it) => Some(it.attrs(db)),
|
ScopeDef::GenericParam(it) => Some(it.attrs(db)),
|
||||||
ScopeDef::ImplSelfType(_)
|
ScopeDef::ImplSelfType(_)
|
||||||
| ScopeDef::AdtSelfType(_)
|
| ScopeDef::AdtSelfType(_)
|
||||||
|
@ -3281,7 +3301,6 @@ impl ScopeDef {
|
||||||
pub fn krate(&self, db: &dyn HirDatabase) -> Option<Crate> {
|
pub fn krate(&self, db: &dyn HirDatabase) -> Option<Crate> {
|
||||||
match self {
|
match self {
|
||||||
ScopeDef::ModuleDef(it) => it.module(db).map(|m| m.krate()),
|
ScopeDef::ModuleDef(it) => it.module(db).map(|m| m.krate()),
|
||||||
ScopeDef::MacroDef(it) => it.module(db).map(|m| m.krate()),
|
|
||||||
ScopeDef::GenericParam(it) => Some(it.module(db).krate()),
|
ScopeDef::GenericParam(it) => Some(it.module(db).krate()),
|
||||||
ScopeDef::ImplSelfType(_) => None,
|
ScopeDef::ImplSelfType(_) => None,
|
||||||
ScopeDef::AdtSelfType(it) => Some(it.module(db).krate()),
|
ScopeDef::AdtSelfType(it) => Some(it.module(db).krate()),
|
||||||
|
@ -3297,7 +3316,7 @@ impl From<ItemInNs> for ScopeDef {
|
||||||
match item {
|
match item {
|
||||||
ItemInNs::Types(id) => ScopeDef::ModuleDef(id),
|
ItemInNs::Types(id) => ScopeDef::ModuleDef(id),
|
||||||
ItemInNs::Values(id) => ScopeDef::ModuleDef(id),
|
ItemInNs::Values(id) => ScopeDef::ModuleDef(id),
|
||||||
ItemInNs::Macros(id) => ScopeDef::MacroDef(id),
|
ItemInNs::Macros(id) => ScopeDef::ModuleDef(ModuleDef::Macro(id)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3356,3 +3375,9 @@ impl HasCrate for Type {
|
||||||
self.krate.into()
|
self.krate.into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl HasCrate for Macro {
|
||||||
|
fn krate(&self, db: &dyn HirDatabase) -> Crate {
|
||||||
|
self.module(db).krate()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -6,11 +6,12 @@ use std::{cell::RefCell, fmt, iter};
|
||||||
|
|
||||||
use base_db::{FileId, FileRange};
|
use base_db::{FileId, FileRange};
|
||||||
use hir_def::{
|
use hir_def::{
|
||||||
body,
|
body, macro_id_to_def_id,
|
||||||
resolver::{self, HasResolver, Resolver, TypeNs},
|
resolver::{self, HasResolver, Resolver, TypeNs},
|
||||||
AsMacroCall, FunctionId, TraitId, VariantId,
|
AsMacroCall, FunctionId, MacroId, TraitId, VariantId,
|
||||||
};
|
};
|
||||||
use hir_expand::{
|
use hir_expand::{
|
||||||
|
db::AstDatabase,
|
||||||
name::{known, AsName},
|
name::{known, AsName},
|
||||||
ExpansionInfo, MacroCallId,
|
ExpansionInfo, MacroCallId,
|
||||||
};
|
};
|
||||||
|
@ -29,7 +30,7 @@ use crate::{
|
||||||
semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx},
|
semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx},
|
||||||
source_analyzer::{resolve_hir_path, SourceAnalyzer},
|
source_analyzer::{resolve_hir_path, SourceAnalyzer},
|
||||||
Access, AssocItem, BuiltinAttr, Callable, ConstParam, Crate, Field, Function, HasSource,
|
Access, AssocItem, BuiltinAttr, Callable, ConstParam, Crate, Field, Function, HasSource,
|
||||||
HirFileId, Impl, InFile, Label, LifetimeParam, Local, MacroDef, Module, ModuleDef, Name, Path,
|
HirFileId, Impl, InFile, Label, LifetimeParam, Local, Macro, Module, ModuleDef, Name, Path,
|
||||||
ScopeDef, ToolModule, Trait, Type, TypeAlias, TypeParam, VariantDef,
|
ScopeDef, ToolModule, Trait, Type, TypeAlias, TypeParam, VariantDef,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -44,7 +45,6 @@ pub enum PathResolution {
|
||||||
/// A const parameter
|
/// A const parameter
|
||||||
ConstParam(ConstParam),
|
ConstParam(ConstParam),
|
||||||
SelfType(Impl),
|
SelfType(Impl),
|
||||||
Macro(MacroDef),
|
|
||||||
AssocItem(AssocItem),
|
AssocItem(AssocItem),
|
||||||
BuiltinAttr(BuiltinAttr),
|
BuiltinAttr(BuiltinAttr),
|
||||||
ToolModule(ToolModule),
|
ToolModule(ToolModule),
|
||||||
|
@ -60,6 +60,7 @@ impl PathResolution {
|
||||||
PathResolution::Def(
|
PathResolution::Def(
|
||||||
ModuleDef::Const(_)
|
ModuleDef::Const(_)
|
||||||
| ModuleDef::Variant(_)
|
| ModuleDef::Variant(_)
|
||||||
|
| ModuleDef::Macro(_)
|
||||||
| ModuleDef::Function(_)
|
| ModuleDef::Function(_)
|
||||||
| ModuleDef::Module(_)
|
| ModuleDef::Module(_)
|
||||||
| ModuleDef::Static(_)
|
| ModuleDef::Static(_)
|
||||||
|
@ -71,7 +72,6 @@ impl PathResolution {
|
||||||
PathResolution::BuiltinAttr(_)
|
PathResolution::BuiltinAttr(_)
|
||||||
| PathResolution::ToolModule(_)
|
| PathResolution::ToolModule(_)
|
||||||
| PathResolution::Local(_)
|
| PathResolution::Local(_)
|
||||||
| PathResolution::Macro(_)
|
|
||||||
| PathResolution::ConstParam(_) => None,
|
| PathResolution::ConstParam(_) => None,
|
||||||
PathResolution::TypeParam(param) => Some(TypeNs::GenericParam((*param).into())),
|
PathResolution::TypeParam(param) => Some(TypeNs::GenericParam((*param).into())),
|
||||||
PathResolution::SelfType(impl_def) => Some(TypeNs::SelfType((*impl_def).into())),
|
PathResolution::SelfType(impl_def) => Some(TypeNs::SelfType((*impl_def).into())),
|
||||||
|
@ -151,7 +151,7 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
|
||||||
self.imp.expand_attr_macro(item)
|
self.imp.expand_attr_macro(item)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolve_derive_macro(&self, derive: &ast::Attr) -> Option<Vec<Option<MacroDef>>> {
|
pub fn resolve_derive_macro(&self, derive: &ast::Attr) -> Option<Vec<Option<Macro>>> {
|
||||||
self.imp.resolve_derive_macro(derive)
|
self.imp.resolve_derive_macro(derive)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -331,11 +331,11 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
|
||||||
self.imp.resolve_record_pat_field(field)
|
self.imp.resolve_record_pat_field(field)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolve_macro_call(&self, macro_call: &ast::MacroCall) -> Option<MacroDef> {
|
pub fn resolve_macro_call(&self, macro_call: &ast::MacroCall) -> Option<Macro> {
|
||||||
self.imp.resolve_macro_call(macro_call)
|
self.imp.resolve_macro_call(macro_call)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolve_attr_macro_call(&self, item: &ast::Item) -> Option<MacroDef> {
|
pub fn resolve_attr_macro_call(&self, item: &ast::Item) -> Option<Macro> {
|
||||||
self.imp.resolve_attr_macro_call(item)
|
self.imp.resolve_attr_macro_call(item)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -443,13 +443,18 @@ impl<'db> SemanticsImpl<'db> {
|
||||||
Some(node)
|
Some(node)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_derive_macro(&self, attr: &ast::Attr) -> Option<Vec<Option<MacroDef>>> {
|
fn resolve_derive_macro(&self, attr: &ast::Attr) -> Option<Vec<Option<Macro>>> {
|
||||||
let res = self
|
let calls = self.derive_macro_calls(attr)?;
|
||||||
.derive_macro_calls(attr)?
|
self.with_ctx(|ctx| {
|
||||||
|
Some(
|
||||||
|
calls
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|call| Some(MacroDef { id: self.db.lookup_intern_macro_call(call?).def }))
|
.map(|call| {
|
||||||
.collect();
|
macro_call_to_macro_id(ctx, self.db.upcast(), call?).map(|id| Macro { id })
|
||||||
Some(res)
|
})
|
||||||
|
.collect(),
|
||||||
|
)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expand_derive_macro(&self, attr: &ast::Attr) -> Option<Vec<SyntaxNode>> {
|
fn expand_derive_macro(&self, attr: &ast::Attr) -> Option<Vec<SyntaxNode>> {
|
||||||
|
@ -500,7 +505,9 @@ impl<'db> SemanticsImpl<'db> {
|
||||||
let macro_call = InFile::new(file_id, actual_macro_call);
|
let macro_call = InFile::new(file_id, actual_macro_call);
|
||||||
let krate = resolver.krate()?;
|
let krate = resolver.krate()?;
|
||||||
let macro_call_id = macro_call.as_call_id(self.db.upcast(), krate, |path| {
|
let macro_call_id = macro_call.as_call_id(self.db.upcast(), krate, |path| {
|
||||||
resolver.resolve_path_as_macro(self.db.upcast(), &path)
|
resolver
|
||||||
|
.resolve_path_as_macro(self.db.upcast(), &path)
|
||||||
|
.map(|it| macro_id_to_def_id(self.db.upcast(), it))
|
||||||
})?;
|
})?;
|
||||||
hir_expand::db::expand_speculative(
|
hir_expand::db::expand_speculative(
|
||||||
self.db.upcast(),
|
self.db.upcast(),
|
||||||
|
@ -895,16 +902,19 @@ impl<'db> SemanticsImpl<'db> {
|
||||||
self.analyze(field.syntax()).resolve_record_pat_field(self.db, field)
|
self.analyze(field.syntax()).resolve_record_pat_field(self.db, field)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_macro_call(&self, macro_call: &ast::MacroCall) -> Option<MacroDef> {
|
fn resolve_macro_call(&self, macro_call: &ast::MacroCall) -> Option<Macro> {
|
||||||
let sa = self.analyze(macro_call.syntax());
|
let sa = self.analyze(macro_call.syntax());
|
||||||
let macro_call = self.find_file(macro_call.syntax()).with_value(macro_call);
|
let macro_call = self.find_file(macro_call.syntax()).with_value(macro_call);
|
||||||
sa.resolve_macro_call(self.db, macro_call)
|
sa.resolve_macro_call(self.db, macro_call)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_attr_macro_call(&self, item: &ast::Item) -> Option<MacroDef> {
|
fn resolve_attr_macro_call(&self, item: &ast::Item) -> Option<Macro> {
|
||||||
let item_in_file = self.wrap_node_infile(item.clone());
|
let item_in_file = self.wrap_node_infile(item.clone());
|
||||||
let macro_call_id = self.with_ctx(|ctx| ctx.item_to_macro_call(item_in_file))?;
|
let id = self.with_ctx(|ctx| {
|
||||||
Some(MacroDef { id: self.db.lookup_intern_macro_call(macro_call_id).def })
|
let macro_call_id = ctx.item_to_macro_call(item_in_file)?;
|
||||||
|
macro_call_to_macro_id(ctx, self.db.upcast(), macro_call_id)
|
||||||
|
})?;
|
||||||
|
Some(Macro { id })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_path(&self, path: &ast::Path) -> Option<PathResolution> {
|
fn resolve_path(&self, path: &ast::Path) -> Option<PathResolution> {
|
||||||
|
@ -1152,6 +1162,26 @@ impl<'db> SemanticsImpl<'db> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn macro_call_to_macro_id(
|
||||||
|
ctx: &mut SourceToDefCtx,
|
||||||
|
db: &dyn AstDatabase,
|
||||||
|
macro_call_id: MacroCallId,
|
||||||
|
) -> Option<MacroId> {
|
||||||
|
let loc = db.lookup_intern_macro_call(macro_call_id);
|
||||||
|
match loc.def.kind {
|
||||||
|
hir_expand::MacroDefKind::Declarative(it)
|
||||||
|
| hir_expand::MacroDefKind::BuiltIn(_, it)
|
||||||
|
| hir_expand::MacroDefKind::BuiltInAttr(_, it)
|
||||||
|
| hir_expand::MacroDefKind::BuiltInDerive(_, it)
|
||||||
|
| hir_expand::MacroDefKind::BuiltInEager(_, it) => {
|
||||||
|
ctx.macro_to_def(InFile::new(it.file_id, it.to_node(db)))
|
||||||
|
}
|
||||||
|
hir_expand::MacroDefKind::ProcMacro(_, _, it) => {
|
||||||
|
ctx.proc_macro_to_def(InFile::new(it.file_id, it.to_node(db)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub trait ToDef: AstNode + Clone {
|
pub trait ToDef: AstNode + Clone {
|
||||||
type Def;
|
type Def;
|
||||||
|
|
||||||
|
@ -1188,7 +1218,7 @@ to_def_impls![
|
||||||
(crate::LifetimeParam, ast::LifetimeParam, lifetime_param_to_def),
|
(crate::LifetimeParam, ast::LifetimeParam, lifetime_param_to_def),
|
||||||
(crate::ConstParam, ast::ConstParam, const_param_to_def),
|
(crate::ConstParam, ast::ConstParam, const_param_to_def),
|
||||||
(crate::GenericParam, ast::GenericParam, generic_param_to_def),
|
(crate::GenericParam, ast::GenericParam, generic_param_to_def),
|
||||||
(crate::MacroDef, ast::Macro, macro_to_def),
|
(crate::Macro, ast::Macro, macro_to_def),
|
||||||
(crate::Local, ast::IdentPat, bind_pat_to_def),
|
(crate::Local, ast::IdentPat, bind_pat_to_def),
|
||||||
(crate::Local, ast::SelfParam, self_param_to_def),
|
(crate::Local, ast::SelfParam, self_param_to_def),
|
||||||
(crate::Label, ast::Label, label_to_def),
|
(crate::Label, ast::Label, label_to_def),
|
||||||
|
@ -1250,7 +1280,6 @@ impl<'a> SemanticsScope<'a> {
|
||||||
for entry in entries {
|
for entry in entries {
|
||||||
let def = match entry {
|
let def = match entry {
|
||||||
resolver::ScopeDef::ModuleDef(it) => ScopeDef::ModuleDef(it.into()),
|
resolver::ScopeDef::ModuleDef(it) => ScopeDef::ModuleDef(it.into()),
|
||||||
resolver::ScopeDef::MacroDef(it) => ScopeDef::MacroDef(it.into()),
|
|
||||||
resolver::ScopeDef::Unknown => ScopeDef::Unknown,
|
resolver::ScopeDef::Unknown => ScopeDef::Unknown,
|
||||||
resolver::ScopeDef::ImplSelfType(it) => ScopeDef::ImplSelfType(it.into()),
|
resolver::ScopeDef::ImplSelfType(it) => ScopeDef::ImplSelfType(it.into()),
|
||||||
resolver::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()),
|
resolver::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()),
|
||||||
|
|
|
@ -93,10 +93,10 @@ use hir_def::{
|
||||||
expr::{LabelId, PatId},
|
expr::{LabelId, PatId},
|
||||||
keys::{self, Key},
|
keys::{self, Key},
|
||||||
AdtId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, FieldId, FunctionId,
|
AdtId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, FieldId, FunctionId,
|
||||||
GenericDefId, GenericParamId, ImplId, LifetimeParamId, ModuleId, StaticId, StructId, TraitId,
|
GenericDefId, GenericParamId, ImplId, LifetimeParamId, MacroId, ModuleId, StaticId, StructId,
|
||||||
TypeAliasId, TypeParamId, UnionId, VariantId,
|
TraitId, TypeAliasId, TypeParamId, UnionId, VariantId,
|
||||||
};
|
};
|
||||||
use hir_expand::{name::AsName, AstId, HirFileId, MacroCallId, MacroDefId, MacroDefKind};
|
use hir_expand::{name::AsName, HirFileId, MacroCallId};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use stdx::impl_from;
|
use stdx::impl_from;
|
||||||
|
@ -317,20 +317,18 @@ impl SourceToDefCtx<'_, '_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn macro_to_def(&mut self, src: InFile<ast::Macro>) -> Option<MacroDefId> {
|
pub(super) fn macro_to_def(&mut self, src: InFile<ast::Macro>) -> Option<MacroId> {
|
||||||
let makro = self.dyn_map(src.as_ref()).and_then(|it| it[keys::MACRO].get(&src.value));
|
self.dyn_map(src.as_ref()).and_then(|it| match &src.value {
|
||||||
if let Some(&makro) = makro {
|
ast::Macro::MacroRules(value) => {
|
||||||
return Some(makro);
|
it[keys::MACRO_RULES].get(value).copied().map(MacroId::from)
|
||||||
|
}
|
||||||
|
ast::Macro::MacroDef(value) => it[keys::MACRO2].get(value).copied().map(MacroId::from),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not all macros are recorded in the dyn map, only the ones behaving like items, so fall back
|
pub(super) fn proc_macro_to_def(&mut self, src: InFile<ast::Fn>) -> Option<MacroId> {
|
||||||
// for the non-item like definitions.
|
self.dyn_map(src.as_ref())
|
||||||
let file_ast_id = self.db.ast_id_map(src.file_id).ast_id(&src.value);
|
.and_then(|it| it[keys::PROC_MACRO].get(&src.value).copied().map(MacroId::from))
|
||||||
let ast_id = AstId::new(src.file_id, file_ast_id.upcast());
|
|
||||||
let kind = MacroDefKind::Declarative(ast_id);
|
|
||||||
let file_id = src.file_id.original_file(self.db.upcast());
|
|
||||||
let krate = self.file_to_def(file_id).get(0).copied()?.krate();
|
|
||||||
Some(MacroDefId { krate, kind, local_inner: false })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn find_container(&mut self, src: InFile<&SyntaxNode>) -> Option<ChildContainer> {
|
pub(super) fn find_container(&mut self, src: InFile<&SyntaxNode>) -> Option<ChildContainer> {
|
||||||
|
|
|
@ -17,6 +17,7 @@ use hir_def::{
|
||||||
Body, BodySourceMap,
|
Body, BodySourceMap,
|
||||||
},
|
},
|
||||||
expr::{ExprId, Pat, PatId},
|
expr::{ExprId, Pat, PatId},
|
||||||
|
macro_id_to_def_id,
|
||||||
path::{ModPath, Path, PathKind},
|
path::{ModPath, Path, PathKind},
|
||||||
resolver::{resolver_for_scope, Resolver, TypeNs, ValueNs},
|
resolver::{resolver_for_scope, Resolver, TypeNs, ValueNs},
|
||||||
AsMacroCall, DefWithBodyId, FieldId, FunctionId, LocalFieldId, ModuleDefId, VariantId,
|
AsMacroCall, DefWithBodyId, FieldId, FunctionId, LocalFieldId, ModuleDefId, VariantId,
|
||||||
|
@ -33,8 +34,7 @@ use syntax::{
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
db::HirDatabase, semantics::PathResolution, Adt, BuiltinAttr, BuiltinType, Const, Field,
|
db::HirDatabase, semantics::PathResolution, Adt, BuiltinAttr, BuiltinType, Const, Field,
|
||||||
Function, Local, MacroDef, ModuleDef, Static, Struct, ToolModule, Trait, Type, TypeAlias,
|
Function, Local, Macro, ModuleDef, Static, Struct, ToolModule, Trait, Type, TypeAlias, Variant,
|
||||||
Variant,
|
|
||||||
};
|
};
|
||||||
use base_db::CrateId;
|
use base_db::CrateId;
|
||||||
|
|
||||||
|
@ -248,7 +248,7 @@ impl SourceAnalyzer {
|
||||||
&self,
|
&self,
|
||||||
db: &dyn HirDatabase,
|
db: &dyn HirDatabase,
|
||||||
macro_call: InFile<&ast::MacroCall>,
|
macro_call: InFile<&ast::MacroCall>,
|
||||||
) -> Option<MacroDef> {
|
) -> Option<Macro> {
|
||||||
let ctx = body::LowerCtx::new(db.upcast(), macro_call.file_id);
|
let ctx = body::LowerCtx::new(db.upcast(), macro_call.file_id);
|
||||||
let path = macro_call.value.path().and_then(|ast| Path::from_src(ast, &ctx))?;
|
let path = macro_call.value.path().and_then(|ast| Path::from_src(ast, &ctx))?;
|
||||||
self.resolver.resolve_path_as_macro(db.upcast(), path.mod_path()).map(|it| it.into())
|
self.resolver.resolve_path_as_macro(db.upcast(), path.mod_path()).map(|it| it.into())
|
||||||
|
@ -371,7 +371,7 @@ impl SourceAnalyzer {
|
||||||
return builtin.map(PathResolution::BuiltinAttr);
|
return builtin.map(PathResolution::BuiltinAttr);
|
||||||
}
|
}
|
||||||
return match resolve_hir_path_as_macro(db, &self.resolver, &hir_path) {
|
return match resolve_hir_path_as_macro(db, &self.resolver, &hir_path) {
|
||||||
Some(m) => Some(PathResolution::Macro(m)),
|
Some(m) => Some(PathResolution::Def(ModuleDef::Macro(m))),
|
||||||
// this labels any path that starts with a tool module as the tool itself, this is technically wrong
|
// this labels any path that starts with a tool module as the tool itself, this is technically wrong
|
||||||
// but there is no benefit in differentiating these two cases for the time being
|
// but there is no benefit in differentiating these two cases for the time being
|
||||||
None => path.first_segment().and_then(|it| it.name_ref()).and_then(|name_ref| {
|
None => path.first_segment().and_then(|it| it.name_ref()).and_then(|name_ref| {
|
||||||
|
@ -453,7 +453,9 @@ impl SourceAnalyzer {
|
||||||
) -> Option<HirFileId> {
|
) -> Option<HirFileId> {
|
||||||
let krate = self.resolver.krate()?;
|
let krate = self.resolver.krate()?;
|
||||||
let macro_call_id = macro_call.as_call_id(db.upcast(), krate, |path| {
|
let macro_call_id = macro_call.as_call_id(db.upcast(), krate, |path| {
|
||||||
self.resolver.resolve_path_as_macro(db.upcast(), &path)
|
self.resolver
|
||||||
|
.resolve_path_as_macro(db.upcast(), &path)
|
||||||
|
.map(|it| macro_id_to_def_id(db.upcast(), it))
|
||||||
})?;
|
})?;
|
||||||
Some(macro_call_id.as_file()).filter(|it| it.expansion_level(db.upcast()) < 64)
|
Some(macro_call_id.as_file()).filter(|it| it.expansion_level(db.upcast()) < 64)
|
||||||
}
|
}
|
||||||
|
@ -571,7 +573,7 @@ pub(crate) fn resolve_hir_path_as_macro(
|
||||||
db: &dyn HirDatabase,
|
db: &dyn HirDatabase,
|
||||||
resolver: &Resolver,
|
resolver: &Resolver,
|
||||||
path: &Path,
|
path: &Path,
|
||||||
) -> Option<MacroDef> {
|
) -> Option<Macro> {
|
||||||
resolver.resolve_path_as_macro(db.upcast(), path.mod_path()).map(Into::into)
|
resolver.resolve_path_as_macro(db.upcast(), path.mod_path()).map(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -666,7 +668,7 @@ fn resolve_hir_path_(
|
||||||
let macros = || {
|
let macros = || {
|
||||||
resolver
|
resolver
|
||||||
.resolve_path_as_macro(db.upcast(), path.mod_path())
|
.resolve_path_as_macro(db.upcast(), path.mod_path())
|
||||||
.map(|def| PathResolution::Macro(def.into()))
|
.map(|def| PathResolution::Def(ModuleDef::Macro(def.into())))
|
||||||
};
|
};
|
||||||
|
|
||||||
if prefer_value_ns { values().or_else(types) } else { types().or_else(values) }
|
if prefer_value_ns { values().or_else(types) } else { types().or_else(values) }
|
||||||
|
|
|
@ -1,16 +1,15 @@
|
||||||
//! File symbol extraction.
|
//! File symbol extraction.
|
||||||
|
|
||||||
use base_db::FileRange;
|
use base_db::FileRange;
|
||||||
use either::Either;
|
|
||||||
use hir_def::{
|
use hir_def::{
|
||||||
item_tree::ItemTreeNode, src::HasSource, AdtId, AssocItemId, AssocItemLoc, DefWithBodyId,
|
item_tree::ItemTreeNode, src::HasSource, AdtId, AssocItemId, AssocItemLoc, DefWithBodyId,
|
||||||
ImplId, ItemContainerId, ItemLoc, Lookup, ModuleDefId, ModuleId, TraitId,
|
ImplId, ItemContainerId, Lookup, MacroId, ModuleDefId, ModuleId, TraitId,
|
||||||
};
|
};
|
||||||
use hir_expand::{HirFileId, InFile};
|
use hir_expand::{HirFileId, InFile};
|
||||||
use hir_ty::db::HirDatabase;
|
use hir_ty::db::HirDatabase;
|
||||||
use syntax::{ast::HasName, AstNode, SmolStr, SyntaxNode, SyntaxNodePtr};
|
use syntax::{ast::HasName, AstNode, SmolStr, SyntaxNode, SyntaxNodePtr};
|
||||||
|
|
||||||
use crate::{HasSource as _, MacroDef, Module, Semantics};
|
use crate::{Module, Semantics};
|
||||||
|
|
||||||
/// The actual data that is stored in the index. It should be as compact as
|
/// The actual data that is stored in the index. It should be as compact as
|
||||||
/// possible.
|
/// possible.
|
||||||
|
@ -157,6 +156,11 @@ impl<'a> SymbolCollector<'a> {
|
||||||
ModuleDefId::TypeAliasId(id) => {
|
ModuleDefId::TypeAliasId(id) => {
|
||||||
self.push_decl_assoc(id, FileSymbolKind::TypeAlias);
|
self.push_decl_assoc(id, FileSymbolKind::TypeAlias);
|
||||||
}
|
}
|
||||||
|
ModuleDefId::MacroId(id) => match id {
|
||||||
|
MacroId::Macro2Id(id) => self.push_decl(id, FileSymbolKind::Macro),
|
||||||
|
MacroId::MacroRulesId(id) => self.push_decl(id, FileSymbolKind::Macro),
|
||||||
|
MacroId::ProcMacroId(id) => self.push_decl(id, FileSymbolKind::Macro),
|
||||||
|
},
|
||||||
// Don't index these.
|
// Don't index these.
|
||||||
ModuleDefId::BuiltinType(_) => {}
|
ModuleDefId::BuiltinType(_) => {}
|
||||||
ModuleDefId::EnumVariantId(_) => {}
|
ModuleDefId::EnumVariantId(_) => {}
|
||||||
|
@ -171,8 +175,11 @@ impl<'a> SymbolCollector<'a> {
|
||||||
self.collect_from_body(const_id);
|
self.collect_from_body(const_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
for macro_def_id in scope.macro_declarations() {
|
for (_, id) in scope.legacy_macros() {
|
||||||
self.push_decl_macro(macro_def_id.into());
|
let loc = id.lookup(self.db.upcast());
|
||||||
|
if loc.container == module_id {
|
||||||
|
self.push_decl(id, FileSymbolKind::Macro);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -283,11 +290,11 @@ impl<'a> SymbolCollector<'a> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_decl<L, T>(&mut self, id: L, kind: FileSymbolKind)
|
fn push_decl<L>(&mut self, id: L, kind: FileSymbolKind)
|
||||||
where
|
where
|
||||||
L: Lookup<Data = ItemLoc<T>>,
|
L: Lookup,
|
||||||
T: ItemTreeNode,
|
<L as Lookup>::Data: HasSource,
|
||||||
<T as ItemTreeNode>::Source: HasName,
|
<<L as Lookup>::Data as HasSource>::Value: HasName,
|
||||||
{
|
{
|
||||||
self.push_file_symbol(|s| {
|
self.push_file_symbol(|s| {
|
||||||
let loc = id.lookup(s.db.upcast());
|
let loc = id.lookup(s.db.upcast());
|
||||||
|
@ -328,29 +335,6 @@ impl<'a> SymbolCollector<'a> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_decl_macro(&mut self, macro_def: MacroDef) {
|
|
||||||
self.push_file_symbol(|s| {
|
|
||||||
let name = macro_def.name(s.db)?.as_text()?;
|
|
||||||
let source = macro_def.source(s.db)?;
|
|
||||||
|
|
||||||
let (ptr, name_ptr) = match source.value {
|
|
||||||
Either::Left(m) => {
|
|
||||||
(SyntaxNodePtr::new(m.syntax()), SyntaxNodePtr::new(m.name()?.syntax()))
|
|
||||||
}
|
|
||||||
Either::Right(f) => {
|
|
||||||
(SyntaxNodePtr::new(f.syntax()), SyntaxNodePtr::new(f.name()?.syntax()))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Some(FileSymbol {
|
|
||||||
name,
|
|
||||||
kind: FileSymbolKind::Macro,
|
|
||||||
container_name: s.current_container_name(),
|
|
||||||
loc: DeclarationLocation { hir_file_id: source.file_id, name_ptr, ptr },
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn push_file_symbol(&mut self, f: impl FnOnce(&Self) -> Option<FileSymbol>) {
|
fn push_file_symbol(&mut self, f: impl FnOnce(&Self) -> Option<FileSymbol>) {
|
||||||
if let Some(file_symbol) = f(self) {
|
if let Some(file_symbol) = f(self) {
|
||||||
self.symbols.push(file_symbol);
|
self.symbols.push(file_symbol);
|
||||||
|
|
|
@ -5,7 +5,7 @@ use std::{fmt, hash::Hash, ops, sync::Arc};
|
||||||
use base_db::CrateId;
|
use base_db::CrateId;
|
||||||
use cfg::{CfgExpr, CfgOptions};
|
use cfg::{CfgExpr, CfgOptions};
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use hir_expand::{hygiene::Hygiene, name::AsName, AstId, HirFileId, InFile};
|
use hir_expand::{hygiene::Hygiene, name::AsName, HirFileId, InFile};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use la_arena::ArenaMap;
|
use la_arena::ArenaMap;
|
||||||
use mbe::{syntax_node_to_token_tree, DelimiterKind, Punct};
|
use mbe::{syntax_node_to_token_tree, DelimiterKind, Punct};
|
||||||
|
@ -24,7 +24,7 @@ use crate::{
|
||||||
path::{ModPath, PathKind},
|
path::{ModPath, PathKind},
|
||||||
src::{HasChildSource, HasSource},
|
src::{HasChildSource, HasSource},
|
||||||
AdtId, AttrDefId, EnumId, GenericParamId, HasModule, LocalEnumVariantId, LocalFieldId, Lookup,
|
AdtId, AttrDefId, EnumId, GenericParamId, HasModule, LocalEnumVariantId, LocalFieldId, Lookup,
|
||||||
VariantId,
|
MacroId, VariantId,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Holds documentation
|
/// Holds documentation
|
||||||
|
@ -358,9 +358,11 @@ impl AttrsWithOwner {
|
||||||
AdtId::UnionId(it) => attrs_from_item_tree(it.lookup(db).id, db),
|
AdtId::UnionId(it) => attrs_from_item_tree(it.lookup(db).id, db),
|
||||||
},
|
},
|
||||||
AttrDefId::TraitId(it) => attrs_from_item_tree(it.lookup(db).id, db),
|
AttrDefId::TraitId(it) => attrs_from_item_tree(it.lookup(db).id, db),
|
||||||
AttrDefId::MacroDefId(it) => it
|
AttrDefId::MacroId(it) => match it {
|
||||||
.ast_id()
|
MacroId::Macro2Id(it) => attrs_from_item_tree(it.lookup(db).id, db),
|
||||||
.either(|ast_id| attrs_from_ast(ast_id, db), |ast_id| attrs_from_ast(ast_id, db)),
|
MacroId::MacroRulesId(it) => attrs_from_item_tree(it.lookup(db).id, db),
|
||||||
|
MacroId::ProcMacroId(it) => attrs_from_item_tree(it.lookup(db).id, db),
|
||||||
|
},
|
||||||
AttrDefId::ImplId(it) => attrs_from_item_tree(it.lookup(db).id, db),
|
AttrDefId::ImplId(it) => attrs_from_item_tree(it.lookup(db).id, db),
|
||||||
AttrDefId::ConstId(it) => attrs_from_item_tree(it.lookup(db).id, db),
|
AttrDefId::ConstId(it) => attrs_from_item_tree(it.lookup(db).id, db),
|
||||||
AttrDefId::StaticId(it) => attrs_from_item_tree(it.lookup(db).id, db),
|
AttrDefId::StaticId(it) => attrs_from_item_tree(it.lookup(db).id, db),
|
||||||
|
@ -461,10 +463,11 @@ impl AttrsWithOwner {
|
||||||
AttrDefId::ConstId(id) => id.lookup(db).source(db).map(ast::AnyHasAttrs::new),
|
AttrDefId::ConstId(id) => id.lookup(db).source(db).map(ast::AnyHasAttrs::new),
|
||||||
AttrDefId::TraitId(id) => id.lookup(db).source(db).map(ast::AnyHasAttrs::new),
|
AttrDefId::TraitId(id) => id.lookup(db).source(db).map(ast::AnyHasAttrs::new),
|
||||||
AttrDefId::TypeAliasId(id) => id.lookup(db).source(db).map(ast::AnyHasAttrs::new),
|
AttrDefId::TypeAliasId(id) => id.lookup(db).source(db).map(ast::AnyHasAttrs::new),
|
||||||
AttrDefId::MacroDefId(id) => id.ast_id().either(
|
AttrDefId::MacroId(id) => match id {
|
||||||
|it| it.with_value(ast::AnyHasAttrs::new(it.to_node(db.upcast()))),
|
MacroId::Macro2Id(id) => id.lookup(db).source(db).map(ast::AnyHasAttrs::new),
|
||||||
|it| it.with_value(ast::AnyHasAttrs::new(it.to_node(db.upcast()))),
|
MacroId::MacroRulesId(id) => id.lookup(db).source(db).map(ast::AnyHasAttrs::new),
|
||||||
),
|
MacroId::ProcMacroId(id) => id.lookup(db).source(db).map(ast::AnyHasAttrs::new),
|
||||||
|
},
|
||||||
AttrDefId::ImplId(id) => id.lookup(db).source(db).map(ast::AnyHasAttrs::new),
|
AttrDefId::ImplId(id) => id.lookup(db).source(db).map(ast::AnyHasAttrs::new),
|
||||||
AttrDefId::GenericParamId(id) => match id {
|
AttrDefId::GenericParamId(id) => match id {
|
||||||
GenericParamId::ConstParamId(id) => {
|
GenericParamId::ConstParamId(id) => {
|
||||||
|
@ -845,14 +848,6 @@ impl<'attr> AttrQuery<'attr> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn attrs_from_ast<N>(src: AstId<N>, db: &dyn DefDatabase) -> RawAttrs
|
|
||||||
where
|
|
||||||
N: ast::HasAttrs,
|
|
||||||
{
|
|
||||||
let src = InFile::new(src.file_id, src.to_node(db.upcast()));
|
|
||||||
RawAttrs::from_attrs_owner(db, src.as_ref().map(|it| it as &dyn ast::HasAttrs))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn attrs_from_item_tree<N: ItemTreeNode>(id: ItemTreeId<N>, db: &dyn DefDatabase) -> RawAttrs {
|
fn attrs_from_item_tree<N: ItemTreeNode>(id: ItemTreeId<N>, db: &dyn DefDatabase) -> RawAttrs {
|
||||||
let tree = id.item_tree(db);
|
let tree = id.item_tree(db);
|
||||||
let mod_item = N::id_to_mod_item(id.value);
|
let mod_item = N::id_to_mod_item(id.value);
|
||||||
|
|
|
@ -13,7 +13,7 @@ use drop_bomb::DropBomb;
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use hir_expand::{
|
use hir_expand::{
|
||||||
ast_id_map::AstIdMap, hygiene::Hygiene, AstId, ExpandError, ExpandResult, HirFileId, InFile,
|
ast_id_map::AstIdMap, hygiene::Hygiene, AstId, ExpandError, ExpandResult, HirFileId, InFile,
|
||||||
MacroCallId, MacroDefId,
|
MacroCallId,
|
||||||
};
|
};
|
||||||
use la_arena::{Arena, ArenaMap};
|
use la_arena::{Arena, ArenaMap};
|
||||||
use limit::Limit;
|
use limit::Limit;
|
||||||
|
@ -26,10 +26,11 @@ use crate::{
|
||||||
db::DefDatabase,
|
db::DefDatabase,
|
||||||
expr::{Expr, ExprId, Label, LabelId, Pat, PatId},
|
expr::{Expr, ExprId, Label, LabelId, Pat, PatId},
|
||||||
item_scope::BuiltinShadowMode,
|
item_scope::BuiltinShadowMode,
|
||||||
|
macro_id_to_def_id,
|
||||||
nameres::DefMap,
|
nameres::DefMap,
|
||||||
path::{ModPath, Path},
|
path::{ModPath, Path},
|
||||||
src::HasSource,
|
src::HasSource,
|
||||||
AsMacroCall, BlockId, DefWithBodyId, HasModule, LocalModuleId, Lookup, ModuleId,
|
AsMacroCall, BlockId, DefWithBodyId, HasModule, LocalModuleId, Lookup, MacroId, ModuleId,
|
||||||
UnresolvedMacro,
|
UnresolvedMacro,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -105,7 +106,7 @@ impl Expander {
|
||||||
let macro_call = InFile::new(self.current_file_id, ¯o_call);
|
let macro_call = InFile::new(self.current_file_id, ¯o_call);
|
||||||
|
|
||||||
let resolver =
|
let resolver =
|
||||||
|path: ModPath| -> Option<MacroDefId> { self.resolve_path_as_macro(db, &path) };
|
|path| self.resolve_path_as_macro(db, &path).map(|it| macro_id_to_def_id(db, it));
|
||||||
|
|
||||||
let mut err = None;
|
let mut err = None;
|
||||||
let call_id =
|
let call_id =
|
||||||
|
@ -208,7 +209,7 @@ impl Expander {
|
||||||
Path::from_src(path, &ctx)
|
Path::from_src(path, &ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_path_as_macro(&self, db: &dyn DefDatabase, path: &ModPath) -> Option<MacroDefId> {
|
fn resolve_path_as_macro(&self, db: &dyn DefDatabase, path: &ModPath) -> Option<MacroId> {
|
||||||
self.def_map.resolve_path(db, self.module, path, BuiltinShadowMode::Other).0.take_macros()
|
self.def_map.resolve_path(db, self.module, path, BuiltinShadowMode::Other).0.take_macros()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,8 +14,8 @@ use crate::{
|
||||||
item_scope::ItemScope,
|
item_scope::ItemScope,
|
||||||
keys,
|
keys,
|
||||||
src::{HasChildSource, HasSource},
|
src::{HasChildSource, HasSource},
|
||||||
AdtId, AssocItemId, DefWithBodyId, EnumId, EnumVariantId, FieldId, ImplId, Lookup, ModuleDefId,
|
AdtId, AssocItemId, DefWithBodyId, EnumId, EnumVariantId, FieldId, ImplId, Lookup, MacroId,
|
||||||
ModuleId, TraitId, VariantId,
|
ModuleDefId, ModuleId, TraitId, VariantId,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait ChildBySource {
|
pub trait ChildBySource {
|
||||||
|
@ -97,22 +97,17 @@ impl ChildBySource for ItemScope {
|
||||||
res[keys::CONST].insert(loc.source(db).value, konst);
|
res[keys::CONST].insert(loc.source(db).value, konst);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
self.macros().for_each(|(_, makro)| {
|
|
||||||
let ast_id = makro.ast_id();
|
|
||||||
if ast_id.either(|it| it.file_id, |it| it.file_id) == file_id {
|
|
||||||
let src = match ast_id {
|
|
||||||
Either::Left(ast_id) => ast_id.to_node(db.upcast()),
|
|
||||||
// FIXME: Do we need to add proc-macros into a PROCMACRO dynmap here?
|
|
||||||
Either::Right(_fn) => return,
|
|
||||||
};
|
|
||||||
res[keys::MACRO].insert(src, makro);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
self.attr_macro_invocs().filter(|(id, _)| id.file_id == file_id).for_each(
|
self.attr_macro_invocs().filter(|(id, _)| id.file_id == file_id).for_each(
|
||||||
|(ast_id, call_id)| {
|
|(ast_id, call_id)| {
|
||||||
res[keys::ATTR_MACRO_CALL].insert(ast_id.to_node(db.upcast()), call_id);
|
res[keys::ATTR_MACRO_CALL].insert(ast_id.to_node(db.upcast()), call_id);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
self.legacy_macros().for_each(|(_, id)| {
|
||||||
|
let loc = id.lookup(db);
|
||||||
|
if loc.id.file_id() == file_id {
|
||||||
|
res[keys::MACRO_RULES].insert(loc.source(db).value, id);
|
||||||
|
}
|
||||||
|
});
|
||||||
self.derive_macro_invocs().filter(|(id, _)| id.file_id == file_id).for_each(
|
self.derive_macro_invocs().filter(|(id, _)| id.file_id == file_id).for_each(
|
||||||
|(ast_id, calls)| {
|
|(ast_id, calls)| {
|
||||||
let adt = ast_id.to_node(db.upcast());
|
let adt = ast_id.to_node(db.upcast());
|
||||||
|
@ -151,7 +146,14 @@ impl ChildBySource for ItemScope {
|
||||||
AdtId::UnionId(id) => insert!(map[keys::UNION].insert(id)),
|
AdtId::UnionId(id) => insert!(map[keys::UNION].insert(id)),
|
||||||
AdtId::EnumId(id) => insert!(map[keys::ENUM].insert(id)),
|
AdtId::EnumId(id) => insert!(map[keys::ENUM].insert(id)),
|
||||||
},
|
},
|
||||||
_ => (),
|
ModuleDefId::MacroId(id) => match id {
|
||||||
|
MacroId::Macro2Id(id) => insert!(map[keys::MACRO2].insert(id)),
|
||||||
|
MacroId::MacroRulesId(id) => insert!(map[keys::MACRO_RULES].insert(id)),
|
||||||
|
MacroId::ProcMacroId(id) => insert!(map[keys::PROC_MACRO].insert(id)),
|
||||||
|
},
|
||||||
|
ModuleDefId::ModuleId(_)
|
||||||
|
| ModuleDefId::EnumVariantId(_)
|
||||||
|
| ModuleDefId::BuiltinType(_) => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn add_impl(db: &dyn DefDatabase, map: &mut DynMap, file_id: HirFileId, imp: ImplId) {
|
fn add_impl(db: &dyn DefDatabase, map: &mut DynMap, file_id: HirFileId, imp: ImplId) {
|
||||||
|
|
|
@ -15,7 +15,8 @@ use crate::{
|
||||||
type_ref::{TraitRef, TypeBound, TypeRef},
|
type_ref::{TraitRef, TypeBound, TypeRef},
|
||||||
visibility::RawVisibility,
|
visibility::RawVisibility,
|
||||||
AssocItemId, AstIdWithPath, ConstId, ConstLoc, FunctionId, FunctionLoc, HasModule, ImplId,
|
AssocItemId, AstIdWithPath, ConstId, ConstLoc, FunctionId, FunctionLoc, HasModule, ImplId,
|
||||||
Intern, ItemContainerId, Lookup, ModuleId, StaticId, TraitId, TypeAliasId, TypeAliasLoc,
|
Intern, ItemContainerId, Lookup, Macro2Id, MacroRulesId, ModuleId, ProcMacroId, StaticId,
|
||||||
|
TraitId, TypeAliasId, TypeAliasLoc,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
@ -293,6 +294,70 @@ impl ImplData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct Macro2Data {
|
||||||
|
pub name: Name,
|
||||||
|
pub visibility: RawVisibility,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Macro2Data {
|
||||||
|
pub(crate) fn macro2_data_query(db: &dyn DefDatabase, makro: Macro2Id) -> Arc<Macro2Data> {
|
||||||
|
let loc = makro.lookup(db);
|
||||||
|
let item_tree = loc.id.item_tree(db);
|
||||||
|
let makro = &item_tree[loc.id.value];
|
||||||
|
|
||||||
|
Arc::new(Macro2Data {
|
||||||
|
name: makro.name.clone(),
|
||||||
|
visibility: item_tree[makro.visibility].clone(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct MacroRulesData {
|
||||||
|
pub name: Name,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MacroRulesData {
|
||||||
|
pub(crate) fn macro_rules_data_query(
|
||||||
|
db: &dyn DefDatabase,
|
||||||
|
makro: MacroRulesId,
|
||||||
|
) -> Arc<MacroRulesData> {
|
||||||
|
let loc = makro.lookup(db);
|
||||||
|
let item_tree = loc.id.item_tree(db);
|
||||||
|
let makro = &item_tree[loc.id.value];
|
||||||
|
|
||||||
|
Arc::new(MacroRulesData { name: makro.name.clone() })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct ProcMacroData {
|
||||||
|
pub name: Name,
|
||||||
|
// FIXME: Record deriver helper here?
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ProcMacroData {
|
||||||
|
pub(crate) fn proc_macro_data_query(
|
||||||
|
db: &dyn DefDatabase,
|
||||||
|
makro: ProcMacroId,
|
||||||
|
) -> Arc<ProcMacroData> {
|
||||||
|
let loc = makro.lookup(db);
|
||||||
|
let item_tree = loc.id.item_tree(db);
|
||||||
|
let makro = &item_tree[loc.id.value];
|
||||||
|
|
||||||
|
let name = if let Some(def) = item_tree
|
||||||
|
.attrs(db, loc.container.krate(), ModItem::from(loc.id.value).into())
|
||||||
|
.parse_proc_macro_decl(&makro.name)
|
||||||
|
{
|
||||||
|
def.name
|
||||||
|
} else {
|
||||||
|
// eeeh...
|
||||||
|
stdx::never!("proc macro declaration is not a proc macro");
|
||||||
|
makro.name.clone()
|
||||||
|
};
|
||||||
|
Arc::new(ProcMacroData { name })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct ConstData {
|
pub struct ConstData {
|
||||||
/// `None` for `const _: () = ();`
|
/// `None` for `const _: () = ();`
|
||||||
|
|
|
@ -11,7 +11,10 @@ use crate::{
|
||||||
adt::{EnumData, StructData},
|
adt::{EnumData, StructData},
|
||||||
attr::{Attrs, AttrsWithOwner},
|
attr::{Attrs, AttrsWithOwner},
|
||||||
body::{scope::ExprScopes, Body, BodySourceMap},
|
body::{scope::ExprScopes, Body, BodySourceMap},
|
||||||
data::{ConstData, FunctionData, ImplData, StaticData, TraitData, TypeAliasData},
|
data::{
|
||||||
|
ConstData, FunctionData, ImplData, Macro2Data, MacroRulesData, ProcMacroData, StaticData,
|
||||||
|
TraitData, TypeAliasData,
|
||||||
|
},
|
||||||
generics::GenericParams,
|
generics::GenericParams,
|
||||||
import_map::ImportMap,
|
import_map::ImportMap,
|
||||||
intern::Interned,
|
intern::Interned,
|
||||||
|
@ -21,8 +24,9 @@ use crate::{
|
||||||
visibility::{self, Visibility},
|
visibility::{self, Visibility},
|
||||||
AttrDefId, BlockId, BlockLoc, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, ExternBlockId,
|
AttrDefId, BlockId, BlockLoc, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, ExternBlockId,
|
||||||
ExternBlockLoc, FunctionId, FunctionLoc, GenericDefId, ImplId, ImplLoc, LocalEnumVariantId,
|
ExternBlockLoc, FunctionId, FunctionLoc, GenericDefId, ImplId, ImplLoc, LocalEnumVariantId,
|
||||||
LocalFieldId, StaticId, StaticLoc, StructId, StructLoc, TraitId, TraitLoc, TypeAliasId,
|
LocalFieldId, Macro2Id, Macro2Loc, MacroRulesId, MacroRulesLoc, ProcMacroId, ProcMacroLoc,
|
||||||
TypeAliasLoc, UnionId, UnionLoc, VariantId,
|
StaticId, StaticLoc, StructId, StructLoc, TraitId, TraitLoc, TypeAliasId, TypeAliasLoc,
|
||||||
|
UnionId, UnionLoc, VariantId,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[salsa::query_group(InternDatabaseStorage)]
|
#[salsa::query_group(InternDatabaseStorage)]
|
||||||
|
@ -49,6 +53,12 @@ pub trait InternDatabase: SourceDatabase {
|
||||||
fn intern_extern_block(&self, loc: ExternBlockLoc) -> ExternBlockId;
|
fn intern_extern_block(&self, loc: ExternBlockLoc) -> ExternBlockId;
|
||||||
#[salsa::interned]
|
#[salsa::interned]
|
||||||
fn intern_block(&self, loc: BlockLoc) -> BlockId;
|
fn intern_block(&self, loc: BlockLoc) -> BlockId;
|
||||||
|
#[salsa::interned]
|
||||||
|
fn intern_macro2(&self, loc: Macro2Loc) -> Macro2Id;
|
||||||
|
#[salsa::interned]
|
||||||
|
fn intern_proc_macro(&self, loc: ProcMacroLoc) -> ProcMacroId;
|
||||||
|
#[salsa::interned]
|
||||||
|
fn intern_macro_rules(&self, loc: MacroRulesLoc) -> MacroRulesId;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[salsa::query_group(DefDatabaseStorage)]
|
#[salsa::query_group(DefDatabaseStorage)]
|
||||||
|
@ -86,6 +96,7 @@ pub trait DefDatabase: InternDatabase + AstDatabase + Upcast<dyn AstDatabase> {
|
||||||
|
|
||||||
#[salsa::invoke(StructData::struct_data_query)]
|
#[salsa::invoke(StructData::struct_data_query)]
|
||||||
fn struct_data(&self, id: StructId) -> Arc<StructData>;
|
fn struct_data(&self, id: StructId) -> Arc<StructData>;
|
||||||
|
|
||||||
#[salsa::invoke(StructData::union_data_query)]
|
#[salsa::invoke(StructData::union_data_query)]
|
||||||
fn union_data(&self, id: UnionId) -> Arc<StructData>;
|
fn union_data(&self, id: UnionId) -> Arc<StructData>;
|
||||||
|
|
||||||
|
@ -110,6 +121,15 @@ pub trait DefDatabase: InternDatabase + AstDatabase + Upcast<dyn AstDatabase> {
|
||||||
#[salsa::invoke(StaticData::static_data_query)]
|
#[salsa::invoke(StaticData::static_data_query)]
|
||||||
fn static_data(&self, konst: StaticId) -> Arc<StaticData>;
|
fn static_data(&self, konst: StaticId) -> Arc<StaticData>;
|
||||||
|
|
||||||
|
#[salsa::invoke(Macro2Data::macro2_data_query)]
|
||||||
|
fn macro2_data(&self, makro: Macro2Id) -> Arc<Macro2Data>;
|
||||||
|
|
||||||
|
#[salsa::invoke(MacroRulesData::macro_rules_data_query)]
|
||||||
|
fn macro_rules_data(&self, makro: MacroRulesId) -> Arc<MacroRulesData>;
|
||||||
|
|
||||||
|
#[salsa::invoke(ProcMacroData::proc_macro_data_query)]
|
||||||
|
fn proc_macro_data(&self, makro: ProcMacroId) -> Arc<ProcMacroData>;
|
||||||
|
|
||||||
#[salsa::invoke(Body::body_with_source_map_query)]
|
#[salsa::invoke(Body::body_with_source_map_query)]
|
||||||
fn body_with_source_map(&self, def: DefWithBodyId) -> (Arc<Body>, Arc<BodySourceMap>);
|
fn body_with_source_map(&self, def: DefWithBodyId) -> (Arc<Body>, Arc<BodySourceMap>);
|
||||||
|
|
||||||
|
|
|
@ -98,6 +98,7 @@ impl PrefixKind {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Attempts to find a path to refer to the given `item` visible from the `from` ModuleId
|
||||||
fn find_path_inner(
|
fn find_path_inner(
|
||||||
db: &dyn DefDatabase,
|
db: &dyn DefDatabase,
|
||||||
item: ItemInNs,
|
item: ItemInNs,
|
||||||
|
|
|
@ -271,6 +271,7 @@ pub enum ImportKind {
|
||||||
TypeAlias,
|
TypeAlias,
|
||||||
BuiltinType,
|
BuiltinType,
|
||||||
AssociatedItem,
|
AssociatedItem,
|
||||||
|
Macro,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A way to match import map contents against the search query.
|
/// A way to match import map contents against the search query.
|
||||||
|
@ -464,6 +465,7 @@ fn item_import_kind(item: ItemInNs) -> Option<ImportKind> {
|
||||||
ModuleDefId::TraitId(_) => ImportKind::Trait,
|
ModuleDefId::TraitId(_) => ImportKind::Trait,
|
||||||
ModuleDefId::TypeAliasId(_) => ImportKind::TypeAlias,
|
ModuleDefId::TypeAliasId(_) => ImportKind::TypeAlias,
|
||||||
ModuleDefId::BuiltinType(_) => ImportKind::BuiltinType,
|
ModuleDefId::BuiltinType(_) => ImportKind::BuiltinType,
|
||||||
|
ModuleDefId::MacroId(_) => ImportKind::Macro,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1067,9 +1069,9 @@ mod tests {
|
||||||
Query::new("".to_string()).limit(2),
|
Query::new("".to_string()).limit(2),
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
dep::fmt (t)
|
dep::fmt (t)
|
||||||
dep::Fmt (m)
|
|
||||||
dep::Fmt (t)
|
dep::Fmt (t)
|
||||||
dep::Fmt (v)
|
dep::Fmt (v)
|
||||||
|
dep::Fmt (m)
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
use std::collections::hash_map::Entry;
|
use std::collections::hash_map::Entry;
|
||||||
|
|
||||||
use base_db::CrateId;
|
use base_db::CrateId;
|
||||||
use hir_expand::{name::Name, AstId, MacroCallId, MacroDefKind};
|
use hir_expand::{name::Name, AstId, MacroCallId};
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use profile::Count;
|
use profile::Count;
|
||||||
use rustc_hash::{FxHashMap, FxHashSet};
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
|
@ -14,7 +14,8 @@ use syntax::ast;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
attr::AttrId, db::DefDatabase, per_ns::PerNs, visibility::Visibility, AdtId, BuiltinType,
|
attr::AttrId, db::DefDatabase, per_ns::PerNs, visibility::Visibility, AdtId, BuiltinType,
|
||||||
ConstId, ImplId, LocalModuleId, MacroDefId, ModuleDefId, ModuleId, TraitId,
|
ConstId, HasModule, ImplId, LocalModuleId, MacroId, MacroRulesId, ModuleDefId, ModuleId,
|
||||||
|
TraitId,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
|
@ -38,13 +39,12 @@ pub struct ItemScope {
|
||||||
/// imports.
|
/// imports.
|
||||||
types: FxHashMap<Name, (ModuleDefId, Visibility)>,
|
types: FxHashMap<Name, (ModuleDefId, Visibility)>,
|
||||||
values: FxHashMap<Name, (ModuleDefId, Visibility)>,
|
values: FxHashMap<Name, (ModuleDefId, Visibility)>,
|
||||||
macros: FxHashMap<Name, (MacroDefId, Visibility)>,
|
macros: FxHashMap<Name, (MacroId, Visibility)>,
|
||||||
unresolved: FxHashSet<Name>,
|
unresolved: FxHashSet<Name>,
|
||||||
|
|
||||||
/// The defs declared in this scope. Each def has a single scope where it is
|
/// The defs declared in this scope. Each def has a single scope where it is
|
||||||
/// declared.
|
/// declared.
|
||||||
declarations: Vec<ModuleDefId>,
|
declarations: Vec<ModuleDefId>,
|
||||||
macro_declarations: Vec<MacroDefId>,
|
|
||||||
|
|
||||||
impls: Vec<ImplId>,
|
impls: Vec<ImplId>,
|
||||||
unnamed_consts: Vec<ConstId>,
|
unnamed_consts: Vec<ConstId>,
|
||||||
|
@ -62,7 +62,7 @@ pub struct ItemScope {
|
||||||
/// Module scoped macros will be inserted into `items` instead of here.
|
/// Module scoped macros will be inserted into `items` instead of here.
|
||||||
// FIXME: Macro shadowing in one module is not properly handled. Non-item place macros will
|
// FIXME: Macro shadowing in one module is not properly handled. Non-item place macros will
|
||||||
// be all resolved to the last one defined if shadowing happens.
|
// be all resolved to the last one defined if shadowing happens.
|
||||||
legacy_macros: FxHashMap<Name, MacroDefId>,
|
legacy_macros: FxHashMap<Name, MacroRulesId>,
|
||||||
attr_macros: FxHashMap<AstId<ast::Item>, MacroCallId>,
|
attr_macros: FxHashMap<AstId<ast::Item>, MacroCallId>,
|
||||||
/// The derive macro invocations in this scope, keyed by the owner item over the actual derive attributes
|
/// The derive macro invocations in this scope, keyed by the owner item over the actual derive attributes
|
||||||
/// paired with the derive macro invocations for the specific attribute.
|
/// paired with the derive macro invocations for the specific attribute.
|
||||||
|
@ -108,10 +108,6 @@ impl ItemScope {
|
||||||
self.declarations.iter().copied()
|
self.declarations.iter().copied()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn macro_declarations(&self) -> impl Iterator<Item = MacroDefId> + '_ {
|
|
||||||
self.macro_declarations.iter().copied()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn impls(&self) -> impl Iterator<Item = ImplId> + ExactSizeIterator + '_ {
|
pub fn impls(&self) -> impl Iterator<Item = ImplId> + ExactSizeIterator + '_ {
|
||||||
self.impls.iter().copied()
|
self.impls.iter().copied()
|
||||||
}
|
}
|
||||||
|
@ -127,12 +123,12 @@ impl ItemScope {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Iterate over all module scoped macros
|
/// Iterate over all module scoped macros
|
||||||
pub(crate) fn macros<'a>(&'a self) -> impl Iterator<Item = (&'a Name, MacroDefId)> + 'a {
|
pub(crate) fn macros<'a>(&'a self) -> impl Iterator<Item = (&'a Name, MacroId)> + 'a {
|
||||||
self.entries().filter_map(|(name, def)| def.take_macros().map(|macro_| (name, macro_)))
|
self.entries().filter_map(|(name, def)| def.take_macros().map(|macro_| (name, macro_)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Iterate over all legacy textual scoped macros visible at the end of the module
|
/// Iterate over all legacy textual scoped macros visible at the end of the module
|
||||||
pub(crate) fn legacy_macros<'a>(&'a self) -> impl Iterator<Item = (&'a Name, MacroDefId)> + 'a {
|
pub fn legacy_macros<'a>(&'a self) -> impl Iterator<Item = (&'a Name, MacroRulesId)> + 'a {
|
||||||
self.legacy_macros.iter().map(|(name, def)| (name, *def))
|
self.legacy_macros.iter().map(|(name, def)| (name, *def))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,8 +159,8 @@ impl ItemScope {
|
||||||
pub(crate) fn traits<'a>(&'a self) -> impl Iterator<Item = TraitId> + 'a {
|
pub(crate) fn traits<'a>(&'a self) -> impl Iterator<Item = TraitId> + 'a {
|
||||||
self.types
|
self.types
|
||||||
.values()
|
.values()
|
||||||
.filter_map(|(def, _)| match def {
|
.filter_map(|&(def, _)| match def {
|
||||||
ModuleDefId::TraitId(t) => Some(*t),
|
ModuleDefId::TraitId(t) => Some(t),
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
.chain(self.unnamed_trait_imports.keys().copied())
|
.chain(self.unnamed_trait_imports.keys().copied())
|
||||||
|
@ -174,11 +170,7 @@ impl ItemScope {
|
||||||
self.declarations.push(def)
|
self.declarations.push(def)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn declare_macro(&mut self, def: MacroDefId) {
|
pub(crate) fn get_legacy_macro(&self, name: &Name) -> Option<MacroRulesId> {
|
||||||
self.macro_declarations.push(def);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn get_legacy_macro(&self, name: &Name) -> Option<MacroDefId> {
|
|
||||||
self.legacy_macros.get(name).copied()
|
self.legacy_macros.get(name).copied()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,7 +182,7 @@ impl ItemScope {
|
||||||
self.unnamed_consts.push(konst);
|
self.unnamed_consts.push(konst);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn define_legacy_macro(&mut self, name: Name, mac: MacroDefId) {
|
pub(crate) fn define_legacy_macro(&mut self, name: Name, mac: MacroRulesId) {
|
||||||
self.legacy_macros.insert(name, mac);
|
self.legacy_macros.insert(name, mac);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,7 +312,7 @@ impl ItemScope {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn collect_legacy_macros(&self) -> FxHashMap<Name, MacroDefId> {
|
pub(crate) fn collect_legacy_macros(&self) -> FxHashMap<Name, MacroRulesId> {
|
||||||
self.legacy_macros.clone()
|
self.legacy_macros.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,7 +326,7 @@ impl ItemScope {
|
||||||
.for_each(|vis| *vis = Visibility::Module(this_module));
|
.for_each(|vis| *vis = Visibility::Module(this_module));
|
||||||
|
|
||||||
for (mac, vis) in self.macros.values_mut() {
|
for (mac, vis) in self.macros.values_mut() {
|
||||||
if let MacroDefKind::ProcMacro(..) = mac.kind {
|
if let MacroId::ProcMacroId(_) = mac {
|
||||||
// FIXME: Technically this is insufficient since reexports of proc macros are also
|
// FIXME: Technically this is insufficient since reexports of proc macros are also
|
||||||
// forbidden. Practically nobody does that.
|
// forbidden. Practically nobody does that.
|
||||||
continue;
|
continue;
|
||||||
|
@ -377,7 +369,6 @@ impl ItemScope {
|
||||||
macros,
|
macros,
|
||||||
unresolved,
|
unresolved,
|
||||||
declarations,
|
declarations,
|
||||||
macro_declarations,
|
|
||||||
impls,
|
impls,
|
||||||
unnamed_consts,
|
unnamed_consts,
|
||||||
unnamed_trait_imports,
|
unnamed_trait_imports,
|
||||||
|
@ -390,7 +381,6 @@ impl ItemScope {
|
||||||
macros.shrink_to_fit();
|
macros.shrink_to_fit();
|
||||||
unresolved.shrink_to_fit();
|
unresolved.shrink_to_fit();
|
||||||
declarations.shrink_to_fit();
|
declarations.shrink_to_fit();
|
||||||
macro_declarations.shrink_to_fit();
|
|
||||||
impls.shrink_to_fit();
|
impls.shrink_to_fit();
|
||||||
unnamed_consts.shrink_to_fit();
|
unnamed_consts.shrink_to_fit();
|
||||||
unnamed_trait_imports.shrink_to_fit();
|
unnamed_trait_imports.shrink_to_fit();
|
||||||
|
@ -421,6 +411,7 @@ impl PerNs {
|
||||||
ModuleDefId::TraitId(_) => PerNs::types(def, v),
|
ModuleDefId::TraitId(_) => PerNs::types(def, v),
|
||||||
ModuleDefId::TypeAliasId(_) => PerNs::types(def, v),
|
ModuleDefId::TypeAliasId(_) => PerNs::types(def, v),
|
||||||
ModuleDefId::BuiltinType(_) => PerNs::types(def, v),
|
ModuleDefId::BuiltinType(_) => PerNs::types(def, v),
|
||||||
|
ModuleDefId::MacroId(mac) => PerNs::macros(mac, v),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -429,7 +420,7 @@ impl PerNs {
|
||||||
pub enum ItemInNs {
|
pub enum ItemInNs {
|
||||||
Types(ModuleDefId),
|
Types(ModuleDefId),
|
||||||
Values(ModuleDefId),
|
Values(ModuleDefId),
|
||||||
Macros(MacroDefId),
|
Macros(MacroId),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ItemInNs {
|
impl ItemInNs {
|
||||||
|
@ -444,7 +435,7 @@ impl ItemInNs {
|
||||||
pub fn krate(&self, db: &dyn DefDatabase) -> Option<CrateId> {
|
pub fn krate(&self, db: &dyn DefDatabase) -> Option<CrateId> {
|
||||||
match self {
|
match self {
|
||||||
ItemInNs::Types(did) | ItemInNs::Values(did) => did.module(db).map(|m| m.krate),
|
ItemInNs::Types(did) | ItemInNs::Values(did) => did.module(db).map(|m| m.krate),
|
||||||
ItemInNs::Macros(id) => Some(id.krate),
|
ItemInNs::Macros(id) => Some(id.module(db).krate),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,15 +2,16 @@
|
||||||
|
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
use hir_expand::{MacroCallId, MacroDefId};
|
use hir_expand::MacroCallId;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use syntax::{ast, AstNode, AstPtr};
|
use syntax::{ast, AstNode, AstPtr};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
attr::AttrId,
|
attr::AttrId,
|
||||||
dyn_map::{DynMap, Policy},
|
dyn_map::{DynMap, Policy},
|
||||||
ConstId, EnumId, EnumVariantId, FieldId, FunctionId, ImplId, LifetimeParamId, StaticId,
|
ConstId, EnumId, EnumVariantId, FieldId, FunctionId, ImplId, LifetimeParamId, Macro2Id,
|
||||||
StructId, TraitId, TypeAliasId, TypeOrConstParamId, UnionId,
|
MacroRulesId, ProcMacroId, StaticId, StructId, TraitId, TypeAliasId, TypeOrConstParamId,
|
||||||
|
UnionId,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub type Key<K, V> = crate::dyn_map::Key<K, V, AstPtrPolicy<K, V>>;
|
pub type Key<K, V> = crate::dyn_map::Key<K, V, AstPtrPolicy<K, V>>;
|
||||||
|
@ -32,7 +33,9 @@ pub const TYPE_PARAM: Key<ast::TypeParam, TypeOrConstParamId> = Key::new();
|
||||||
pub const CONST_PARAM: Key<ast::ConstParam, TypeOrConstParamId> = Key::new();
|
pub const CONST_PARAM: Key<ast::ConstParam, TypeOrConstParamId> = Key::new();
|
||||||
pub const LIFETIME_PARAM: Key<ast::LifetimeParam, LifetimeParamId> = Key::new();
|
pub const LIFETIME_PARAM: Key<ast::LifetimeParam, LifetimeParamId> = Key::new();
|
||||||
|
|
||||||
pub const MACRO: Key<ast::Macro, MacroDefId> = Key::new();
|
pub const MACRO_RULES: Key<ast::MacroRules, MacroRulesId> = Key::new();
|
||||||
|
pub const MACRO2: Key<ast::MacroDef, Macro2Id> = Key::new();
|
||||||
|
pub const PROC_MACRO: Key<ast::Fn, ProcMacroId> = Key::new();
|
||||||
pub const ATTR_MACRO_CALL: Key<ast::Item, MacroCallId> = Key::new();
|
pub const ATTR_MACRO_CALL: Key<ast::Item, MacroCallId> = Key::new();
|
||||||
pub const DERIVE_MACRO_CALL: Key<ast::Attr, (AttrId, MacroCallId, Box<[Option<MacroCallId>]>)> =
|
pub const DERIVE_MACRO_CALL: Key<ast::Attr, (AttrId, MacroCallId, Box<[Option<MacroCallId>]>)> =
|
||||||
Key::new();
|
Key::new();
|
||||||
|
|
|
@ -58,11 +58,15 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use attr::Attr;
|
use attr::Attr;
|
||||||
use base_db::{impl_intern_key, salsa, CrateId};
|
use base_db::{impl_intern_key, salsa, CrateId, ProcMacroKind};
|
||||||
use hir_expand::{
|
use hir_expand::{
|
||||||
ast_id_map::FileAstId,
|
ast_id_map::FileAstId,
|
||||||
|
builtin_attr_macro::BuiltinAttrExpander,
|
||||||
|
builtin_derive_macro::BuiltinDeriveExpander,
|
||||||
|
builtin_fn_macro::{BuiltinFnLikeExpander, EagerExpander},
|
||||||
eager::{expand_eager_macro, ErrorEmitted, ErrorSink},
|
eager::{expand_eager_macro, ErrorEmitted, ErrorSink},
|
||||||
hygiene::Hygiene,
|
hygiene::Hygiene,
|
||||||
|
proc_macro::ProcMacroExpander,
|
||||||
AstId, ExpandError, ExpandTo, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefId,
|
AstId, ExpandError, ExpandTo, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefId,
|
||||||
MacroDefKind, UnresolvedMacro,
|
MacroDefKind, UnresolvedMacro,
|
||||||
};
|
};
|
||||||
|
@ -77,8 +81,8 @@ use crate::{
|
||||||
attr::AttrId,
|
attr::AttrId,
|
||||||
builtin_type::BuiltinType,
|
builtin_type::BuiltinType,
|
||||||
item_tree::{
|
item_tree::{
|
||||||
Const, Enum, Function, Impl, ItemTreeId, ItemTreeNode, ModItem, Static, Struct, Trait,
|
Const, Enum, Function, Impl, ItemTreeId, ItemTreeNode, MacroDef, MacroRules, ModItem,
|
||||||
TypeAlias, Union,
|
Static, Struct, Trait, TypeAlias, Union,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -268,6 +272,48 @@ pub struct ExternBlockId(salsa::InternId);
|
||||||
type ExternBlockLoc = ItemLoc<ExternBlock>;
|
type ExternBlockLoc = ItemLoc<ExternBlock>;
|
||||||
impl_intern!(ExternBlockId, ExternBlockLoc, intern_extern_block, lookup_intern_extern_block);
|
impl_intern!(ExternBlockId, ExternBlockLoc, intern_extern_block, lookup_intern_extern_block);
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
pub enum MacroExpander {
|
||||||
|
Declarative,
|
||||||
|
BuiltIn(BuiltinFnLikeExpander),
|
||||||
|
BuiltInAttr(BuiltinAttrExpander),
|
||||||
|
BuiltInDerive(BuiltinDeriveExpander),
|
||||||
|
BuiltInEager(EagerExpander),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
|
||||||
|
pub struct Macro2Id(salsa::InternId);
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
pub struct Macro2Loc {
|
||||||
|
pub container: ModuleId,
|
||||||
|
pub id: ItemTreeId<MacroDef>,
|
||||||
|
pub expander: MacroExpander,
|
||||||
|
}
|
||||||
|
impl_intern!(Macro2Id, Macro2Loc, intern_macro2, lookup_intern_macro2);
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
|
||||||
|
pub struct MacroRulesId(salsa::InternId);
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
pub struct MacroRulesLoc {
|
||||||
|
pub container: ModuleId,
|
||||||
|
pub id: ItemTreeId<MacroRules>,
|
||||||
|
pub local_inner: bool,
|
||||||
|
pub expander: MacroExpander,
|
||||||
|
}
|
||||||
|
impl_intern!(MacroRulesId, MacroRulesLoc, intern_macro_rules, lookup_intern_macro_rules);
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
|
||||||
|
pub struct ProcMacroId(salsa::InternId);
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
pub struct ProcMacroLoc {
|
||||||
|
// FIXME: this should be a crate? or just a crate-root module
|
||||||
|
pub container: ModuleId,
|
||||||
|
pub id: ItemTreeId<Function>,
|
||||||
|
pub expander: ProcMacroExpander,
|
||||||
|
pub kind: ProcMacroKind,
|
||||||
|
}
|
||||||
|
impl_intern!(ProcMacroId, ProcMacroLoc, intern_proc_macro, lookup_intern_proc_macro);
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
|
||||||
pub struct BlockId(salsa::InternId);
|
pub struct BlockId(salsa::InternId);
|
||||||
#[derive(Debug, Hash, PartialEq, Eq, Clone)]
|
#[derive(Debug, Hash, PartialEq, Eq, Clone)]
|
||||||
|
@ -284,8 +330,8 @@ pub struct TypeOrConstParamId {
|
||||||
pub local_id: LocalTypeOrConstParamId,
|
pub local_id: LocalTypeOrConstParamId,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
||||||
/// A TypeOrConstParamId with an invariant that it actually belongs to a type
|
/// A TypeOrConstParamId with an invariant that it actually belongs to a type
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
pub struct TypeParamId(TypeOrConstParamId);
|
pub struct TypeParamId(TypeOrConstParamId);
|
||||||
|
|
||||||
impl TypeParamId {
|
impl TypeParamId {
|
||||||
|
@ -359,6 +405,24 @@ pub enum AdtId {
|
||||||
}
|
}
|
||||||
impl_from!(StructId, UnionId, EnumId for AdtId);
|
impl_from!(StructId, UnionId, EnumId for AdtId);
|
||||||
|
|
||||||
|
/// A macro
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||||
|
pub enum MacroId {
|
||||||
|
Macro2Id(Macro2Id),
|
||||||
|
MacroRulesId(MacroRulesId),
|
||||||
|
ProcMacroId(ProcMacroId),
|
||||||
|
}
|
||||||
|
impl_from!(Macro2Id, MacroRulesId, ProcMacroId for MacroId);
|
||||||
|
|
||||||
|
impl MacroId {
|
||||||
|
pub fn is_attribute(self, db: &dyn db::DefDatabase) -> bool {
|
||||||
|
match self {
|
||||||
|
MacroId::ProcMacroId(it) => it.lookup(db).kind == ProcMacroKind::Attr,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A generic param
|
/// A generic param
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||||
pub enum GenericParamId {
|
pub enum GenericParamId {
|
||||||
|
@ -381,8 +445,10 @@ pub enum ModuleDefId {
|
||||||
TraitId(TraitId),
|
TraitId(TraitId),
|
||||||
TypeAliasId(TypeAliasId),
|
TypeAliasId(TypeAliasId),
|
||||||
BuiltinType(BuiltinType),
|
BuiltinType(BuiltinType),
|
||||||
|
MacroId(MacroId),
|
||||||
}
|
}
|
||||||
impl_from!(
|
impl_from!(
|
||||||
|
MacroId(Macro2Id, MacroRulesId, ProcMacroId),
|
||||||
ModuleId,
|
ModuleId,
|
||||||
FunctionId,
|
FunctionId,
|
||||||
AdtId(StructId, EnumId, UnionId),
|
AdtId(StructId, EnumId, UnionId),
|
||||||
|
@ -472,7 +538,7 @@ pub enum AttrDefId {
|
||||||
ConstId(ConstId),
|
ConstId(ConstId),
|
||||||
TraitId(TraitId),
|
TraitId(TraitId),
|
||||||
TypeAliasId(TypeAliasId),
|
TypeAliasId(TypeAliasId),
|
||||||
MacroDefId(MacroDefId),
|
MacroId(MacroId),
|
||||||
ImplId(ImplId),
|
ImplId(ImplId),
|
||||||
GenericParamId(GenericParamId),
|
GenericParamId(GenericParamId),
|
||||||
ExternBlockId(ExternBlockId),
|
ExternBlockId(ExternBlockId),
|
||||||
|
@ -488,7 +554,7 @@ impl_from!(
|
||||||
FunctionId,
|
FunctionId,
|
||||||
TraitId,
|
TraitId,
|
||||||
TypeAliasId,
|
TypeAliasId,
|
||||||
MacroDefId,
|
MacroId(Macro2Id, MacroRulesId, ProcMacroId),
|
||||||
ImplId,
|
ImplId,
|
||||||
GenericParamId
|
GenericParamId
|
||||||
for AttrDefId
|
for AttrDefId
|
||||||
|
@ -592,6 +658,16 @@ impl HasModule for VariantId {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl HasModule for MacroId {
|
||||||
|
fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
|
||||||
|
match self {
|
||||||
|
MacroId::MacroRulesId(it) => it.lookup(db).container,
|
||||||
|
MacroId::Macro2Id(it) => it.lookup(db).container,
|
||||||
|
MacroId::ProcMacroId(it) => it.lookup(db).container,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl HasModule for DefWithBodyId {
|
impl HasModule for DefWithBodyId {
|
||||||
fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
|
fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
|
||||||
match self {
|
match self {
|
||||||
|
@ -652,6 +728,7 @@ impl ModuleDefId {
|
||||||
ModuleDefId::StaticId(id) => id.lookup(db).module(db),
|
ModuleDefId::StaticId(id) => id.lookup(db).module(db),
|
||||||
ModuleDefId::TraitId(id) => id.lookup(db).container,
|
ModuleDefId::TraitId(id) => id.lookup(db).container,
|
||||||
ModuleDefId::TypeAliasId(id) => id.lookup(db).module(db),
|
ModuleDefId::TypeAliasId(id) => id.lookup(db).module(db),
|
||||||
|
ModuleDefId::MacroId(id) => id.module(db),
|
||||||
ModuleDefId::BuiltinType(_) => return None,
|
ModuleDefId::BuiltinType(_) => return None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -680,9 +757,7 @@ impl AttrDefId {
|
||||||
.module(db)
|
.module(db)
|
||||||
.krate
|
.krate
|
||||||
}
|
}
|
||||||
// FIXME: `MacroDefId` should store the defining module, then this can implement
|
AttrDefId::MacroId(it) => it.module(db).krate,
|
||||||
// `HasModule`
|
|
||||||
AttrDefId::MacroDefId(it) => it.krate,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -762,7 +837,7 @@ fn macro_call_as_call_id(
|
||||||
resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
|
resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
|
||||||
error_sink: &mut dyn FnMut(ExpandError),
|
error_sink: &mut dyn FnMut(ExpandError),
|
||||||
) -> Result<Result<MacroCallId, ErrorEmitted>, UnresolvedMacro> {
|
) -> Result<Result<MacroCallId, ErrorEmitted>, UnresolvedMacro> {
|
||||||
let def: MacroDefId =
|
let def =
|
||||||
resolver(call.path.clone()).ok_or_else(|| UnresolvedMacro { path: call.path.clone() })?;
|
resolver(call.path.clone()).ok_or_else(|| UnresolvedMacro { path: call.path.clone() })?;
|
||||||
|
|
||||||
let res = if let MacroDefKind::BuiltInEager(..) = def.kind {
|
let res = if let MacroDefKind::BuiltInEager(..) = def.kind {
|
||||||
|
@ -779,6 +854,74 @@ fn macro_call_as_call_id(
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn macro_id_to_def_id(db: &dyn db::DefDatabase, id: MacroId) -> MacroDefId {
|
||||||
|
match id {
|
||||||
|
MacroId::Macro2Id(it) => {
|
||||||
|
let loc = it.lookup(db);
|
||||||
|
|
||||||
|
let item_tree = loc.id.item_tree(db);
|
||||||
|
let makro = &item_tree[loc.id.value];
|
||||||
|
let in_file = |m: FileAstId<ast::MacroDef>| InFile::new(loc.id.file_id(), m.upcast());
|
||||||
|
MacroDefId {
|
||||||
|
krate: loc.container.krate,
|
||||||
|
kind: match loc.expander {
|
||||||
|
MacroExpander::Declarative => MacroDefKind::Declarative(in_file(makro.ast_id)),
|
||||||
|
MacroExpander::BuiltIn(it) => MacroDefKind::BuiltIn(it, in_file(makro.ast_id)),
|
||||||
|
MacroExpander::BuiltInAttr(it) => {
|
||||||
|
MacroDefKind::BuiltInAttr(it, in_file(makro.ast_id))
|
||||||
|
}
|
||||||
|
MacroExpander::BuiltInDerive(it) => {
|
||||||
|
MacroDefKind::BuiltInDerive(it, in_file(makro.ast_id))
|
||||||
|
}
|
||||||
|
MacroExpander::BuiltInEager(it) => {
|
||||||
|
MacroDefKind::BuiltInEager(it, in_file(makro.ast_id))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
local_inner: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MacroId::MacroRulesId(it) => {
|
||||||
|
let loc = it.lookup(db);
|
||||||
|
|
||||||
|
let item_tree = loc.id.item_tree(db);
|
||||||
|
let makro = &item_tree[loc.id.value];
|
||||||
|
let in_file = |m: FileAstId<ast::MacroRules>| InFile::new(loc.id.file_id(), m.upcast());
|
||||||
|
MacroDefId {
|
||||||
|
krate: loc.container.krate,
|
||||||
|
kind: match loc.expander {
|
||||||
|
MacroExpander::Declarative => MacroDefKind::Declarative(in_file(makro.ast_id)),
|
||||||
|
MacroExpander::BuiltIn(it) => MacroDefKind::BuiltIn(it, in_file(makro.ast_id)),
|
||||||
|
MacroExpander::BuiltInAttr(it) => {
|
||||||
|
MacroDefKind::BuiltInAttr(it, in_file(makro.ast_id))
|
||||||
|
}
|
||||||
|
MacroExpander::BuiltInDerive(it) => {
|
||||||
|
MacroDefKind::BuiltInDerive(it, in_file(makro.ast_id))
|
||||||
|
}
|
||||||
|
MacroExpander::BuiltInEager(it) => {
|
||||||
|
MacroDefKind::BuiltInEager(it, in_file(makro.ast_id))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
local_inner: loc.local_inner,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MacroId::ProcMacroId(it) => {
|
||||||
|
let loc = it.lookup(db);
|
||||||
|
|
||||||
|
let item_tree = loc.id.item_tree(db);
|
||||||
|
let makro = &item_tree[loc.id.value];
|
||||||
|
MacroDefId {
|
||||||
|
krate: loc.container.krate,
|
||||||
|
kind: MacroDefKind::ProcMacro(
|
||||||
|
loc.expander,
|
||||||
|
loc.kind,
|
||||||
|
InFile::new(loc.id.file_id(), makro.ast_id),
|
||||||
|
),
|
||||||
|
local_inner: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn derive_macro_as_call_id(
|
fn derive_macro_as_call_id(
|
||||||
db: &dyn db::DefDatabase,
|
db: &dyn db::DefDatabase,
|
||||||
item_attr: &AstIdWithPath<ast::Adt>,
|
item_attr: &AstIdWithPath<ast::Adt>,
|
||||||
|
|
|
@ -33,8 +33,8 @@ use syntax::{
|
||||||
use tt::{Subtree, TokenId};
|
use tt::{Subtree, TokenId};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
db::DefDatabase, nameres::ModuleSource, resolver::HasResolver, src::HasSource, test_db::TestDB,
|
db::DefDatabase, macro_id_to_def_id, nameres::ModuleSource, resolver::HasResolver,
|
||||||
AdtId, AsMacroCall, Lookup, ModuleDefId,
|
src::HasSource, test_db::TestDB, AdtId, AsMacroCall, Lookup, ModuleDefId,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
|
@ -128,7 +128,9 @@ pub fn identity_when_valid(_attr: TokenStream, item: TokenStream) -> TokenStream
|
||||||
.as_call_id_with_errors(
|
.as_call_id_with_errors(
|
||||||
&db,
|
&db,
|
||||||
krate,
|
krate,
|
||||||
|path| resolver.resolve_path_as_macro(&db, &path),
|
|path| {
|
||||||
|
resolver.resolve_path_as_macro(&db, &path).map(|it| macro_id_to_def_id(&db, it))
|
||||||
|
},
|
||||||
&mut |err| error = Some(err),
|
&mut |err| error = Some(err),
|
||||||
)
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
|
|
@ -75,11 +75,9 @@ use crate::{
|
||||||
path::ModPath,
|
path::ModPath,
|
||||||
per_ns::PerNs,
|
per_ns::PerNs,
|
||||||
visibility::Visibility,
|
visibility::Visibility,
|
||||||
AstId, BlockId, BlockLoc, LocalModuleId, ModuleDefId, ModuleId,
|
AstId, BlockId, BlockLoc, FunctionId, LocalModuleId, ModuleDefId, ModuleId, ProcMacroId,
|
||||||
};
|
};
|
||||||
|
|
||||||
use self::proc_macro::ProcMacroDef;
|
|
||||||
|
|
||||||
/// Contains the results of (early) name resolution.
|
/// Contains the results of (early) name resolution.
|
||||||
///
|
///
|
||||||
/// A `DefMap` stores the module tree and the definitions that are in scope in every module after
|
/// A `DefMap` stores the module tree and the definitions that are in scope in every module after
|
||||||
|
@ -102,11 +100,9 @@ pub struct DefMap {
|
||||||
prelude: Option<ModuleId>,
|
prelude: Option<ModuleId>,
|
||||||
extern_prelude: FxHashMap<Name, ModuleDefId>,
|
extern_prelude: FxHashMap<Name, ModuleDefId>,
|
||||||
|
|
||||||
/// Side table with additional proc. macro info, for use by name resolution in downstream
|
/// Side table for resolving derive helpers.
|
||||||
/// crates.
|
exported_derives: FxHashMap<MacroDefId, Box<[Name]>>,
|
||||||
///
|
fn_proc_macro_mapping: FxHashMap<FunctionId, ProcMacroId>,
|
||||||
/// (the primary purpose is to resolve derive helpers and fetch a proc-macros name)
|
|
||||||
exported_proc_macros: FxHashMap<MacroDefId, ProcMacroDef>,
|
|
||||||
|
|
||||||
/// Custom attributes registered with `#![register_attr]`.
|
/// Custom attributes registered with `#![register_attr]`.
|
||||||
registered_attrs: Vec<SmolStr>,
|
registered_attrs: Vec<SmolStr>,
|
||||||
|
@ -275,7 +271,8 @@ impl DefMap {
|
||||||
edition,
|
edition,
|
||||||
recursion_limit: None,
|
recursion_limit: None,
|
||||||
extern_prelude: FxHashMap::default(),
|
extern_prelude: FxHashMap::default(),
|
||||||
exported_proc_macros: FxHashMap::default(),
|
exported_derives: FxHashMap::default(),
|
||||||
|
fn_proc_macro_mapping: FxHashMap::default(),
|
||||||
prelude: None,
|
prelude: None,
|
||||||
root,
|
root,
|
||||||
modules,
|
modules,
|
||||||
|
@ -295,9 +292,6 @@ impl DefMap {
|
||||||
pub fn modules(&self) -> impl Iterator<Item = (LocalModuleId, &ModuleData)> + '_ {
|
pub fn modules(&self) -> impl Iterator<Item = (LocalModuleId, &ModuleData)> + '_ {
|
||||||
self.modules.iter()
|
self.modules.iter()
|
||||||
}
|
}
|
||||||
pub fn exported_proc_macros(&self) -> impl Iterator<Item = (MacroDefId, Name)> + '_ {
|
|
||||||
self.exported_proc_macros.iter().map(|(id, def)| (*id, def.name.clone()))
|
|
||||||
}
|
|
||||||
pub fn registered_tools(&self) -> &[SmolStr] {
|
pub fn registered_tools(&self) -> &[SmolStr] {
|
||||||
&self.registered_tools
|
&self.registered_tools
|
||||||
}
|
}
|
||||||
|
@ -308,6 +302,10 @@ impl DefMap {
|
||||||
self.root
|
self.root
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn fn_as_proc_macro(&self, id: FunctionId) -> Option<ProcMacroId> {
|
||||||
|
self.fn_proc_macro_mapping.get(&id).copied()
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn krate(&self) -> CrateId {
|
pub(crate) fn krate(&self) -> CrateId {
|
||||||
self.krate
|
self.krate
|
||||||
}
|
}
|
||||||
|
@ -455,12 +453,13 @@ impl DefMap {
|
||||||
// Exhaustive match to require handling new fields.
|
// Exhaustive match to require handling new fields.
|
||||||
let Self {
|
let Self {
|
||||||
_c: _,
|
_c: _,
|
||||||
exported_proc_macros,
|
exported_derives,
|
||||||
extern_prelude,
|
extern_prelude,
|
||||||
diagnostics,
|
diagnostics,
|
||||||
modules,
|
modules,
|
||||||
registered_attrs,
|
registered_attrs,
|
||||||
registered_tools,
|
registered_tools,
|
||||||
|
fn_proc_macro_mapping,
|
||||||
block: _,
|
block: _,
|
||||||
edition: _,
|
edition: _,
|
||||||
recursion_limit: _,
|
recursion_limit: _,
|
||||||
|
@ -470,11 +469,12 @@ impl DefMap {
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
extern_prelude.shrink_to_fit();
|
extern_prelude.shrink_to_fit();
|
||||||
exported_proc_macros.shrink_to_fit();
|
exported_derives.shrink_to_fit();
|
||||||
diagnostics.shrink_to_fit();
|
diagnostics.shrink_to_fit();
|
||||||
modules.shrink_to_fit();
|
modules.shrink_to_fit();
|
||||||
registered_attrs.shrink_to_fit();
|
registered_attrs.shrink_to_fit();
|
||||||
registered_tools.shrink_to_fit();
|
registered_tools.shrink_to_fit();
|
||||||
|
fn_proc_macro_mapping.shrink_to_fit();
|
||||||
for (_, module) in modules.iter_mut() {
|
for (_, module) in modules.iter_mut() {
|
||||||
module.children.shrink_to_fit();
|
module.children.shrink_to_fit();
|
||||||
module.scope.shrink_to_fit();
|
module.scope.shrink_to_fit();
|
||||||
|
|
|
@ -8,6 +8,7 @@ use crate::{
|
||||||
attr_macro_as_call_id, builtin_attr,
|
attr_macro_as_call_id, builtin_attr,
|
||||||
db::DefDatabase,
|
db::DefDatabase,
|
||||||
item_scope::BuiltinShadowMode,
|
item_scope::BuiltinShadowMode,
|
||||||
|
macro_id_to_def_id,
|
||||||
nameres::path_resolution::ResolveMode,
|
nameres::path_resolution::ResolveMode,
|
||||||
path::{ModPath, PathKind},
|
path::{ModPath, PathKind},
|
||||||
AstIdWithPath, LocalModuleId, UnresolvedMacro,
|
AstIdWithPath, LocalModuleId, UnresolvedMacro,
|
||||||
|
@ -45,7 +46,7 @@ impl DefMap {
|
||||||
);
|
);
|
||||||
let def = match resolved_res.resolved_def.take_macros() {
|
let def = match resolved_res.resolved_def.take_macros() {
|
||||||
Some(def) => {
|
Some(def) => {
|
||||||
if def.is_attribute() {
|
if def.is_attribute(db) {
|
||||||
def
|
def
|
||||||
} else {
|
} else {
|
||||||
return Ok(ResolvedAttr::Other);
|
return Ok(ResolvedAttr::Other);
|
||||||
|
@ -54,7 +55,14 @@ impl DefMap {
|
||||||
None => return Err(UnresolvedMacro { path: ast_id.path.clone() }),
|
None => return Err(UnresolvedMacro { path: ast_id.path.clone() }),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(ResolvedAttr::Macro(attr_macro_as_call_id(db, &ast_id, attr, self.krate, def, false)))
|
Ok(ResolvedAttr::Macro(attr_macro_as_call_id(
|
||||||
|
db,
|
||||||
|
&ast_id,
|
||||||
|
attr,
|
||||||
|
self.krate,
|
||||||
|
macro_id_to_def_id(db, def),
|
||||||
|
false,
|
||||||
|
)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn is_builtin_or_registered_attr(&self, path: &ModPath) -> bool {
|
pub(crate) fn is_builtin_or_registered_attr(&self, path: &ModPath) -> bool {
|
||||||
|
|
|
@ -5,8 +5,9 @@
|
||||||
|
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
|
||||||
use base_db::{CrateId, Edition, FileId, ProcMacroId};
|
use base_db::{CrateId, Edition, FileId};
|
||||||
use cfg::{CfgExpr, CfgOptions};
|
use cfg::{CfgExpr, CfgOptions};
|
||||||
|
use either::Either;
|
||||||
use hir_expand::{
|
use hir_expand::{
|
||||||
ast_id_map::FileAstId,
|
ast_id_map::FileAstId,
|
||||||
builtin_attr_macro::find_builtin_attr,
|
builtin_attr_macro::find_builtin_attr,
|
||||||
|
@ -34,7 +35,7 @@ use crate::{
|
||||||
self, Fields, FileItemTreeId, ImportKind, ItemTree, ItemTreeId, ItemTreeNode, MacroCall,
|
self, Fields, FileItemTreeId, ImportKind, ItemTree, ItemTreeId, ItemTreeNode, MacroCall,
|
||||||
MacroDef, MacroRules, Mod, ModItem, ModKind, TreeId,
|
MacroDef, MacroRules, Mod, ModItem, ModKind, TreeId,
|
||||||
},
|
},
|
||||||
macro_call_as_call_id,
|
macro_call_as_call_id, macro_id_to_def_id,
|
||||||
nameres::{
|
nameres::{
|
||||||
diagnostics::DefDiagnostic,
|
diagnostics::DefDiagnostic,
|
||||||
mod_resolution::ModDir,
|
mod_resolution::ModDir,
|
||||||
|
@ -45,9 +46,10 @@ use crate::{
|
||||||
path::{ImportAlias, ModPath, PathKind},
|
path::{ImportAlias, ModPath, PathKind},
|
||||||
per_ns::PerNs,
|
per_ns::PerNs,
|
||||||
visibility::{RawVisibility, Visibility},
|
visibility::{RawVisibility, Visibility},
|
||||||
AdtId, AstId, AstIdWithPath, ConstLoc, EnumLoc, EnumVariantId, ExternBlockLoc, FunctionLoc,
|
AdtId, AstId, AstIdWithPath, ConstLoc, EnumLoc, EnumVariantId, ExternBlockLoc, FunctionId,
|
||||||
ImplLoc, Intern, ItemContainerId, LocalModuleId, ModuleDefId, StaticLoc, StructLoc, TraitLoc,
|
FunctionLoc, ImplLoc, Intern, ItemContainerId, LocalModuleId, Macro2Id, Macro2Loc,
|
||||||
TypeAliasLoc, UnionLoc, UnresolvedMacro,
|
MacroExpander, MacroId, MacroRulesId, MacroRulesLoc, ModuleDefId, ModuleId, ProcMacroId,
|
||||||
|
ProcMacroLoc, StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, UnionLoc, UnresolvedMacro,
|
||||||
};
|
};
|
||||||
|
|
||||||
static GLOB_RECURSION_LIMIT: Limit = Limit::new(100);
|
static GLOB_RECURSION_LIMIT: Limit = Limit::new(100);
|
||||||
|
@ -79,7 +81,10 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, mut def_map: DefMap, tree_id: T
|
||||||
.map(|(idx, it)| {
|
.map(|(idx, it)| {
|
||||||
// FIXME: a hacky way to create a Name from string.
|
// FIXME: a hacky way to create a Name from string.
|
||||||
let name = tt::Ident { text: it.name.clone(), id: tt::TokenId::unspecified() };
|
let name = tt::Ident { text: it.name.clone(), id: tt::TokenId::unspecified() };
|
||||||
(name.as_name(), ProcMacroExpander::new(def_map.krate, ProcMacroId(idx as u32)))
|
(
|
||||||
|
name.as_name(),
|
||||||
|
ProcMacroExpander::new(def_map.krate, base_db::ProcMacroId(idx as u32)),
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
@ -543,28 +548,30 @@ impl DefCollector<'_> {
|
||||||
/// use a dummy expander that always errors. This comes with the drawback of macros potentially
|
/// use a dummy expander that always errors. This comes with the drawback of macros potentially
|
||||||
/// going out of sync with what the build system sees (since we resolve using VFS state, but
|
/// going out of sync with what the build system sees (since we resolve using VFS state, but
|
||||||
/// Cargo builds only on-disk files). We could and probably should add diagnostics for that.
|
/// Cargo builds only on-disk files). We could and probably should add diagnostics for that.
|
||||||
fn export_proc_macro(&mut self, def: ProcMacroDef, ast_id: AstId<ast::Fn>) {
|
fn export_proc_macro(
|
||||||
let kind = def.kind.to_basedb_kind();
|
&mut self,
|
||||||
|
def: ProcMacroDef,
|
||||||
|
id: ItemTreeId<item_tree::Function>,
|
||||||
|
fn_id: FunctionId,
|
||||||
|
module_id: ModuleId,
|
||||||
|
) {
|
||||||
self.exports_proc_macros = true;
|
self.exports_proc_macros = true;
|
||||||
let macro_def = match self.proc_macros.iter().find(|(n, _)| n == &def.name) {
|
|
||||||
Some(&(_, expander)) => MacroDefId {
|
let kind = def.kind.to_basedb_kind();
|
||||||
krate: self.def_map.krate,
|
let (expander, kind) = match self.proc_macros.iter().find(|(n, _)| n == &def.name) {
|
||||||
kind: MacroDefKind::ProcMacro(expander, kind, ast_id),
|
Some(&(_, expander)) => (expander, kind),
|
||||||
local_inner: false,
|
None => (ProcMacroExpander::dummy(self.def_map.krate), kind),
|
||||||
},
|
|
||||||
None => MacroDefId {
|
|
||||||
krate: self.def_map.krate,
|
|
||||||
kind: MacroDefKind::ProcMacro(
|
|
||||||
ProcMacroExpander::dummy(self.def_map.krate),
|
|
||||||
kind,
|
|
||||||
ast_id,
|
|
||||||
),
|
|
||||||
local_inner: false,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
self.define_proc_macro(def.name.clone(), macro_def);
|
let proc_macro_id =
|
||||||
self.def_map.exported_proc_macros.insert(macro_def, def);
|
ProcMacroLoc { container: module_id, id, expander, kind }.intern(self.db);
|
||||||
|
self.define_proc_macro(def.name.clone(), proc_macro_id.into());
|
||||||
|
if let ProcMacroKind::CustomDerive { helpers } = def.kind {
|
||||||
|
self.def_map
|
||||||
|
.exported_derives
|
||||||
|
.insert(macro_id_to_def_id(self.db, proc_macro_id.into()), helpers);
|
||||||
|
}
|
||||||
|
self.def_map.fn_proc_macro_mapping.insert(fn_id, proc_macro_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Define a macro with `macro_rules`.
|
/// Define a macro with `macro_rules`.
|
||||||
|
@ -596,20 +603,21 @@ impl DefCollector<'_> {
|
||||||
&mut self,
|
&mut self,
|
||||||
module_id: LocalModuleId,
|
module_id: LocalModuleId,
|
||||||
name: Name,
|
name: Name,
|
||||||
macro_: MacroDefId,
|
macro_: MacroRulesId,
|
||||||
export: bool,
|
export: bool,
|
||||||
) {
|
) {
|
||||||
// Textual scoping
|
// Textual scoping
|
||||||
self.define_legacy_macro(module_id, name.clone(), macro_);
|
self.define_legacy_macro(module_id, name.clone(), macro_);
|
||||||
self.def_map.modules[module_id].scope.declare_macro(macro_);
|
|
||||||
|
|
||||||
// Module scoping
|
// Module scoping
|
||||||
// In Rust, `#[macro_export]` macros are unconditionally visible at the
|
// In Rust, `#[macro_export]` macros are unconditionally visible at the
|
||||||
// crate root, even if the parent modules is **not** visible.
|
// crate root, even if the parent modules is **not** visible.
|
||||||
if export {
|
if export {
|
||||||
|
let module_id = self.def_map.root;
|
||||||
|
self.def_map.modules[module_id].scope.declare(macro_.into());
|
||||||
self.update(
|
self.update(
|
||||||
self.def_map.root,
|
module_id,
|
||||||
&[(Some(name), PerNs::macros(macro_, Visibility::Public))],
|
&[(Some(name), PerNs::macros(macro_.into(), Visibility::Public))],
|
||||||
Visibility::Public,
|
Visibility::Public,
|
||||||
ImportType::Named,
|
ImportType::Named,
|
||||||
);
|
);
|
||||||
|
@ -623,7 +631,7 @@ impl DefCollector<'_> {
|
||||||
/// the definition of current module.
|
/// the definition of current module.
|
||||||
/// And also, `macro_use` on a module will import all legacy macros visible inside to
|
/// And also, `macro_use` on a module will import all legacy macros visible inside to
|
||||||
/// current legacy scope, with possible shadowing.
|
/// current legacy scope, with possible shadowing.
|
||||||
fn define_legacy_macro(&mut self, module_id: LocalModuleId, name: Name, mac: MacroDefId) {
|
fn define_legacy_macro(&mut self, module_id: LocalModuleId, name: Name, mac: MacroRulesId) {
|
||||||
// Always shadowing
|
// Always shadowing
|
||||||
self.def_map.modules[module_id].scope.define_legacy_macro(name, mac);
|
self.def_map.modules[module_id].scope.define_legacy_macro(name, mac);
|
||||||
}
|
}
|
||||||
|
@ -635,24 +643,30 @@ impl DefCollector<'_> {
|
||||||
&mut self,
|
&mut self,
|
||||||
module_id: LocalModuleId,
|
module_id: LocalModuleId,
|
||||||
name: Name,
|
name: Name,
|
||||||
macro_: MacroDefId,
|
macro_: Macro2Id,
|
||||||
vis: &RawVisibility,
|
vis: &RawVisibility,
|
||||||
) {
|
) {
|
||||||
let vis =
|
let vis =
|
||||||
self.def_map.resolve_visibility(self.db, module_id, vis).unwrap_or(Visibility::Public);
|
self.def_map.resolve_visibility(self.db, module_id, vis).unwrap_or(Visibility::Public);
|
||||||
self.def_map.modules[module_id].scope.declare_macro(macro_);
|
self.def_map.modules[module_id].scope.declare(macro_.into());
|
||||||
self.update(module_id, &[(Some(name), PerNs::macros(macro_, vis))], vis, ImportType::Named);
|
self.update(
|
||||||
|
module_id,
|
||||||
|
&[(Some(name), PerNs::macros(macro_.into(), Visibility::Public))],
|
||||||
|
vis,
|
||||||
|
ImportType::Named,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Define a proc macro
|
/// Define a proc macro
|
||||||
///
|
///
|
||||||
/// A proc macro is similar to normal macro scope, but it would not visible in legacy textual scoped.
|
/// A proc macro is similar to normal macro scope, but it would not visible in legacy textual scoped.
|
||||||
/// And unconditionally exported.
|
/// And unconditionally exported.
|
||||||
fn define_proc_macro(&mut self, name: Name, macro_: MacroDefId) {
|
fn define_proc_macro(&mut self, name: Name, macro_: ProcMacroId) {
|
||||||
self.def_map.modules[self.def_map.root].scope.declare_macro(macro_);
|
let module_id = self.def_map.root;
|
||||||
|
self.def_map.modules[module_id].scope.declare(macro_.into());
|
||||||
self.update(
|
self.update(
|
||||||
self.def_map.root,
|
module_id,
|
||||||
&[(Some(name), PerNs::macros(macro_, Visibility::Public))],
|
&[(Some(name), PerNs::macros(macro_.into(), Visibility::Public))],
|
||||||
Visibility::Public,
|
Visibility::Public,
|
||||||
ImportType::Named,
|
ImportType::Named,
|
||||||
);
|
);
|
||||||
|
@ -691,10 +705,12 @@ impl DefCollector<'_> {
|
||||||
fn import_all_macros_exported(&mut self, current_module_id: LocalModuleId, krate: CrateId) {
|
fn import_all_macros_exported(&mut self, current_module_id: LocalModuleId, krate: CrateId) {
|
||||||
let def_map = self.db.crate_def_map(krate);
|
let def_map = self.db.crate_def_map(krate);
|
||||||
for (name, def) in def_map[def_map.root].scope.macros() {
|
for (name, def) in def_map[def_map.root].scope.macros() {
|
||||||
|
if let MacroId::MacroRulesId(def) = def {
|
||||||
// `macro_use` only bring things into legacy scope.
|
// `macro_use` only bring things into legacy scope.
|
||||||
self.define_legacy_macro(current_module_id, name.clone(), def);
|
self.define_legacy_macro(current_module_id, name.clone(), def);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Tries to resolve every currently unresolved import.
|
/// Tries to resolve every currently unresolved import.
|
||||||
fn resolve_imports(&mut self) -> ReachedFixedPoint {
|
fn resolve_imports(&mut self) -> ReachedFixedPoint {
|
||||||
|
@ -1049,7 +1065,7 @@ impl DefCollector<'_> {
|
||||||
&path,
|
&path,
|
||||||
BuiltinShadowMode::Module,
|
BuiltinShadowMode::Module,
|
||||||
);
|
);
|
||||||
resolved_res.resolved_def.take_macros()
|
resolved_res.resolved_def.take_macros().map(|it| macro_id_to_def_id(self.db, it))
|
||||||
};
|
};
|
||||||
|
|
||||||
match &directive.kind {
|
match &directive.kind {
|
||||||
|
@ -1293,8 +1309,7 @@ impl DefCollector<'_> {
|
||||||
if let MacroCallKind::Derive { ast_id, .. } = &loc.kind {
|
if let MacroCallKind::Derive { ast_id, .. } = &loc.kind {
|
||||||
if loc.def.krate != self.def_map.krate {
|
if loc.def.krate != self.def_map.krate {
|
||||||
let def_map = self.db.crate_def_map(loc.def.krate);
|
let def_map = self.db.crate_def_map(loc.def.krate);
|
||||||
if let Some(def) = def_map.exported_proc_macros.get(&loc.def) {
|
if let Some(helpers) = def_map.exported_derives.get(&loc.def) {
|
||||||
if let ProcMacroKind::CustomDerive { helpers } = &def.kind {
|
|
||||||
self.derive_helpers_in_scope
|
self.derive_helpers_in_scope
|
||||||
.entry(ast_id.map(|it| it.upcast()))
|
.entry(ast_id.map(|it| it.upcast()))
|
||||||
.or_default()
|
.or_default()
|
||||||
|
@ -1302,7 +1317,6 @@ impl DefCollector<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Then, fetch and process the item tree. This will reuse the expansion result from above.
|
// Then, fetch and process the item tree. This will reuse the expansion result from above.
|
||||||
let item_tree = self.db.file_item_tree(file_id);
|
let item_tree = self.db.file_item_tree(file_id);
|
||||||
|
@ -1339,7 +1353,10 @@ impl DefCollector<'_> {
|
||||||
&path,
|
&path,
|
||||||
BuiltinShadowMode::Module,
|
BuiltinShadowMode::Module,
|
||||||
);
|
);
|
||||||
resolved_res.resolved_def.take_macros()
|
resolved_res
|
||||||
|
.resolved_def
|
||||||
|
.take_macros()
|
||||||
|
.map(|it| macro_id_to_def_id(self.db, it))
|
||||||
},
|
},
|
||||||
&mut |_| (),
|
&mut |_| (),
|
||||||
);
|
);
|
||||||
|
@ -1525,10 +1542,9 @@ impl ModCollector<'_, '_> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ModItem::MacroCall(mac) => self.collect_macro_call(&self.item_tree[mac], container),
|
ModItem::MacroCall(mac) => self.collect_macro_call(&self.item_tree[mac], container),
|
||||||
ModItem::MacroRules(id) => self.collect_macro_rules(id),
|
ModItem::MacroRules(id) => self.collect_macro_rules(id, module),
|
||||||
ModItem::MacroDef(id) => self.collect_macro_def(id),
|
ModItem::MacroDef(id) => self.collect_macro_def(id, module),
|
||||||
ModItem::Impl(imp) => {
|
ModItem::Impl(imp) => {
|
||||||
let module = self.def_collector.def_map.module_id(self.module_id);
|
|
||||||
let impl_id =
|
let impl_id =
|
||||||
ImplLoc { container: module, id: ItemTreeId::new(self.tree_id, imp) }
|
ImplLoc { container: module, id: ItemTreeId::new(self.tree_id, imp) }
|
||||||
.intern(db);
|
.intern(db);
|
||||||
|
@ -1536,27 +1552,26 @@ impl ModCollector<'_, '_> {
|
||||||
}
|
}
|
||||||
ModItem::Function(id) => {
|
ModItem::Function(id) => {
|
||||||
let it = &self.item_tree[id];
|
let it = &self.item_tree[id];
|
||||||
|
let fn_id =
|
||||||
|
FunctionLoc { container, id: ItemTreeId::new(self.tree_id, id) }.intern(db);
|
||||||
|
|
||||||
let is_proc_macro = attrs.parse_proc_macro_decl(&it.name);
|
let is_proc_macro = attrs.parse_proc_macro_decl(&it.name);
|
||||||
let vis = match is_proc_macro {
|
let vis = match is_proc_macro {
|
||||||
Some(proc_macro) => {
|
Some(proc_macro) => {
|
||||||
// FIXME: this should only be done in the root module of `proc-macro` crates, not everywhere
|
// FIXME: this should only be done in the root module of `proc-macro` crates, not everywhere
|
||||||
let ast_id = InFile::new(self.tree_id.file_id(), it.ast_id);
|
|
||||||
let module_id = def_map.module_id(def_map.root());
|
let module_id = def_map.module_id(def_map.root());
|
||||||
self.def_collector.export_proc_macro(proc_macro, ast_id);
|
|
||||||
|
self.def_collector.export_proc_macro(
|
||||||
|
proc_macro,
|
||||||
|
ItemTreeId::new(self.tree_id, id),
|
||||||
|
fn_id,
|
||||||
|
module_id,
|
||||||
|
);
|
||||||
Visibility::Module(module_id)
|
Visibility::Module(module_id)
|
||||||
}
|
}
|
||||||
None => resolve_vis(def_map, &self.item_tree[it.visibility]),
|
None => resolve_vis(def_map, &self.item_tree[it.visibility]),
|
||||||
};
|
};
|
||||||
update_def(
|
update_def(self.def_collector, fn_id.into(), &it.name, vis, false);
|
||||||
self.def_collector,
|
|
||||||
FunctionLoc { container, id: ItemTreeId::new(self.tree_id, id) }
|
|
||||||
.intern(db)
|
|
||||||
.into(),
|
|
||||||
&it.name,
|
|
||||||
vis,
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
ModItem::Struct(id) => {
|
ModItem::Struct(id) => {
|
||||||
let it = &self.item_tree[id];
|
let it = &self.item_tree[id];
|
||||||
|
@ -1845,7 +1860,7 @@ impl ModCollector<'_, '_> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn collect_macro_rules(&mut self, id: FileItemTreeId<MacroRules>) {
|
fn collect_macro_rules(&mut self, id: FileItemTreeId<MacroRules>, module: ModuleId) {
|
||||||
let krate = self.def_collector.def_map.krate;
|
let krate = self.def_collector.def_map.krate;
|
||||||
let mac = &self.item_tree[id];
|
let mac = &self.item_tree[id];
|
||||||
let attrs = self.item_tree.attrs(self.def_collector.db, krate, ModItem::from(id).into());
|
let attrs = self.item_tree.attrs(self.def_collector.db, krate, ModItem::from(id).into());
|
||||||
|
@ -1854,7 +1869,7 @@ impl ModCollector<'_, '_> {
|
||||||
let export_attr = attrs.by_key("macro_export");
|
let export_attr = attrs.by_key("macro_export");
|
||||||
|
|
||||||
let is_export = export_attr.exists();
|
let is_export = export_attr.exists();
|
||||||
let is_local_inner = if is_export {
|
let local_inner = if is_export {
|
||||||
export_attr.tt_values().flat_map(|it| &it.token_trees).any(|it| match it {
|
export_attr.tt_values().flat_map(|it| &it.token_trees).any(|it| match it {
|
||||||
tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => {
|
tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => {
|
||||||
ident.text.contains("local_inner_macros")
|
ident.text.contains("local_inner_macros")
|
||||||
|
@ -1866,7 +1881,7 @@ impl ModCollector<'_, '_> {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Case 1: builtin macros
|
// Case 1: builtin macros
|
||||||
if attrs.by_key("rustc_builtin_macro").exists() {
|
let expander = if attrs.by_key("rustc_builtin_macro").exists() {
|
||||||
// `#[rustc_builtin_macro = "builtin_name"]` overrides the `macro_rules!` name.
|
// `#[rustc_builtin_macro = "builtin_name"]` overrides the `macro_rules!` name.
|
||||||
let name;
|
let name;
|
||||||
let name = match attrs.by_key("rustc_builtin_macro").string_value() {
|
let name = match attrs.by_key("rustc_builtin_macro").string_value() {
|
||||||
|
@ -1892,32 +1907,29 @@ impl ModCollector<'_, '_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let krate = self.def_collector.def_map.krate;
|
match find_builtin_macro(name) {
|
||||||
match find_builtin_macro(name, krate, ast_id) {
|
Some(Either::Left(it)) => MacroExpander::BuiltIn(it),
|
||||||
Some(macro_id) => {
|
Some(Either::Right(it)) => MacroExpander::BuiltInEager(it),
|
||||||
self.def_collector.define_macro_rules(
|
|
||||||
self.module_id,
|
|
||||||
mac.name.clone(),
|
|
||||||
macro_id,
|
|
||||||
is_export,
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
None => {
|
None => {
|
||||||
self.def_collector
|
self.def_collector
|
||||||
.def_map
|
.def_map
|
||||||
.diagnostics
|
.diagnostics
|
||||||
.push(DefDiagnostic::unimplemented_builtin_macro(self.module_id, ast_id));
|
.push(DefDiagnostic::unimplemented_builtin_macro(self.module_id, ast_id));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
|
|
||||||
// Case 2: normal `macro_rules!` macro
|
// Case 2: normal `macro_rules!` macro
|
||||||
let macro_id = MacroDefId {
|
MacroExpander::Declarative
|
||||||
krate: self.def_collector.def_map.krate,
|
|
||||||
kind: MacroDefKind::Declarative(ast_id),
|
|
||||||
local_inner: is_local_inner,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let macro_id = MacroRulesLoc {
|
||||||
|
container: module,
|
||||||
|
id: ItemTreeId::new(self.tree_id, id),
|
||||||
|
local_inner,
|
||||||
|
expander,
|
||||||
|
}
|
||||||
|
.intern(self.def_collector.db);
|
||||||
self.def_collector.define_macro_rules(
|
self.def_collector.define_macro_rules(
|
||||||
self.module_id,
|
self.module_id,
|
||||||
mac.name.clone(),
|
mac.name.clone(),
|
||||||
|
@ -1926,44 +1938,38 @@ impl ModCollector<'_, '_> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn collect_macro_def(&mut self, id: FileItemTreeId<MacroDef>) {
|
fn collect_macro_def(&mut self, id: FileItemTreeId<MacroDef>, module: ModuleId) {
|
||||||
let krate = self.def_collector.def_map.krate;
|
let krate = self.def_collector.def_map.krate;
|
||||||
let mac = &self.item_tree[id];
|
let mac = &self.item_tree[id];
|
||||||
let ast_id = InFile::new(self.file_id(), mac.ast_id.upcast());
|
let ast_id = InFile::new(self.file_id(), mac.ast_id.upcast());
|
||||||
|
|
||||||
// Case 1: builtin macros
|
// Case 1: builtin macros
|
||||||
let attrs = self.item_tree.attrs(self.def_collector.db, krate, ModItem::from(id).into());
|
let attrs = self.item_tree.attrs(self.def_collector.db, krate, ModItem::from(id).into());
|
||||||
if attrs.by_key("rustc_builtin_macro").exists() {
|
let expander = if attrs.by_key("rustc_builtin_macro").exists() {
|
||||||
let macro_id = find_builtin_macro(&mac.name, krate, ast_id)
|
if let Some(expander) = find_builtin_macro(&mac.name) {
|
||||||
.or_else(|| find_builtin_derive(&mac.name, krate, ast_id))
|
match expander {
|
||||||
.or_else(|| find_builtin_attr(&mac.name, krate, ast_id));
|
Either::Left(it) => MacroExpander::BuiltIn(it),
|
||||||
|
Either::Right(it) => MacroExpander::BuiltInEager(it),
|
||||||
match macro_id {
|
|
||||||
Some(macro_id) => {
|
|
||||||
self.def_collector.define_macro_def(
|
|
||||||
self.module_id,
|
|
||||||
mac.name.clone(),
|
|
||||||
macro_id,
|
|
||||||
&self.item_tree[mac.visibility],
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
None => {
|
} else if let Some(expander) = find_builtin_derive(&mac.name) {
|
||||||
|
MacroExpander::BuiltInDerive(expander)
|
||||||
|
} else if let Some(expander) = find_builtin_attr(&mac.name) {
|
||||||
|
MacroExpander::BuiltInAttr(expander)
|
||||||
|
} else {
|
||||||
self.def_collector
|
self.def_collector
|
||||||
.def_map
|
.def_map
|
||||||
.diagnostics
|
.diagnostics
|
||||||
.push(DefDiagnostic::unimplemented_builtin_macro(self.module_id, ast_id));
|
.push(DefDiagnostic::unimplemented_builtin_macro(self.module_id, ast_id));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
}
|
|
||||||
|
|
||||||
// Case 2: normal `macro`
|
// Case 2: normal `macro`
|
||||||
let macro_id = MacroDefId {
|
MacroExpander::Declarative
|
||||||
krate: self.def_collector.def_map.krate,
|
|
||||||
kind: MacroDefKind::Declarative(ast_id),
|
|
||||||
local_inner: false,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let macro_id =
|
||||||
|
Macro2Loc { container: module, id: ItemTreeId::new(self.tree_id, id), expander }
|
||||||
|
.intern(self.def_collector.db);
|
||||||
self.def_collector.define_macro_def(
|
self.def_collector.define_macro_def(
|
||||||
self.module_id,
|
self.module_id,
|
||||||
mac.name.clone(),
|
mac.name.clone(),
|
||||||
|
@ -1987,7 +1993,12 @@ impl ModCollector<'_, '_> {
|
||||||
self.def_collector.def_map.with_ancestor_maps(
|
self.def_collector.def_map.with_ancestor_maps(
|
||||||
self.def_collector.db,
|
self.def_collector.db,
|
||||||
self.module_id,
|
self.module_id,
|
||||||
&mut |map, module| map[module].scope.get_legacy_macro(name),
|
&mut |map, module| {
|
||||||
|
map[module]
|
||||||
|
.scope
|
||||||
|
.get_legacy_macro(name)
|
||||||
|
.map(|it| macro_id_to_def_id(self.def_collector.db, it.into()))
|
||||||
|
},
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
|
@ -389,7 +389,7 @@ impl DefMap {
|
||||||
let from_legacy_macro = self[module]
|
let from_legacy_macro = self[module]
|
||||||
.scope
|
.scope
|
||||||
.get_legacy_macro(name)
|
.get_legacy_macro(name)
|
||||||
.map_or_else(PerNs::none, |m| PerNs::macros(m, Visibility::Public));
|
.map_or_else(PerNs::none, |m| PerNs::macros(m.into(), Visibility::Public));
|
||||||
let from_scope = self[module].scope.get(name);
|
let from_scope = self[module].scope.get(name);
|
||||||
let from_builtin = match self.block {
|
let from_builtin = match self.block {
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
|
|
|
@ -6,13 +6,13 @@ use tt::{Leaf, TokenTree};
|
||||||
use crate::attr::Attrs;
|
use crate::attr::Attrs;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub(super) struct ProcMacroDef {
|
pub struct ProcMacroDef {
|
||||||
pub(super) name: Name,
|
pub name: Name,
|
||||||
pub(super) kind: ProcMacroKind,
|
pub kind: ProcMacroKind,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub(super) enum ProcMacroKind {
|
pub enum ProcMacroKind {
|
||||||
CustomDerive { helpers: Box<[Name]> },
|
CustomDerive { helpers: Box<[Name]> },
|
||||||
FnLike,
|
FnLike,
|
||||||
Attr,
|
Attr,
|
||||||
|
@ -30,7 +30,7 @@ impl ProcMacroKind {
|
||||||
|
|
||||||
impl Attrs {
|
impl Attrs {
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
pub(super) fn parse_proc_macro_decl(&self, func_name: &Name) -> Option<ProcMacroDef> {
|
pub fn parse_proc_macro_decl(&self, func_name: &Name) -> Option<ProcMacroDef> {
|
||||||
if self.is_proc_macro() {
|
if self.is_proc_macro() {
|
||||||
Some(ProcMacroDef { name: func_name.clone(), kind: ProcMacroKind::FnLike })
|
Some(ProcMacroDef { name: func_name.clone(), kind: ProcMacroKind::FnLike })
|
||||||
} else if self.is_proc_macro_attribute() {
|
} else if self.is_proc_macro_attribute() {
|
||||||
|
|
|
@ -226,6 +226,7 @@ pub type Ty = ();
|
||||||
ModuleDefId::TypeAliasId(it) => drop(db.type_alias_data(it)),
|
ModuleDefId::TypeAliasId(it) => drop(db.type_alias_data(it)),
|
||||||
ModuleDefId::EnumVariantId(_)
|
ModuleDefId::EnumVariantId(_)
|
||||||
| ModuleDefId::ModuleId(_)
|
| ModuleDefId::ModuleId(_)
|
||||||
|
| ModuleDefId::MacroId(_)
|
||||||
| ModuleDefId::BuiltinType(_) => unreachable!(),
|
| ModuleDefId::BuiltinType(_) => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
use crate::nameres::proc_macro::{ProcMacroDef, ProcMacroKind};
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn macro_rules_are_globally_visible() {
|
fn macro_rules_are_globally_visible() {
|
||||||
check(
|
check(
|
||||||
|
@ -978,14 +976,12 @@ fn collects_derive_helpers() {
|
||||||
",
|
",
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(def_map.exported_proc_macros.len(), 1);
|
assert_eq!(def_map.exported_derives.len(), 1);
|
||||||
match def_map.exported_proc_macros.values().next() {
|
match def_map.exported_derives.values().next() {
|
||||||
Some(ProcMacroDef { kind: ProcMacroKind::CustomDerive { helpers }, .. }) => {
|
Some(helpers) => match &**helpers {
|
||||||
match &**helpers {
|
|
||||||
[attr] => assert_eq!(attr.to_string(), "helper_attr"),
|
[attr] => assert_eq!(attr.to_string(), "helper_attr"),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
},
|
||||||
}
|
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,15 +3,13 @@
|
||||||
//!
|
//!
|
||||||
//! `PerNs` (per namespace) captures this.
|
//! `PerNs` (per namespace) captures this.
|
||||||
|
|
||||||
use hir_expand::MacroDefId;
|
use crate::{item_scope::ItemInNs, visibility::Visibility, MacroId, ModuleDefId};
|
||||||
|
|
||||||
use crate::{item_scope::ItemInNs, visibility::Visibility, ModuleDefId};
|
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct PerNs {
|
pub struct PerNs {
|
||||||
pub types: Option<(ModuleDefId, Visibility)>,
|
pub types: Option<(ModuleDefId, Visibility)>,
|
||||||
pub values: Option<(ModuleDefId, Visibility)>,
|
pub values: Option<(ModuleDefId, Visibility)>,
|
||||||
pub macros: Option<(MacroDefId, Visibility)>,
|
pub macros: Option<(MacroId, Visibility)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for PerNs {
|
impl Default for PerNs {
|
||||||
|
@ -37,7 +35,7 @@ impl PerNs {
|
||||||
PerNs { types: Some((types, v)), values: Some((values, v)), macros: None }
|
PerNs { types: Some((types, v)), values: Some((values, v)), macros: None }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn macros(macro_: MacroDefId, v: Visibility) -> PerNs {
|
pub fn macros(macro_: MacroId, v: Visibility) -> PerNs {
|
||||||
PerNs { types: None, values: None, macros: Some((macro_, v)) }
|
PerNs { types: None, values: None, macros: Some((macro_, v)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +55,7 @@ impl PerNs {
|
||||||
self.values.map(|it| it.0)
|
self.values.map(|it| it.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn take_macros(self) -> Option<MacroDefId> {
|
pub fn take_macros(self) -> Option<MacroId> {
|
||||||
self.macros.map(|it| it.0)
|
self.macros.map(|it| it.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,7 @@
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use base_db::CrateId;
|
use base_db::CrateId;
|
||||||
use hir_expand::{
|
use hir_expand::name::{name, Name};
|
||||||
name::{name, Name},
|
|
||||||
MacroDefId,
|
|
||||||
};
|
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use rustc_hash::FxHashSet;
|
use rustc_hash::FxHashSet;
|
||||||
use smallvec::{smallvec, SmallVec};
|
use smallvec::{smallvec, SmallVec};
|
||||||
|
@ -24,8 +21,8 @@ use crate::{
|
||||||
visibility::{RawVisibility, Visibility},
|
visibility::{RawVisibility, Visibility},
|
||||||
AdtId, AssocItemId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, ExternBlockId,
|
AdtId, AssocItemId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, ExternBlockId,
|
||||||
FunctionId, GenericDefId, GenericParamId, HasModule, ImplId, ItemContainerId, LifetimeParamId,
|
FunctionId, GenericDefId, GenericParamId, HasModule, ImplId, ItemContainerId, LifetimeParamId,
|
||||||
LocalModuleId, Lookup, ModuleDefId, ModuleId, StaticId, StructId, TraitId, TypeAliasId,
|
LocalModuleId, Lookup, Macro2Id, MacroId, MacroRulesId, ModuleDefId, ModuleId, ProcMacroId,
|
||||||
TypeOrConstParamId, TypeParamId, VariantId,
|
StaticId, StructId, TraitId, TypeAliasId, TypeOrConstParamId, TypeParamId, VariantId,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
|
@ -347,11 +344,7 @@ impl Resolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolve_path_as_macro(
|
pub fn resolve_path_as_macro(&self, db: &dyn DefDatabase, path: &ModPath) -> Option<MacroId> {
|
||||||
&self,
|
|
||||||
db: &dyn DefDatabase,
|
|
||||||
path: &ModPath,
|
|
||||||
) -> Option<MacroDefId> {
|
|
||||||
let (item_map, module) = self.module_scope()?;
|
let (item_map, module) = self.module_scope()?;
|
||||||
item_map.resolve_path(db, module, path, BuiltinShadowMode::Other).0.take_macros()
|
item_map.resolve_path(db, module, path, BuiltinShadowMode::Other).0.take_macros()
|
||||||
}
|
}
|
||||||
|
@ -485,7 +478,6 @@ impl Resolver {
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub enum ScopeDef {
|
pub enum ScopeDef {
|
||||||
ModuleDef(ModuleDefId),
|
ModuleDef(ModuleDefId),
|
||||||
MacroDef(MacroDefId),
|
|
||||||
Unknown,
|
Unknown,
|
||||||
ImplSelfType(ImplId),
|
ImplSelfType(ImplId),
|
||||||
AdtSelfType(AdtId),
|
AdtSelfType(AdtId),
|
||||||
|
@ -509,7 +501,7 @@ impl Scope {
|
||||||
acc.add_per_ns(name, def);
|
acc.add_per_ns(name, def);
|
||||||
});
|
});
|
||||||
m.def_map[m.module_id].scope.legacy_macros().for_each(|(name, mac)| {
|
m.def_map[m.module_id].scope.legacy_macros().for_each(|(name, mac)| {
|
||||||
acc.add(name, ScopeDef::MacroDef(mac));
|
acc.add(name, ScopeDef::ModuleDef(ModuleDefId::MacroId(MacroId::from(mac))));
|
||||||
});
|
});
|
||||||
m.def_map.extern_prelude().for_each(|(name, &def)| {
|
m.def_map.extern_prelude().for_each(|(name, &def)| {
|
||||||
acc.add(name, ScopeDef::ModuleDef(def));
|
acc.add(name, ScopeDef::ModuleDef(def));
|
||||||
|
@ -651,6 +643,7 @@ impl ModuleItemMap {
|
||||||
| ModuleDefId::FunctionId(_)
|
| ModuleDefId::FunctionId(_)
|
||||||
| ModuleDefId::EnumVariantId(_)
|
| ModuleDefId::EnumVariantId(_)
|
||||||
| ModuleDefId::ConstId(_)
|
| ModuleDefId::ConstId(_)
|
||||||
|
| ModuleDefId::MacroId(_)
|
||||||
| ModuleDefId::StaticId(_) => return None,
|
| ModuleDefId::StaticId(_) => return None,
|
||||||
};
|
};
|
||||||
Some(ResolveValueResult::Partial(ty, idx))
|
Some(ResolveValueResult::Partial(ty, idx))
|
||||||
|
@ -682,6 +675,7 @@ fn to_value_ns(per_ns: PerNs) -> Option<ValueNs> {
|
||||||
| ModuleDefId::TraitId(_)
|
| ModuleDefId::TraitId(_)
|
||||||
| ModuleDefId::TypeAliasId(_)
|
| ModuleDefId::TypeAliasId(_)
|
||||||
| ModuleDefId::BuiltinType(_)
|
| ModuleDefId::BuiltinType(_)
|
||||||
|
| ModuleDefId::MacroId(_)
|
||||||
| ModuleDefId::ModuleId(_) => return None,
|
| ModuleDefId::ModuleId(_) => return None,
|
||||||
};
|
};
|
||||||
Some(res)
|
Some(res)
|
||||||
|
@ -699,6 +693,7 @@ fn to_type_ns(per_ns: PerNs) -> Option<TypeNs> {
|
||||||
|
|
||||||
ModuleDefId::FunctionId(_)
|
ModuleDefId::FunctionId(_)
|
||||||
| ModuleDefId::ConstId(_)
|
| ModuleDefId::ConstId(_)
|
||||||
|
| ModuleDefId::MacroId(_)
|
||||||
| ModuleDefId::StaticId(_)
|
| ModuleDefId::StaticId(_)
|
||||||
| ModuleDefId::ModuleId(_) => return None,
|
| ModuleDefId::ModuleId(_) => return None,
|
||||||
};
|
};
|
||||||
|
@ -718,14 +713,14 @@ impl ScopeNames {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn add_per_ns(&mut self, name: &Name, def: PerNs) {
|
fn add_per_ns(&mut self, name: &Name, def: PerNs) {
|
||||||
if let Some(ty) = &def.types {
|
if let &Some((ty, _)) = &def.types {
|
||||||
self.add(name, ScopeDef::ModuleDef(ty.0))
|
self.add(name, ScopeDef::ModuleDef(ty))
|
||||||
}
|
}
|
||||||
if let Some(val) = &def.values {
|
if let &Some((def, _)) = &def.values {
|
||||||
self.add(name, ScopeDef::ModuleDef(val.0))
|
self.add(name, ScopeDef::ModuleDef(def))
|
||||||
}
|
}
|
||||||
if let Some(mac) = &def.macros {
|
if let &Some((mac, _)) = &def.macros {
|
||||||
self.add(name, ScopeDef::MacroDef(mac.0))
|
self.add(name, ScopeDef::ModuleDef(ModuleDefId::MacroId(mac)))
|
||||||
}
|
}
|
||||||
if def.is_none() {
|
if def.is_none() {
|
||||||
self.add(name, ScopeDef::Unknown)
|
self.add(name, ScopeDef::Unknown)
|
||||||
|
@ -869,3 +864,31 @@ impl HasResolver for VariantId {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl HasResolver for MacroId {
|
||||||
|
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
||||||
|
match self {
|
||||||
|
MacroId::Macro2Id(it) => it.resolver(db),
|
||||||
|
MacroId::MacroRulesId(it) => it.resolver(db),
|
||||||
|
MacroId::ProcMacroId(it) => it.resolver(db),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HasResolver for Macro2Id {
|
||||||
|
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
||||||
|
self.lookup(db).container.resolver(db)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HasResolver for ProcMacroId {
|
||||||
|
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
||||||
|
self.lookup(db).container.resolver(db)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HasResolver for MacroRulesId {
|
||||||
|
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
||||||
|
self.lookup(db).container.resolver(db)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -2,8 +2,12 @@
|
||||||
|
|
||||||
use hir_expand::InFile;
|
use hir_expand::InFile;
|
||||||
use la_arena::ArenaMap;
|
use la_arena::ArenaMap;
|
||||||
|
use syntax::ast;
|
||||||
|
|
||||||
use crate::{db::DefDatabase, item_tree::ItemTreeNode, AssocItemLoc, ItemLoc};
|
use crate::{
|
||||||
|
db::DefDatabase, item_tree::ItemTreeNode, AssocItemLoc, ItemLoc, Macro2Loc, MacroRulesLoc,
|
||||||
|
ProcMacroLoc,
|
||||||
|
};
|
||||||
|
|
||||||
pub trait HasSource {
|
pub trait HasSource {
|
||||||
type Value;
|
type Value;
|
||||||
|
@ -36,6 +40,45 @@ impl<N: ItemTreeNode> HasSource for ItemLoc<N> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl HasSource for Macro2Loc {
|
||||||
|
type Value = ast::MacroDef;
|
||||||
|
|
||||||
|
fn source(&self, db: &dyn DefDatabase) -> InFile<Self::Value> {
|
||||||
|
let tree = self.id.item_tree(db);
|
||||||
|
let ast_id_map = db.ast_id_map(self.id.file_id());
|
||||||
|
let root = db.parse_or_expand(self.id.file_id()).unwrap();
|
||||||
|
let node = &tree[self.id.value];
|
||||||
|
|
||||||
|
InFile::new(self.id.file_id(), ast_id_map.get(node.ast_id()).to_node(&root))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HasSource for MacroRulesLoc {
|
||||||
|
type Value = ast::MacroRules;
|
||||||
|
|
||||||
|
fn source(&self, db: &dyn DefDatabase) -> InFile<Self::Value> {
|
||||||
|
let tree = self.id.item_tree(db);
|
||||||
|
let ast_id_map = db.ast_id_map(self.id.file_id());
|
||||||
|
let root = db.parse_or_expand(self.id.file_id()).unwrap();
|
||||||
|
let node = &tree[self.id.value];
|
||||||
|
|
||||||
|
InFile::new(self.id.file_id(), ast_id_map.get(node.ast_id()).to_node(&root))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HasSource for ProcMacroLoc {
|
||||||
|
type Value = ast::Fn;
|
||||||
|
|
||||||
|
fn source(&self, db: &dyn DefDatabase) -> InFile<Self::Value> {
|
||||||
|
let tree = self.id.item_tree(db);
|
||||||
|
let ast_id_map = db.ast_id_map(self.id.file_id());
|
||||||
|
let root = db.parse_or_expand(self.id.file_id()).unwrap();
|
||||||
|
let node = &tree[self.id.value];
|
||||||
|
|
||||||
|
InFile::new(self.id.file_id(), ast_id_map.get(node.ast_id()).to_node(&root))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub trait HasChildSource<ChildId> {
|
pub trait HasChildSource<ChildId> {
|
||||||
type Value;
|
type Value;
|
||||||
fn child_source(&self, db: &dyn DefDatabase) -> InFile<ArenaMap<ChildId, Self::Value>>;
|
fn child_source(&self, db: &dyn DefDatabase) -> InFile<ArenaMap<ChildId, Self::Value>>;
|
||||||
|
|
|
@ -1,12 +1,8 @@
|
||||||
//! Builtin attributes.
|
//! Builtin attributes.
|
||||||
|
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use syntax::ast;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{db::AstDatabase, name, ExpandResult, MacroCallId, MacroCallKind};
|
||||||
db::AstDatabase, name, AstId, CrateId, ExpandResult, MacroCallId, MacroCallKind, MacroDefId,
|
|
||||||
MacroDefKind,
|
|
||||||
};
|
|
||||||
|
|
||||||
macro_rules! register_builtin {
|
macro_rules! register_builtin {
|
||||||
( $(($name:ident, $variant:ident) => $expand:ident),* ) => {
|
( $(($name:ident, $variant:ident) => $expand:ident),* ) => {
|
||||||
|
@ -61,17 +57,8 @@ register_builtin! {
|
||||||
(test_case, TestCase) => dummy_attr_expand
|
(test_case, TestCase) => dummy_attr_expand
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_builtin_attr(
|
pub fn find_builtin_attr(ident: &name::Name) -> Option<BuiltinAttrExpander> {
|
||||||
ident: &name::Name,
|
BuiltinAttrExpander::find_by_name(ident)
|
||||||
krate: CrateId,
|
|
||||||
ast_id: AstId<ast::Macro>,
|
|
||||||
) -> Option<MacroDefId> {
|
|
||||||
let expander = BuiltinAttrExpander::find_by_name(ident)?;
|
|
||||||
Some(MacroDefId {
|
|
||||||
krate,
|
|
||||||
kind: MacroDefKind::BuiltInAttr(expander, ast_id),
|
|
||||||
local_inner: false,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dummy_attr_expand(
|
fn dummy_attr_expand(
|
||||||
|
|
|
@ -8,10 +8,7 @@ use syntax::{
|
||||||
};
|
};
|
||||||
use tt::TokenId;
|
use tt::TokenId;
|
||||||
|
|
||||||
use crate::{
|
use crate::{db::AstDatabase, name, quote, ExpandError, ExpandResult, MacroCallId};
|
||||||
db::AstDatabase, name, quote, AstId, CrateId, ExpandError, ExpandResult, MacroCallId,
|
|
||||||
MacroDefId, MacroDefKind,
|
|
||||||
};
|
|
||||||
|
|
||||||
macro_rules! register_builtin {
|
macro_rules! register_builtin {
|
||||||
( $($trait:ident => $expand:ident),* ) => {
|
( $($trait:ident => $expand:ident),* ) => {
|
||||||
|
@ -56,17 +53,8 @@ register_builtin! {
|
||||||
PartialEq => partial_eq_expand
|
PartialEq => partial_eq_expand
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_builtin_derive(
|
pub fn find_builtin_derive(ident: &name::Name) -> Option<BuiltinDeriveExpander> {
|
||||||
ident: &name::Name,
|
BuiltinDeriveExpander::find_by_name(ident)
|
||||||
krate: CrateId,
|
|
||||||
ast_id: AstId<ast::Macro>,
|
|
||||||
) -> Option<MacroDefId> {
|
|
||||||
let expander = BuiltinDeriveExpander::find_by_name(ident)?;
|
|
||||||
Some(MacroDefId {
|
|
||||||
krate,
|
|
||||||
kind: MacroDefKind::BuiltInDerive(expander, ast_id),
|
|
||||||
local_inner: false,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct BasicAdtInfo {
|
struct BasicAdtInfo {
|
||||||
|
|
|
@ -9,10 +9,7 @@ use syntax::{
|
||||||
SmolStr,
|
SmolStr,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{db::AstDatabase, name, quote, ExpandError, ExpandResult, MacroCallId, MacroCallLoc};
|
||||||
db::AstDatabase, name, quote, AstId, CrateId, ExpandError, ExpandResult, MacroCallId,
|
|
||||||
MacroCallLoc, MacroDefId, MacroDefKind,
|
|
||||||
};
|
|
||||||
|
|
||||||
macro_rules! register_builtin {
|
macro_rules! register_builtin {
|
||||||
( LAZY: $(($name:ident, $kind: ident) => $expand:ident),* , EAGER: $(($e_name:ident, $e_kind: ident) => $e_expand:ident),* ) => {
|
( LAZY: $(($name:ident, $kind: ident) => $expand:ident),* , EAGER: $(($e_name:ident, $e_kind: ident) => $e_expand:ident),* ) => {
|
||||||
|
@ -79,23 +76,8 @@ impl ExpandedEager {
|
||||||
|
|
||||||
pub fn find_builtin_macro(
|
pub fn find_builtin_macro(
|
||||||
ident: &name::Name,
|
ident: &name::Name,
|
||||||
krate: CrateId,
|
) -> Option<Either<BuiltinFnLikeExpander, EagerExpander>> {
|
||||||
ast_id: AstId<ast::Macro>,
|
find_by_name(ident)
|
||||||
) -> Option<MacroDefId> {
|
|
||||||
let kind = find_by_name(ident)?;
|
|
||||||
|
|
||||||
match kind {
|
|
||||||
Either::Left(kind) => Some(MacroDefId {
|
|
||||||
krate,
|
|
||||||
kind: MacroDefKind::BuiltIn(kind, ast_id),
|
|
||||||
local_inner: false,
|
|
||||||
}),
|
|
||||||
Either::Right(kind) => Some(MacroDefId {
|
|
||||||
krate,
|
|
||||||
kind: MacroDefKind::BuiltInEager(kind, ast_id),
|
|
||||||
local_inner: false,
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
register_builtin! {
|
register_builtin! {
|
||||||
|
|
|
@ -180,7 +180,7 @@ impl<'a> DeclValidator<'a> {
|
||||||
AttrDefId::ImplId(iid) => Some(iid.lookup(self.db.upcast()).container.into()),
|
AttrDefId::ImplId(iid) => Some(iid.lookup(self.db.upcast()).container.into()),
|
||||||
AttrDefId::ExternBlockId(id) => Some(id.lookup(self.db.upcast()).container.into()),
|
AttrDefId::ExternBlockId(id) => Some(id.lookup(self.db.upcast()).container.into()),
|
||||||
// These warnings should not explore macro definitions at all
|
// These warnings should not explore macro definitions at all
|
||||||
AttrDefId::MacroDefId(_) => None,
|
AttrDefId::MacroId(_) => None,
|
||||||
AttrDefId::AdtId(aid) => match aid {
|
AttrDefId::AdtId(aid) => match aid {
|
||||||
AdtId::StructId(sid) => Some(sid.lookup(self.db.upcast()).container.into()),
|
AdtId::StructId(sid) => Some(sid.lookup(self.db.upcast()).container.into()),
|
||||||
AdtId::EnumId(eid) => Some(eid.lookup(self.db.upcast()).container.into()),
|
AdtId::EnumId(eid) => Some(eid.lookup(self.db.upcast()).container.into()),
|
||||||
|
|
|
@ -5,7 +5,6 @@ mod tests;
|
||||||
|
|
||||||
mod intra_doc_links;
|
mod intra_doc_links;
|
||||||
|
|
||||||
use either::Either;
|
|
||||||
use pulldown_cmark::{BrokenLink, CowStr, Event, InlineStr, LinkType, Options, Parser, Tag};
|
use pulldown_cmark::{BrokenLink, CowStr, Event, InlineStr, LinkType, Options, Parser, Tag};
|
||||||
use pulldown_cmark_to_cmark::{cmark_resume_with_options, Options as CMarkOptions};
|
use pulldown_cmark_to_cmark::{cmark_resume_with_options, Options as CMarkOptions};
|
||||||
use stdx::format_to;
|
use stdx::format_to;
|
||||||
|
@ -173,7 +172,7 @@ pub(crate) fn resolve_doc_path_for_def(
|
||||||
link: &str,
|
link: &str,
|
||||||
ns: Option<hir::Namespace>,
|
ns: Option<hir::Namespace>,
|
||||||
) -> Option<Definition> {
|
) -> Option<Definition> {
|
||||||
let def = match def {
|
match def {
|
||||||
Definition::Module(it) => it.resolve_doc_path(db, link, ns),
|
Definition::Module(it) => it.resolve_doc_path(db, link, ns),
|
||||||
Definition::Function(it) => it.resolve_doc_path(db, link, ns),
|
Definition::Function(it) => it.resolve_doc_path(db, link, ns),
|
||||||
Definition::Adt(it) => it.resolve_doc_path(db, link, ns),
|
Definition::Adt(it) => it.resolve_doc_path(db, link, ns),
|
||||||
|
@ -191,11 +190,8 @@ pub(crate) fn resolve_doc_path_for_def(
|
||||||
| Definition::Local(_)
|
| Definition::Local(_)
|
||||||
| Definition::GenericParam(_)
|
| Definition::GenericParam(_)
|
||||||
| Definition::Label(_) => None,
|
| Definition::Label(_) => None,
|
||||||
}?;
|
|
||||||
match def {
|
|
||||||
Either::Left(def) => Some(Definition::from(def)),
|
|
||||||
Either::Right(def) => Some(Definition::Macro(def)),
|
|
||||||
}
|
}
|
||||||
|
.map(Definition::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn doc_attributes(
|
pub(crate) fn doc_attributes(
|
||||||
|
@ -476,7 +472,7 @@ fn filename_and_frag_for_def(
|
||||||
}
|
}
|
||||||
Definition::Const(c) => format!("const.{}.html", c.name(db)?),
|
Definition::Const(c) => format!("const.{}.html", c.name(db)?),
|
||||||
Definition::Static(s) => format!("static.{}.html", s.name(db)),
|
Definition::Static(s) => format!("static.{}.html", s.name(db)),
|
||||||
Definition::Macro(mac) => format!("macro.{}.html", mac.name(db)?),
|
Definition::Macro(mac) => format!("macro.{}.html", mac.name(db)),
|
||||||
Definition::Field(field) => {
|
Definition::Field(field) => {
|
||||||
let def = match field.parent_def(db) {
|
let def = match field.parent_def(db) {
|
||||||
hir::VariantDef::Struct(it) => Definition::Adt(it.into()),
|
hir::VariantDef::Struct(it) => Definition::Adt(it.into()),
|
||||||
|
|
|
@ -75,7 +75,7 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<
|
||||||
for node in tok.ancestors() {
|
for node in tok.ancestors() {
|
||||||
if let Some(item) = ast::Item::cast(node.clone()) {
|
if let Some(item) = ast::Item::cast(node.clone()) {
|
||||||
if let Some(def) = sema.resolve_attr_macro_call(&item) {
|
if let Some(def) = sema.resolve_attr_macro_call(&item) {
|
||||||
name = def.name(db).map(|name| name.to_string());
|
name = Some(def.name(db).to_string());
|
||||||
expanded = expand_attr_macro_recur(&sema, &item);
|
expanded = expand_attr_macro_recur(&sema, &item);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4151,7 +4151,7 @@ struct Foo;
|
||||||
*Copy*
|
*Copy*
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
test
|
test::foo
|
||||||
```
|
```
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
|
|
|
@ -211,6 +211,7 @@ impl TryToNav for hir::ModuleDef {
|
||||||
hir::ModuleDef::Static(it) => it.try_to_nav(db),
|
hir::ModuleDef::Static(it) => it.try_to_nav(db),
|
||||||
hir::ModuleDef::Trait(it) => it.try_to_nav(db),
|
hir::ModuleDef::Trait(it) => it.try_to_nav(db),
|
||||||
hir::ModuleDef::TypeAlias(it) => it.try_to_nav(db),
|
hir::ModuleDef::TypeAlias(it) => it.try_to_nav(db),
|
||||||
|
hir::ModuleDef::Macro(it) => it.try_to_nav(db),
|
||||||
hir::ModuleDef::BuiltinType(_) => None,
|
hir::ModuleDef::BuiltinType(_) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -332,7 +333,7 @@ impl TryToNav for hir::Field {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryToNav for hir::MacroDef {
|
impl TryToNav for hir::Macro {
|
||||||
fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> {
|
fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> {
|
||||||
let src = self.source(db)?;
|
let src = self.source(db)?;
|
||||||
let name_owner: &dyn ast::HasName = match &src.value {
|
let name_owner: &dyn ast::HasName = match &src.value {
|
||||||
|
@ -343,7 +344,7 @@ impl TryToNav for hir::MacroDef {
|
||||||
let mut res = NavigationTarget::from_named(
|
let mut res = NavigationTarget::from_named(
|
||||||
db,
|
db,
|
||||||
src.as_ref().with_value(name_owner),
|
src.as_ref().with_value(name_owner),
|
||||||
self.kind().into(),
|
self.kind(db).into(),
|
||||||
);
|
);
|
||||||
res.docs = self.docs(db);
|
res.docs = self.docs(db);
|
||||||
Some(res)
|
Some(res)
|
||||||
|
|
|
@ -320,7 +320,7 @@ fn highlight_def(
|
||||||
) -> Highlight {
|
) -> Highlight {
|
||||||
let db = sema.db;
|
let db = sema.db;
|
||||||
let mut h = match def {
|
let mut h = match def {
|
||||||
Definition::Macro(m) => Highlight::new(HlTag::Symbol(m.kind().into())),
|
Definition::Macro(m) => Highlight::new(HlTag::Symbol(m.kind(sema.db).into())),
|
||||||
Definition::Field(_) => Highlight::new(HlTag::Symbol(SymbolKind::Field)),
|
Definition::Field(_) => Highlight::new(HlTag::Symbol(SymbolKind::Field)),
|
||||||
Definition::Module(module) => {
|
Definition::Module(module) => {
|
||||||
let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Module));
|
let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Module));
|
||||||
|
|
|
@ -130,9 +130,6 @@ impl Ref {
|
||||||
ScopeDef::ModuleDef(def) => {
|
ScopeDef::ModuleDef(def) => {
|
||||||
Some(Ref { visible_name: name, def: Definition::from(def) })
|
Some(Ref { visible_name: name, def: Definition::from(def) })
|
||||||
}
|
}
|
||||||
ScopeDef::MacroDef(def) => {
|
|
||||||
Some(Ref { visible_name: name, def: Definition::Macro(def) })
|
|
||||||
}
|
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -199,6 +199,8 @@ fn target_data_for_def(
|
||||||
let syntax = in_file_source.value.syntax();
|
let syntax = in_file_source.value.syntax();
|
||||||
(vis_offset(syntax), in_file_source.value.visibility(), syntax.text_range(), file_id)
|
(vis_offset(syntax), in_file_source.value.visibility(), syntax.text_range(), file_id)
|
||||||
}
|
}
|
||||||
|
// FIXME
|
||||||
|
hir::ModuleDef::Macro(_) => return None,
|
||||||
// Enum variants can't be private, we can't modify builtin types
|
// Enum variants can't be private, we can't modify builtin types
|
||||||
hir::ModuleDef::Variant(_) | hir::ModuleDef::BuiltinType(_) => return None,
|
hir::ModuleDef::Variant(_) | hir::ModuleDef::BuiltinType(_) => return None,
|
||||||
};
|
};
|
||||||
|
|
|
@ -44,7 +44,6 @@ pub(crate) fn replace_qualified_name_with_use(
|
||||||
// only offer replacement for non assoc items
|
// only offer replacement for non assoc items
|
||||||
match ctx.sema.resolve_path(&path)? {
|
match ctx.sema.resolve_path(&path)? {
|
||||||
hir::PathResolution::Def(def) if def.as_assoc_item(ctx.sema.db).is_none() => (),
|
hir::PathResolution::Def(def) if def.as_assoc_item(ctx.sema.db).is_none() => (),
|
||||||
hir::PathResolution::Macro(_) => (),
|
|
||||||
_ => return None,
|
_ => return None,
|
||||||
}
|
}
|
||||||
// then search for an import for the first path segment of what we want to replace
|
// then search for an import for the first path segment of what we want to replace
|
||||||
|
|
|
@ -21,7 +21,7 @@ pub(crate) mod vis;
|
||||||
|
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
|
||||||
use hir::{known, ScopeDef};
|
use hir::{db::HirDatabase, known, ScopeDef};
|
||||||
use ide_db::SymbolKind;
|
use ide_db::SymbolKind;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -40,17 +40,17 @@ use crate::{
|
||||||
CompletionContext, CompletionItem, CompletionItemKind,
|
CompletionContext, CompletionItem, CompletionItemKind,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn module_or_attr(def: ScopeDef) -> Option<ScopeDef> {
|
fn module_or_attr(db: &dyn HirDatabase, def: ScopeDef) -> Option<ScopeDef> {
|
||||||
match def {
|
match def {
|
||||||
ScopeDef::MacroDef(mac) if mac.is_attr() => Some(def),
|
ScopeDef::ModuleDef(hir::ModuleDef::Macro(m)) if m.is_attr(db) => Some(def),
|
||||||
ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) => Some(def),
|
ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) => Some(def),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn module_or_fn_macro(def: ScopeDef) -> Option<ScopeDef> {
|
fn module_or_fn_macro(db: &dyn HirDatabase, def: ScopeDef) -> Option<ScopeDef> {
|
||||||
match def {
|
match def {
|
||||||
ScopeDef::MacroDef(mac) if mac.is_fn_like() => Some(def),
|
ScopeDef::ModuleDef(hir::ModuleDef::Macro(m)) if m.is_fn_like(db) => Some(def),
|
||||||
ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) => Some(def),
|
ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) => Some(def),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,7 +93,7 @@ pub(crate) fn complete_attribute(acc: &mut Completions, ctx: &CompletionContext)
|
||||||
};
|
};
|
||||||
|
|
||||||
for (name, def) in module.scope(ctx.db, ctx.module) {
|
for (name, def) in module.scope(ctx.db, ctx.module) {
|
||||||
if let Some(def) = module_or_attr(def) {
|
if let Some(def) = module_or_attr(ctx.db, def) {
|
||||||
acc.add_resolution(ctx, name, def);
|
acc.add_resolution(ctx, name, def);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,7 +104,7 @@ pub(crate) fn complete_attribute(acc: &mut Completions, ctx: &CompletionContext)
|
||||||
// only show modules in a fresh UseTree
|
// only show modules in a fresh UseTree
|
||||||
None => {
|
None => {
|
||||||
ctx.process_all_names(&mut |name, def| {
|
ctx.process_all_names(&mut |name, def| {
|
||||||
if let Some(def) = module_or_attr(def) {
|
if let Some(def) = module_or_attr(ctx.db, def) {
|
||||||
acc.add_resolution(ctx, name, def);
|
acc.add_resolution(ctx, name, def);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//! Completion for derives
|
//! Completion for derives
|
||||||
use hir::{HasAttrs, MacroDef, MacroKind};
|
use hir::{HasAttrs, Macro, MacroKind};
|
||||||
use ide_db::{
|
use ide_db::{
|
||||||
imports::{import_assets::ImportAssets, insert_use::ImportScope},
|
imports::{import_assets::ImportAssets, insert_use::ImportScope},
|
||||||
SymbolKind,
|
SymbolKind,
|
||||||
|
@ -24,9 +24,9 @@ pub(super) fn complete_derive(acc: &mut Completions, ctx: &CompletionContext, at
|
||||||
}
|
}
|
||||||
|
|
||||||
let name = name.to_smol_str();
|
let name = name.to_smol_str();
|
||||||
let (label, lookup) = match core.zip(mac.module(ctx.db).map(|it| it.krate())) {
|
let (label, lookup) = match (core, mac.module(ctx.db).krate()) {
|
||||||
// show derive dependencies for `core`/`std` derives
|
// show derive dependencies for `core`/`std` derives
|
||||||
Some((core, mac_krate)) if core == mac_krate => {
|
(Some(core), mac_krate) if core == mac_krate => {
|
||||||
if let Some(derive_completion) = DEFAULT_DERIVE_DEPENDENCIES
|
if let Some(derive_completion) = DEFAULT_DERIVE_DEPENDENCIES
|
||||||
.iter()
|
.iter()
|
||||||
.find(|derive_completion| derive_completion.label == name)
|
.find(|derive_completion| derive_completion.label == name)
|
||||||
|
@ -36,7 +36,7 @@ pub(super) fn complete_derive(acc: &mut Completions, ctx: &CompletionContext, at
|
||||||
|&&dependency| {
|
|&&dependency| {
|
||||||
!existing_derives
|
!existing_derives
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|it| it.name(ctx.db))
|
.map(|it| it.name(ctx.db))
|
||||||
.any(|it| it.to_smol_str() == dependency)
|
.any(|it| it.to_smol_str() == dependency)
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
|
@ -63,11 +63,11 @@ pub(super) fn complete_derive(acc: &mut Completions, ctx: &CompletionContext, at
|
||||||
flyimport_derive(acc, ctx);
|
flyimport_derive(acc, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_derives_in_scope(ctx: &CompletionContext) -> Vec<(hir::Name, MacroDef)> {
|
fn get_derives_in_scope(ctx: &CompletionContext) -> Vec<(hir::Name, Macro)> {
|
||||||
let mut result = Vec::default();
|
let mut result = Vec::default();
|
||||||
ctx.process_all_names(&mut |name, scope_def| {
|
ctx.process_all_names(&mut |name, scope_def| {
|
||||||
if let hir::ScopeDef::MacroDef(mac) = scope_def {
|
if let hir::ScopeDef::ModuleDef(hir::ModuleDef::Macro(mac)) = scope_def {
|
||||||
if mac.kind() == hir::MacroKind::Derive {
|
if mac.kind(ctx.db) == hir::MacroKind::Derive {
|
||||||
result.push((name, mac));
|
result.push((name, mac));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,7 @@ fn flyimport_derive(acc: &mut Completions, ctx: &CompletionContext) -> Option<()
|
||||||
hir::ItemInNs::Macros(mac) => Some((import, mac)),
|
hir::ItemInNs::Macros(mac) => Some((import, mac)),
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
.filter(|&(_, mac)| mac.kind() == MacroKind::Derive)
|
.filter(|&(_, mac)| mac.kind(ctx.db) == MacroKind::Derive)
|
||||||
.filter(|&(_, mac)| !ctx.is_item_hidden(&hir::ItemInNs::Macros(mac)))
|
.filter(|&(_, mac)| !ctx.is_item_hidden(&hir::ItemInNs::Macros(mac)))
|
||||||
.sorted_by_key(|(import, _)| {
|
.sorted_by_key(|(import, _)| {
|
||||||
compute_fuzzy_completion_order_key(&import.import_path, &user_input_lowercased)
|
compute_fuzzy_completion_order_key(&import.import_path, &user_input_lowercased)
|
||||||
|
@ -108,7 +108,7 @@ fn flyimport_derive(acc: &mut Completions, ctx: &CompletionContext) -> Option<()
|
||||||
let mut item = CompletionItem::new(
|
let mut item = CompletionItem::new(
|
||||||
SymbolKind::Derive,
|
SymbolKind::Derive,
|
||||||
ctx.source_range(),
|
ctx.source_range(),
|
||||||
mac.name(ctx.db)?.to_smol_str(),
|
mac.name(ctx.db).to_smol_str(),
|
||||||
);
|
);
|
||||||
item.add_import(ImportEdit { import, scope: import_scope.clone() });
|
item.add_import(ImportEdit { import, scope: import_scope.clone() });
|
||||||
if let Some(docs) = mac.docs(ctx.db) {
|
if let Some(docs) = mac.docs(ctx.db) {
|
||||||
|
|
|
@ -146,7 +146,7 @@ pub(crate) fn import_on_the_fly(acc: &mut Completions, ctx: &CompletionContext)
|
||||||
Some(kind) => kind,
|
Some(kind) => kind,
|
||||||
None => {
|
None => {
|
||||||
return match import.original_item {
|
return match import.original_item {
|
||||||
ItemInNs::Macros(mac) => mac.is_fn_like(),
|
ItemInNs::Macros(mac) => mac.is_fn_like(ctx.db),
|
||||||
_ => true,
|
_ => true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -160,7 +160,7 @@ pub(crate) fn import_on_the_fly(acc: &mut Completions, ctx: &CompletionContext)
|
||||||
(
|
(
|
||||||
PathKind::Expr | PathKind::Type | PathKind::Mac | PathKind::Pat,
|
PathKind::Expr | PathKind::Type | PathKind::Mac | PathKind::Pat,
|
||||||
ItemInNs::Macros(mac),
|
ItemInNs::Macros(mac),
|
||||||
) => mac.is_fn_like(),
|
) => mac.is_fn_like(ctx.db),
|
||||||
(PathKind::Mac, _) => true,
|
(PathKind::Mac, _) => true,
|
||||||
|
|
||||||
(PathKind::Expr, ItemInNs::Types(_) | ItemInNs::Values(_)) => true,
|
(PathKind::Expr, ItemInNs::Types(_) | ItemInNs::Values(_)) => true,
|
||||||
|
@ -171,7 +171,7 @@ pub(crate) fn import_on_the_fly(acc: &mut Completions, ctx: &CompletionContext)
|
||||||
(PathKind::Type, ItemInNs::Types(_)) => true,
|
(PathKind::Type, ItemInNs::Types(_)) => true,
|
||||||
(PathKind::Type, ItemInNs::Values(_)) => false,
|
(PathKind::Type, ItemInNs::Values(_)) => false,
|
||||||
|
|
||||||
(PathKind::Attr { .. }, ItemInNs::Macros(mac)) => mac.is_attr(),
|
(PathKind::Attr { .. }, ItemInNs::Macros(mac)) => mac.is_attr(ctx.db),
|
||||||
(PathKind::Attr { .. }, _) => false,
|
(PathKind::Attr { .. }, _) => false,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -77,9 +77,9 @@ pub(crate) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) {
|
||||||
}
|
}
|
||||||
hir::ModuleDef::Adt(hir::Adt::Enum(e)) => refutable || single_variant_enum(e),
|
hir::ModuleDef::Adt(hir::Adt::Enum(e)) => refutable || single_variant_enum(e),
|
||||||
hir::ModuleDef::Const(..) | hir::ModuleDef::Module(..) => refutable,
|
hir::ModuleDef::Const(..) | hir::ModuleDef::Module(..) => refutable,
|
||||||
|
hir::ModuleDef::Macro(mac) => mac.is_fn_like(ctx.db),
|
||||||
_ => false,
|
_ => false,
|
||||||
},
|
},
|
||||||
hir::ScopeDef::MacroDef(mac) => mac.is_fn_like(),
|
|
||||||
hir::ScopeDef::ImplSelfType(impl_) => match impl_.self_ty(ctx.db).as_adt() {
|
hir::ScopeDef::ImplSelfType(impl_) => match impl_.self_ty(ctx.db).as_adt() {
|
||||||
Some(hir::Adt::Struct(strukt)) => {
|
Some(hir::Adt::Struct(strukt)) => {
|
||||||
acc.add_struct_pat(ctx, strukt, Some(name.clone()));
|
acc.add_struct_pat(ctx, strukt, Some(name.clone()));
|
||||||
|
@ -117,7 +117,9 @@ fn pattern_path_completion(
|
||||||
let module_scope = module.scope(ctx.db, ctx.module);
|
let module_scope = module.scope(ctx.db, ctx.module);
|
||||||
for (name, def) in module_scope {
|
for (name, def) in module_scope {
|
||||||
let add_resolution = match def {
|
let add_resolution = match def {
|
||||||
ScopeDef::MacroDef(m) if m.is_fn_like() => true,
|
ScopeDef::ModuleDef(hir::ModuleDef::Macro(mac)) => {
|
||||||
|
mac.is_fn_like(ctx.db)
|
||||||
|
}
|
||||||
ScopeDef::ModuleDef(_) => true,
|
ScopeDef::ModuleDef(_) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
|
|
|
@ -52,7 +52,7 @@ pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon
|
||||||
Some(ImmediateLocation::ItemList | ImmediateLocation::Trait | ImmediateLocation::Impl) => {
|
Some(ImmediateLocation::ItemList | ImmediateLocation::Trait | ImmediateLocation::Impl) => {
|
||||||
if let hir::PathResolution::Def(hir::ModuleDef::Module(module)) = resolution {
|
if let hir::PathResolution::Def(hir::ModuleDef::Module(module)) = resolution {
|
||||||
for (name, def) in module.scope(ctx.db, ctx.module) {
|
for (name, def) in module.scope(ctx.db, ctx.module) {
|
||||||
if let Some(def) = module_or_fn_macro(def) {
|
if let Some(def) = module_or_fn_macro(ctx.db, def) {
|
||||||
acc.add_resolution(ctx, name, def);
|
acc.add_resolution(ctx, name, def);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,7 @@ pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon
|
||||||
for (name, def) in module_scope {
|
for (name, def) in module_scope {
|
||||||
let add_resolution = match def {
|
let add_resolution = match def {
|
||||||
// Don't suggest attribute macros and derives.
|
// Don't suggest attribute macros and derives.
|
||||||
ScopeDef::MacroDef(mac) => mac.is_fn_like(),
|
ScopeDef::ModuleDef(hir::ModuleDef::Macro(mac)) => mac.is_fn_like(ctx.db),
|
||||||
// no values in type places
|
// no values in type places
|
||||||
ScopeDef::ModuleDef(
|
ScopeDef::ModuleDef(
|
||||||
hir::ModuleDef::Function(_)
|
hir::ModuleDef::Function(_)
|
||||||
|
|
|
@ -36,7 +36,7 @@ pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC
|
||||||
Some(ImmediateLocation::ItemList | ImmediateLocation::Trait | ImmediateLocation::Impl) => {
|
Some(ImmediateLocation::ItemList | ImmediateLocation::Trait | ImmediateLocation::Impl) => {
|
||||||
// only show macros in {Assoc}ItemList
|
// only show macros in {Assoc}ItemList
|
||||||
ctx.process_all_names(&mut |name, def| {
|
ctx.process_all_names(&mut |name, def| {
|
||||||
if let Some(def) = module_or_fn_macro(def) {
|
if let Some(def) = module_or_fn_macro(ctx.db, def) {
|
||||||
acc.add_resolution(ctx, name, def);
|
acc.add_resolution(ctx, name, def);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -45,7 +45,7 @@ pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC
|
||||||
Some(ImmediateLocation::TypeBound) => {
|
Some(ImmediateLocation::TypeBound) => {
|
||||||
ctx.process_all_names(&mut |name, res| {
|
ctx.process_all_names(&mut |name, res| {
|
||||||
let add_resolution = match res {
|
let add_resolution = match res {
|
||||||
ScopeDef::MacroDef(mac) => mac.is_fn_like(),
|
ScopeDef::ModuleDef(hir::ModuleDef::Macro(mac)) => mac.is_fn_like(ctx.db),
|
||||||
ScopeDef::ModuleDef(hir::ModuleDef::Trait(_) | hir::ModuleDef::Module(_)) => {
|
ScopeDef::ModuleDef(hir::ModuleDef::Trait(_) | hir::ModuleDef::Module(_)) => {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
@ -94,7 +94,7 @@ pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC
|
||||||
!ctx.previous_token_is(syntax::T![impl]) && !ctx.previous_token_is(syntax::T![for])
|
!ctx.previous_token_is(syntax::T![impl]) && !ctx.previous_token_is(syntax::T![for])
|
||||||
}
|
}
|
||||||
// Don't suggest attribute macros and derives.
|
// Don't suggest attribute macros and derives.
|
||||||
ScopeDef::MacroDef(mac) => mac.is_fn_like(),
|
ScopeDef::ModuleDef(hir::ModuleDef::Macro(mac)) => mac.is_fn_like(ctx.db),
|
||||||
// no values in type places
|
// no values in type places
|
||||||
ScopeDef::ModuleDef(
|
ScopeDef::ModuleDef(
|
||||||
hir::ModuleDef::Function(_)
|
hir::ModuleDef::Function(_)
|
||||||
|
|
|
@ -56,9 +56,7 @@ pub(crate) fn complete_use_tree(acc: &mut Completions, ctx: &CompletionContext)
|
||||||
cov_mark::hit!(dont_complete_current_use);
|
cov_mark::hit!(dont_complete_current_use);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ScopeDef::ModuleDef(_) | ScopeDef::MacroDef(_) | ScopeDef::Unknown => {
|
ScopeDef::ModuleDef(_) | ScopeDef::Unknown => true,
|
||||||
true
|
|
||||||
}
|
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -171,7 +171,9 @@ fn render_resolution_(
|
||||||
ScopeDef::ModuleDef(Variant(var)) if ctx.completion.pattern_ctx.is_none() => {
|
ScopeDef::ModuleDef(Variant(var)) if ctx.completion.pattern_ctx.is_none() => {
|
||||||
return render_variant(ctx, import_to_add, Some(local_name), var, None);
|
return render_variant(ctx, import_to_add, Some(local_name), var, None);
|
||||||
}
|
}
|
||||||
ScopeDef::MacroDef(mac) => return render_macro(ctx, import_to_add, local_name, mac),
|
ScopeDef::ModuleDef(Macro(mac)) => {
|
||||||
|
return render_macro(ctx, import_to_add, local_name, mac)
|
||||||
|
}
|
||||||
ScopeDef::Unknown => {
|
ScopeDef::Unknown => {
|
||||||
let mut item = CompletionItem::new(
|
let mut item = CompletionItem::new(
|
||||||
CompletionItemKind::UnresolvedReference,
|
CompletionItemKind::UnresolvedReference,
|
||||||
|
@ -274,7 +276,6 @@ fn scope_def_docs(db: &RootDatabase, resolution: ScopeDef) -> Option<hir::Docume
|
||||||
fn scope_def_is_deprecated(ctx: &RenderContext<'_>, resolution: ScopeDef) -> bool {
|
fn scope_def_is_deprecated(ctx: &RenderContext<'_>, resolution: ScopeDef) -> bool {
|
||||||
match resolution {
|
match resolution {
|
||||||
ScopeDef::ModuleDef(it) => ctx.is_deprecated_assoc_item(it),
|
ScopeDef::ModuleDef(it) => ctx.is_deprecated_assoc_item(it),
|
||||||
ScopeDef::MacroDef(it) => ctx.is_deprecated(it),
|
|
||||||
ScopeDef::GenericParam(it) => ctx.is_deprecated(it),
|
ScopeDef::GenericParam(it) => ctx.is_deprecated(it),
|
||||||
ScopeDef::AdtSelfType(it) => ctx.is_deprecated(it),
|
ScopeDef::AdtSelfType(it) => ctx.is_deprecated(it),
|
||||||
_ => false,
|
_ => false,
|
||||||
|
|
|
@ -18,7 +18,7 @@ pub(crate) fn render_macro(
|
||||||
ctx: RenderContext<'_>,
|
ctx: RenderContext<'_>,
|
||||||
import_to_add: Option<ImportEdit>,
|
import_to_add: Option<ImportEdit>,
|
||||||
name: hir::Name,
|
name: hir::Name,
|
||||||
macro_: hir::MacroDef,
|
macro_: hir::Macro,
|
||||||
) -> CompletionItem {
|
) -> CompletionItem {
|
||||||
let _p = profile::span("render_macro");
|
let _p = profile::span("render_macro");
|
||||||
render(ctx, name, macro_, import_to_add)
|
render(ctx, name, macro_, import_to_add)
|
||||||
|
@ -27,7 +27,7 @@ pub(crate) fn render_macro(
|
||||||
fn render(
|
fn render(
|
||||||
ctx @ RenderContext { completion, .. }: RenderContext<'_>,
|
ctx @ RenderContext { completion, .. }: RenderContext<'_>,
|
||||||
name: hir::Name,
|
name: hir::Name,
|
||||||
macro_: hir::MacroDef,
|
macro_: hir::Macro,
|
||||||
import_to_add: Option<ImportEdit>,
|
import_to_add: Option<ImportEdit>,
|
||||||
) -> CompletionItem {
|
) -> CompletionItem {
|
||||||
let source_range = if completion.is_immediately_after_macro_bang() {
|
let source_range = if completion.is_immediately_after_macro_bang() {
|
||||||
|
@ -40,14 +40,14 @@ fn render(
|
||||||
let name = name.to_smol_str();
|
let name = name.to_smol_str();
|
||||||
let docs = ctx.docs(macro_);
|
let docs = ctx.docs(macro_);
|
||||||
let docs_str = docs.as_ref().map(Documentation::as_str).unwrap_or_default();
|
let docs_str = docs.as_ref().map(Documentation::as_str).unwrap_or_default();
|
||||||
let (bra, ket) =
|
let is_fn_like = macro_.is_fn_like(completion.db);
|
||||||
if macro_.is_fn_like() { guess_macro_braces(&name, docs_str) } else { ("", "") };
|
let (bra, ket) = if is_fn_like { guess_macro_braces(&name, docs_str) } else { ("", "") };
|
||||||
|
|
||||||
let needs_bang = macro_.is_fn_like()
|
let needs_bang =
|
||||||
&& !matches!(completion.path_kind(), Some(PathKind::Mac | PathKind::Use));
|
is_fn_like && !matches!(completion.path_kind(), Some(PathKind::Mac | PathKind::Use));
|
||||||
|
|
||||||
let mut item = CompletionItem::new(
|
let mut item = CompletionItem::new(
|
||||||
SymbolKind::from(macro_.kind()),
|
SymbolKind::from(macro_.kind(completion.db)),
|
||||||
source_range,
|
source_range,
|
||||||
label(&ctx, needs_bang, bra, ket, &name),
|
label(&ctx, needs_bang, bra, ket, &name),
|
||||||
);
|
);
|
||||||
|
@ -103,7 +103,7 @@ fn banged_name(name: &str) -> SmolStr {
|
||||||
SmolStr::from_iter([name, "!"])
|
SmolStr::from_iter([name, "!"])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn detail(sema: &Semantics<RootDatabase>, macro_: hir::MacroDef) -> Option<String> {
|
fn detail(sema: &Semantics<RootDatabase>, macro_: hir::Macro) -> Option<String> {
|
||||||
// FIXME: This is parsing the file!
|
// FIXME: This is parsing the file!
|
||||||
let InFile { file_id, value } = macro_.source(sema.db)?;
|
let InFile { file_id, value } = macro_.source(sema.db)?;
|
||||||
let _ = sema.parse_or_expand(file_id);
|
let _ = sema.parse_or_expand(file_id);
|
||||||
|
|
|
@ -181,7 +181,6 @@ fn import_edits(
|
||||||
let resolve = |import: &GreenNode| {
|
let resolve = |import: &GreenNode| {
|
||||||
let path = ast::Path::cast(SyntaxNode::new_root(import.clone()))?;
|
let path = ast::Path::cast(SyntaxNode::new_root(import.clone()))?;
|
||||||
let item = match ctx.scope.speculative_resolve(&path)? {
|
let item = match ctx.scope.speculative_resolve(&path)? {
|
||||||
hir::PathResolution::Macro(mac) => mac.into(),
|
|
||||||
hir::PathResolution::Def(def) => def.into(),
|
hir::PathResolution::Def(def) => def.into(),
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
use arrayvec::ArrayVec;
|
use arrayvec::ArrayVec;
|
||||||
use hir::{
|
use hir::{
|
||||||
Adt, AsAssocItem, AssocItem, BuiltinAttr, BuiltinType, Const, Field, Function, GenericParam,
|
Adt, AsAssocItem, AssocItem, BuiltinAttr, BuiltinType, Const, Field, Function, GenericParam,
|
||||||
HasVisibility, Impl, ItemInNs, Label, Local, MacroDef, Module, ModuleDef, Name, PathResolution,
|
HasVisibility, Impl, ItemInNs, Label, Local, Macro, Module, ModuleDef, Name, PathResolution,
|
||||||
Semantics, Static, ToolModule, Trait, TypeAlias, Variant, Visibility,
|
Semantics, Static, ToolModule, Trait, TypeAlias, Variant, Visibility,
|
||||||
};
|
};
|
||||||
use stdx::impl_from;
|
use stdx::impl_from;
|
||||||
|
@ -22,7 +22,7 @@ use crate::RootDatabase;
|
||||||
// FIXME: a more precise name would probably be `Symbol`?
|
// FIXME: a more precise name would probably be `Symbol`?
|
||||||
#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)]
|
#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)]
|
||||||
pub enum Definition {
|
pub enum Definition {
|
||||||
Macro(MacroDef),
|
Macro(Macro),
|
||||||
Field(Field),
|
Field(Field),
|
||||||
Module(Module),
|
Module(Module),
|
||||||
Function(Function),
|
Function(Function),
|
||||||
|
@ -48,7 +48,7 @@ impl Definition {
|
||||||
|
|
||||||
pub fn module(&self, db: &RootDatabase) -> Option<Module> {
|
pub fn module(&self, db: &RootDatabase) -> Option<Module> {
|
||||||
let module = match self {
|
let module = match self {
|
||||||
Definition::Macro(it) => it.module(db)?,
|
Definition::Macro(it) => it.module(db),
|
||||||
Definition::Module(it) => it.parent(db)?,
|
Definition::Module(it) => it.parent(db)?,
|
||||||
Definition::Field(it) => it.parent_def(db).module(db),
|
Definition::Field(it) => it.parent_def(db).module(db),
|
||||||
Definition::Function(it) => it.module(db),
|
Definition::Function(it) => it.module(db),
|
||||||
|
@ -94,7 +94,7 @@ impl Definition {
|
||||||
|
|
||||||
pub fn name(&self, db: &RootDatabase) -> Option<Name> {
|
pub fn name(&self, db: &RootDatabase) -> Option<Name> {
|
||||||
let name = match self {
|
let name = match self {
|
||||||
Definition::Macro(it) => it.name(db)?,
|
Definition::Macro(it) => it.name(db),
|
||||||
Definition::Field(it) => it.name(db),
|
Definition::Field(it) => it.name(db),
|
||||||
Definition::Module(it) => it.name(db)?,
|
Definition::Module(it) => it.name(db)?,
|
||||||
Definition::Function(it) => it.name(db),
|
Definition::Function(it) => it.name(db),
|
||||||
|
@ -493,7 +493,6 @@ impl From<PathResolution> for Definition {
|
||||||
PathResolution::Local(local) => Definition::Local(local),
|
PathResolution::Local(local) => Definition::Local(local),
|
||||||
PathResolution::TypeParam(par) => Definition::GenericParam(par.into()),
|
PathResolution::TypeParam(par) => Definition::GenericParam(par.into()),
|
||||||
PathResolution::ConstParam(par) => Definition::GenericParam(par.into()),
|
PathResolution::ConstParam(par) => Definition::GenericParam(par.into()),
|
||||||
PathResolution::Macro(def) => Definition::Macro(def),
|
|
||||||
PathResolution::SelfType(impl_def) => Definition::SelfType(impl_def),
|
PathResolution::SelfType(impl_def) => Definition::SelfType(impl_def),
|
||||||
PathResolution::BuiltinAttr(attr) => Definition::BuiltinAttr(attr),
|
PathResolution::BuiltinAttr(attr) => Definition::BuiltinAttr(attr),
|
||||||
PathResolution::ToolModule(tool) => Definition::ToolModule(tool),
|
PathResolution::ToolModule(tool) => Definition::ToolModule(tool),
|
||||||
|
@ -512,6 +511,7 @@ impl From<ModuleDef> for Definition {
|
||||||
ModuleDef::Static(it) => Definition::Static(it),
|
ModuleDef::Static(it) => Definition::Static(it),
|
||||||
ModuleDef::Trait(it) => Definition::Trait(it),
|
ModuleDef::Trait(it) => Definition::Trait(it),
|
||||||
ModuleDef::TypeAlias(it) => Definition::TypeAlias(it),
|
ModuleDef::TypeAlias(it) => Definition::TypeAlias(it),
|
||||||
|
ModuleDef::Macro(it) => Definition::Macro(it),
|
||||||
ModuleDef::BuiltinType(it) => Definition::BuiltinType(it),
|
ModuleDef::BuiltinType(it) => Definition::BuiltinType(it),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//! See [`FamousDefs`].
|
//! See [`FamousDefs`].
|
||||||
use hir::{Crate, Enum, MacroDef, Module, ScopeDef, Semantics, Trait};
|
use hir::{Crate, Enum, Macro, Module, ScopeDef, Semantics, Trait};
|
||||||
|
|
||||||
use crate::RootDatabase;
|
use crate::RootDatabase;
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ impl FamousDefs<'_, '_> {
|
||||||
self.find_trait("core:marker:Copy")
|
self.find_trait("core:marker:Copy")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn core_macros_builtin_derive(&self) -> Option<MacroDef> {
|
pub fn core_macros_builtin_derive(&self) -> Option<Macro> {
|
||||||
self.find_macro("core:macros:builtin:derive")
|
self.find_macro("core:macros:builtin:derive")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,9 +118,9 @@ impl FamousDefs<'_, '_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_macro(&self, path: &str) -> Option<MacroDef> {
|
fn find_macro(&self, path: &str) -> Option<Macro> {
|
||||||
match self.find_def(path)? {
|
match self.find_def(path)? {
|
||||||
hir::ScopeDef::MacroDef(it) => Some(it),
|
hir::ScopeDef::ModuleDef(hir::ModuleDef::Macro(it)) => Some(it),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
use base_db::FileId;
|
use base_db::FileId;
|
||||||
use hir::{ItemInNs, MacroDef, ModuleDef, Name, Semantics};
|
use hir::{ItemInNs, Macro, ModuleDef, Name, Semantics};
|
||||||
use syntax::{
|
use syntax::{
|
||||||
ast::{self, make},
|
ast::{self, make},
|
||||||
AstToken, SyntaxKind, SyntaxToken, TokenAtOffset,
|
AstToken, SyntaxKind, SyntaxToken, TokenAtOffset,
|
||||||
|
@ -15,7 +15,7 @@ pub fn item_name(db: &RootDatabase, item: ItemInNs) -> Option<Name> {
|
||||||
match item {
|
match item {
|
||||||
ItemInNs::Types(module_def_id) => ModuleDef::from(module_def_id).name(db),
|
ItemInNs::Types(module_def_id) => ModuleDef::from(module_def_id).name(db),
|
||||||
ItemInNs::Values(module_def_id) => ModuleDef::from(module_def_id).name(db),
|
ItemInNs::Values(module_def_id) => ModuleDef::from(module_def_id).name(db),
|
||||||
ItemInNs::Macros(macro_def_id) => MacroDef::from(macro_def_id).name(db),
|
ItemInNs::Macros(macro_def_id) => Some(Macro::from(macro_def_id).name(db)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//! Look up accessible paths for items.
|
//! Look up accessible paths for items.
|
||||||
use hir::{
|
use hir::{
|
||||||
AsAssocItem, AssocItem, AssocItemContainer, Crate, ItemInNs, MacroDef, ModPath, Module,
|
AsAssocItem, AssocItem, AssocItemContainer, Crate, ItemInNs, ModPath, Module, ModuleDef,
|
||||||
ModuleDef, PathResolution, PrefixKind, ScopeDef, Semantics, SemanticsScope, Type,
|
PathResolution, PrefixKind, ScopeDef, Semantics, SemanticsScope, Type,
|
||||||
};
|
};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use rustc_hash::FxHashSet;
|
use rustc_hash::FxHashSet;
|
||||||
|
@ -432,7 +432,7 @@ fn module_with_segment_name(
|
||||||
let mut current_module = match candidate {
|
let mut current_module = match candidate {
|
||||||
ItemInNs::Types(module_def_id) => ModuleDef::from(module_def_id).module(db),
|
ItemInNs::Types(module_def_id) => ModuleDef::from(module_def_id).module(db),
|
||||||
ItemInNs::Values(module_def_id) => ModuleDef::from(module_def_id).module(db),
|
ItemInNs::Values(module_def_id) => ModuleDef::from(module_def_id).module(db),
|
||||||
ItemInNs::Macros(macro_def_id) => MacroDef::from(macro_def_id).module(db),
|
ItemInNs::Macros(macro_def_id) => ModuleDef::from(macro_def_id).module(db),
|
||||||
};
|
};
|
||||||
while let Some(module) = current_module {
|
while let Some(module) = current_module {
|
||||||
if let Some(module_name) = module.name(db) {
|
if let Some(module_name) = module.name(db) {
|
||||||
|
|
|
@ -225,7 +225,6 @@ impl<'a> Ctx<'a> {
|
||||||
hir::PathResolution::Local(_)
|
hir::PathResolution::Local(_)
|
||||||
| hir::PathResolution::ConstParam(_)
|
| hir::PathResolution::ConstParam(_)
|
||||||
| hir::PathResolution::SelfType(_)
|
| hir::PathResolution::SelfType(_)
|
||||||
| hir::PathResolution::Macro(_)
|
|
||||||
| hir::PathResolution::AssocItem(_)
|
| hir::PathResolution::AssocItem(_)
|
||||||
| hir::PathResolution::BuiltinAttr(_)
|
| hir::PathResolution::BuiltinAttr(_)
|
||||||
| hir::PathResolution::ToolModule(_) => (),
|
| hir::PathResolution::ToolModule(_) => (),
|
||||||
|
|
|
@ -271,7 +271,7 @@ impl Definition {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Definition::Macro(macro_def) = self {
|
if let Definition::Macro(macro_def) = self {
|
||||||
return match macro_def.kind() {
|
return match macro_def.kind(db) {
|
||||||
hir::MacroKind::Declarative => {
|
hir::MacroKind::Declarative => {
|
||||||
if macro_def.attrs(db).by_key("macro_export").exists() {
|
if macro_def.attrs(db).by_key("macro_export").exists() {
|
||||||
SearchScope::reverse_dependencies(db, module.krate())
|
SearchScope::reverse_dependencies(db, module.krate())
|
||||||
|
|
|
@ -425,7 +425,11 @@ struct StructInModB;
|
||||||
let symbols: Vec<_> = Crate::from(db.test_crate())
|
let symbols: Vec<_> = Crate::from(db.test_crate())
|
||||||
.modules(&db)
|
.modules(&db)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|module_id| (module_id, SymbolCollector::collect(&db, module_id)))
|
.map(|module_id| {
|
||||||
|
let mut symbols = SymbolCollector::collect(&db, module_id);
|
||||||
|
symbols.sort_by_key(|it| it.name.clone());
|
||||||
|
(module_id, symbols)
|
||||||
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
expect_file!["./test_data/test_symbol_index_collection.txt"].assert_debug_eq(&symbols);
|
expect_file!["./test_data/test_symbol_index_collection.txt"].assert_debug_eq(&symbols);
|
||||||
|
|
|
@ -11,31 +11,7 @@
|
||||||
},
|
},
|
||||||
[
|
[
|
||||||
FileSymbol {
|
FileSymbol {
|
||||||
name: "StructFromMacro",
|
name: "Alias",
|
||||||
loc: DeclarationLocation {
|
|
||||||
hir_file_id: HirFileId(
|
|
||||||
MacroFile(
|
|
||||||
MacroFile {
|
|
||||||
macro_call_id: MacroCallId(
|
|
||||||
0,
|
|
||||||
),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
ptr: SyntaxNodePtr {
|
|
||||||
kind: STRUCT,
|
|
||||||
range: 0..22,
|
|
||||||
},
|
|
||||||
name_ptr: SyntaxNodePtr {
|
|
||||||
kind: NAME,
|
|
||||||
range: 6..21,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
kind: Struct,
|
|
||||||
container_name: None,
|
|
||||||
},
|
|
||||||
FileSymbol {
|
|
||||||
name: "Struct",
|
|
||||||
loc: DeclarationLocation {
|
loc: DeclarationLocation {
|
||||||
hir_file_id: HirFileId(
|
hir_file_id: HirFileId(
|
||||||
FileId(
|
FileId(
|
||||||
|
@ -45,127 +21,15 @@
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ptr: SyntaxNodePtr {
|
ptr: SyntaxNodePtr {
|
||||||
kind: STRUCT,
|
kind: TYPE_ALIAS,
|
||||||
range: 170..184,
|
range: 397..417,
|
||||||
},
|
},
|
||||||
name_ptr: SyntaxNodePtr {
|
name_ptr: SyntaxNodePtr {
|
||||||
kind: NAME,
|
kind: NAME,
|
||||||
range: 177..183,
|
range: 402..407,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
kind: Struct,
|
kind: TypeAlias,
|
||||||
container_name: None,
|
|
||||||
},
|
|
||||||
FileSymbol {
|
|
||||||
name: "Enum",
|
|
||||||
loc: DeclarationLocation {
|
|
||||||
hir_file_id: HirFileId(
|
|
||||||
FileId(
|
|
||||||
FileId(
|
|
||||||
0,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
ptr: SyntaxNodePtr {
|
|
||||||
kind: ENUM,
|
|
||||||
range: 185..207,
|
|
||||||
},
|
|
||||||
name_ptr: SyntaxNodePtr {
|
|
||||||
kind: NAME,
|
|
||||||
range: 190..194,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
kind: Enum,
|
|
||||||
container_name: None,
|
|
||||||
},
|
|
||||||
FileSymbol {
|
|
||||||
name: "Union",
|
|
||||||
loc: DeclarationLocation {
|
|
||||||
hir_file_id: HirFileId(
|
|
||||||
FileId(
|
|
||||||
FileId(
|
|
||||||
0,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
ptr: SyntaxNodePtr {
|
|
||||||
kind: UNION,
|
|
||||||
range: 208..222,
|
|
||||||
},
|
|
||||||
name_ptr: SyntaxNodePtr {
|
|
||||||
kind: NAME,
|
|
||||||
range: 214..219,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
kind: Union,
|
|
||||||
container_name: None,
|
|
||||||
},
|
|
||||||
FileSymbol {
|
|
||||||
name: "Trait",
|
|
||||||
loc: DeclarationLocation {
|
|
||||||
hir_file_id: HirFileId(
|
|
||||||
FileId(
|
|
||||||
FileId(
|
|
||||||
0,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
ptr: SyntaxNodePtr {
|
|
||||||
kind: TRAIT,
|
|
||||||
range: 261..300,
|
|
||||||
},
|
|
||||||
name_ptr: SyntaxNodePtr {
|
|
||||||
kind: NAME,
|
|
||||||
range: 267..272,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
kind: Trait,
|
|
||||||
container_name: None,
|
|
||||||
},
|
|
||||||
FileSymbol {
|
|
||||||
name: "trait_fn",
|
|
||||||
loc: DeclarationLocation {
|
|
||||||
hir_file_id: HirFileId(
|
|
||||||
FileId(
|
|
||||||
FileId(
|
|
||||||
0,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
ptr: SyntaxNodePtr {
|
|
||||||
kind: FN,
|
|
||||||
range: 279..298,
|
|
||||||
},
|
|
||||||
name_ptr: SyntaxNodePtr {
|
|
||||||
kind: NAME,
|
|
||||||
range: 282..290,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
kind: Function,
|
|
||||||
container_name: Some(
|
|
||||||
"Trait",
|
|
||||||
),
|
|
||||||
},
|
|
||||||
FileSymbol {
|
|
||||||
name: "main",
|
|
||||||
loc: DeclarationLocation {
|
|
||||||
hir_file_id: HirFileId(
|
|
||||||
FileId(
|
|
||||||
FileId(
|
|
||||||
0,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
ptr: SyntaxNodePtr {
|
|
||||||
kind: FN,
|
|
||||||
range: 302..338,
|
|
||||||
},
|
|
||||||
name_ptr: SyntaxNodePtr {
|
|
||||||
kind: NAME,
|
|
||||||
range: 305..309,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
kind: Function,
|
|
||||||
container_name: None,
|
container_name: None,
|
||||||
},
|
},
|
||||||
FileSymbol {
|
FileSymbol {
|
||||||
|
@ -190,6 +54,72 @@
|
||||||
kind: Const,
|
kind: Const,
|
||||||
container_name: None,
|
container_name: None,
|
||||||
},
|
},
|
||||||
|
FileSymbol {
|
||||||
|
name: "CONST_WITH_INNER",
|
||||||
|
loc: DeclarationLocation {
|
||||||
|
hir_file_id: HirFileId(
|
||||||
|
FileId(
|
||||||
|
FileId(
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ptr: SyntaxNodePtr {
|
||||||
|
kind: CONST,
|
||||||
|
range: 520..592,
|
||||||
|
},
|
||||||
|
name_ptr: SyntaxNodePtr {
|
||||||
|
kind: NAME,
|
||||||
|
range: 526..542,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
kind: Const,
|
||||||
|
container_name: None,
|
||||||
|
},
|
||||||
|
FileSymbol {
|
||||||
|
name: "Enum",
|
||||||
|
loc: DeclarationLocation {
|
||||||
|
hir_file_id: HirFileId(
|
||||||
|
FileId(
|
||||||
|
FileId(
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ptr: SyntaxNodePtr {
|
||||||
|
kind: ENUM,
|
||||||
|
range: 185..207,
|
||||||
|
},
|
||||||
|
name_ptr: SyntaxNodePtr {
|
||||||
|
kind: NAME,
|
||||||
|
range: 190..194,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
kind: Enum,
|
||||||
|
container_name: None,
|
||||||
|
},
|
||||||
|
FileSymbol {
|
||||||
|
name: "Macro",
|
||||||
|
loc: DeclarationLocation {
|
||||||
|
hir_file_id: HirFileId(
|
||||||
|
FileId(
|
||||||
|
FileId(
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ptr: SyntaxNodePtr {
|
||||||
|
kind: MACRO_DEF,
|
||||||
|
range: 153..168,
|
||||||
|
},
|
||||||
|
name_ptr: SyntaxNodePtr {
|
||||||
|
kind: NAME,
|
||||||
|
range: 159..164,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
kind: Macro,
|
||||||
|
container_name: None,
|
||||||
|
},
|
||||||
FileSymbol {
|
FileSymbol {
|
||||||
name: "STATIC",
|
name: "STATIC",
|
||||||
loc: DeclarationLocation {
|
loc: DeclarationLocation {
|
||||||
|
@ -213,7 +143,7 @@
|
||||||
container_name: None,
|
container_name: None,
|
||||||
},
|
},
|
||||||
FileSymbol {
|
FileSymbol {
|
||||||
name: "Alias",
|
name: "Struct",
|
||||||
loc: DeclarationLocation {
|
loc: DeclarationLocation {
|
||||||
hir_file_id: HirFileId(
|
hir_file_id: HirFileId(
|
||||||
FileId(
|
FileId(
|
||||||
|
@ -223,15 +153,153 @@
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ptr: SyntaxNodePtr {
|
ptr: SyntaxNodePtr {
|
||||||
kind: TYPE_ALIAS,
|
kind: STRUCT,
|
||||||
range: 397..417,
|
range: 170..184,
|
||||||
},
|
},
|
||||||
name_ptr: SyntaxNodePtr {
|
name_ptr: SyntaxNodePtr {
|
||||||
kind: NAME,
|
kind: NAME,
|
||||||
range: 402..407,
|
range: 177..183,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
kind: TypeAlias,
|
kind: Struct,
|
||||||
|
container_name: None,
|
||||||
|
},
|
||||||
|
FileSymbol {
|
||||||
|
name: "StructFromMacro",
|
||||||
|
loc: DeclarationLocation {
|
||||||
|
hir_file_id: HirFileId(
|
||||||
|
MacroFile(
|
||||||
|
MacroFile {
|
||||||
|
macro_call_id: MacroCallId(
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ptr: SyntaxNodePtr {
|
||||||
|
kind: STRUCT,
|
||||||
|
range: 0..22,
|
||||||
|
},
|
||||||
|
name_ptr: SyntaxNodePtr {
|
||||||
|
kind: NAME,
|
||||||
|
range: 6..21,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
kind: Struct,
|
||||||
|
container_name: None,
|
||||||
|
},
|
||||||
|
FileSymbol {
|
||||||
|
name: "StructInFn",
|
||||||
|
loc: DeclarationLocation {
|
||||||
|
hir_file_id: HirFileId(
|
||||||
|
FileId(
|
||||||
|
FileId(
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ptr: SyntaxNodePtr {
|
||||||
|
kind: STRUCT,
|
||||||
|
range: 318..336,
|
||||||
|
},
|
||||||
|
name_ptr: SyntaxNodePtr {
|
||||||
|
kind: NAME,
|
||||||
|
range: 325..335,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
kind: Struct,
|
||||||
|
container_name: Some(
|
||||||
|
"main",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
FileSymbol {
|
||||||
|
name: "StructInNamedConst",
|
||||||
|
loc: DeclarationLocation {
|
||||||
|
hir_file_id: HirFileId(
|
||||||
|
FileId(
|
||||||
|
FileId(
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ptr: SyntaxNodePtr {
|
||||||
|
kind: STRUCT,
|
||||||
|
range: 555..581,
|
||||||
|
},
|
||||||
|
name_ptr: SyntaxNodePtr {
|
||||||
|
kind: NAME,
|
||||||
|
range: 562..580,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
kind: Struct,
|
||||||
|
container_name: Some(
|
||||||
|
"CONST_WITH_INNER",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
FileSymbol {
|
||||||
|
name: "StructInUnnamedConst",
|
||||||
|
loc: DeclarationLocation {
|
||||||
|
hir_file_id: HirFileId(
|
||||||
|
FileId(
|
||||||
|
FileId(
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ptr: SyntaxNodePtr {
|
||||||
|
kind: STRUCT,
|
||||||
|
range: 479..507,
|
||||||
|
},
|
||||||
|
name_ptr: SyntaxNodePtr {
|
||||||
|
kind: NAME,
|
||||||
|
range: 486..506,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
kind: Struct,
|
||||||
|
container_name: None,
|
||||||
|
},
|
||||||
|
FileSymbol {
|
||||||
|
name: "Trait",
|
||||||
|
loc: DeclarationLocation {
|
||||||
|
hir_file_id: HirFileId(
|
||||||
|
FileId(
|
||||||
|
FileId(
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ptr: SyntaxNodePtr {
|
||||||
|
kind: TRAIT,
|
||||||
|
range: 261..300,
|
||||||
|
},
|
||||||
|
name_ptr: SyntaxNodePtr {
|
||||||
|
kind: NAME,
|
||||||
|
range: 267..272,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
kind: Trait,
|
||||||
|
container_name: None,
|
||||||
|
},
|
||||||
|
FileSymbol {
|
||||||
|
name: "Union",
|
||||||
|
loc: DeclarationLocation {
|
||||||
|
hir_file_id: HirFileId(
|
||||||
|
FileId(
|
||||||
|
FileId(
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ptr: SyntaxNodePtr {
|
||||||
|
kind: UNION,
|
||||||
|
range: 208..222,
|
||||||
|
},
|
||||||
|
name_ptr: SyntaxNodePtr {
|
||||||
|
kind: NAME,
|
||||||
|
range: 214..219,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
kind: Union,
|
||||||
container_name: None,
|
container_name: None,
|
||||||
},
|
},
|
||||||
FileSymbol {
|
FileSymbol {
|
||||||
|
@ -256,28 +324,6 @@
|
||||||
kind: Module,
|
kind: Module,
|
||||||
container_name: None,
|
container_name: None,
|
||||||
},
|
},
|
||||||
FileSymbol {
|
|
||||||
name: "CONST_WITH_INNER",
|
|
||||||
loc: DeclarationLocation {
|
|
||||||
hir_file_id: HirFileId(
|
|
||||||
FileId(
|
|
||||||
FileId(
|
|
||||||
0,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
ptr: SyntaxNodePtr {
|
|
||||||
kind: CONST,
|
|
||||||
range: 520..592,
|
|
||||||
},
|
|
||||||
name_ptr: SyntaxNodePtr {
|
|
||||||
kind: NAME,
|
|
||||||
range: 526..542,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
kind: Const,
|
|
||||||
container_name: None,
|
|
||||||
},
|
|
||||||
FileSymbol {
|
FileSymbol {
|
||||||
name: "b_mod",
|
name: "b_mod",
|
||||||
loc: DeclarationLocation {
|
loc: DeclarationLocation {
|
||||||
|
@ -300,6 +346,28 @@
|
||||||
kind: Module,
|
kind: Module,
|
||||||
container_name: None,
|
container_name: None,
|
||||||
},
|
},
|
||||||
|
FileSymbol {
|
||||||
|
name: "define_struct",
|
||||||
|
loc: DeclarationLocation {
|
||||||
|
hir_file_id: HirFileId(
|
||||||
|
FileId(
|
||||||
|
FileId(
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ptr: SyntaxNodePtr {
|
||||||
|
kind: MACRO_RULES,
|
||||||
|
range: 51..131,
|
||||||
|
},
|
||||||
|
name_ptr: SyntaxNodePtr {
|
||||||
|
kind: NAME,
|
||||||
|
range: 64..77,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
kind: Macro,
|
||||||
|
container_name: None,
|
||||||
|
},
|
||||||
FileSymbol {
|
FileSymbol {
|
||||||
name: "impl_fn",
|
name: "impl_fn",
|
||||||
loc: DeclarationLocation {
|
loc: DeclarationLocation {
|
||||||
|
@ -345,7 +413,7 @@
|
||||||
container_name: None,
|
container_name: None,
|
||||||
},
|
},
|
||||||
FileSymbol {
|
FileSymbol {
|
||||||
name: "define_struct",
|
name: "main",
|
||||||
loc: DeclarationLocation {
|
loc: DeclarationLocation {
|
||||||
hir_file_id: HirFileId(
|
hir_file_id: HirFileId(
|
||||||
FileId(
|
FileId(
|
||||||
|
@ -355,19 +423,19 @@
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ptr: SyntaxNodePtr {
|
ptr: SyntaxNodePtr {
|
||||||
kind: MACRO_RULES,
|
kind: FN,
|
||||||
range: 51..131,
|
range: 302..338,
|
||||||
},
|
},
|
||||||
name_ptr: SyntaxNodePtr {
|
name_ptr: SyntaxNodePtr {
|
||||||
kind: NAME,
|
kind: NAME,
|
||||||
range: 64..77,
|
range: 305..309,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
kind: Macro,
|
kind: Function,
|
||||||
container_name: None,
|
container_name: None,
|
||||||
},
|
},
|
||||||
FileSymbol {
|
FileSymbol {
|
||||||
name: "Macro",
|
name: "trait_fn",
|
||||||
loc: DeclarationLocation {
|
loc: DeclarationLocation {
|
||||||
hir_file_id: HirFileId(
|
hir_file_id: HirFileId(
|
||||||
FileId(
|
FileId(
|
||||||
|
@ -377,85 +445,17 @@
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ptr: SyntaxNodePtr {
|
ptr: SyntaxNodePtr {
|
||||||
kind: MACRO_DEF,
|
kind: FN,
|
||||||
range: 153..168,
|
range: 279..298,
|
||||||
},
|
},
|
||||||
name_ptr: SyntaxNodePtr {
|
name_ptr: SyntaxNodePtr {
|
||||||
kind: NAME,
|
kind: NAME,
|
||||||
range: 159..164,
|
range: 282..290,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
kind: Macro,
|
kind: Function,
|
||||||
container_name: None,
|
|
||||||
},
|
|
||||||
FileSymbol {
|
|
||||||
name: "StructInUnnamedConst",
|
|
||||||
loc: DeclarationLocation {
|
|
||||||
hir_file_id: HirFileId(
|
|
||||||
FileId(
|
|
||||||
FileId(
|
|
||||||
0,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
ptr: SyntaxNodePtr {
|
|
||||||
kind: STRUCT,
|
|
||||||
range: 479..507,
|
|
||||||
},
|
|
||||||
name_ptr: SyntaxNodePtr {
|
|
||||||
kind: NAME,
|
|
||||||
range: 486..506,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
kind: Struct,
|
|
||||||
container_name: None,
|
|
||||||
},
|
|
||||||
FileSymbol {
|
|
||||||
name: "StructInNamedConst",
|
|
||||||
loc: DeclarationLocation {
|
|
||||||
hir_file_id: HirFileId(
|
|
||||||
FileId(
|
|
||||||
FileId(
|
|
||||||
0,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
ptr: SyntaxNodePtr {
|
|
||||||
kind: STRUCT,
|
|
||||||
range: 555..581,
|
|
||||||
},
|
|
||||||
name_ptr: SyntaxNodePtr {
|
|
||||||
kind: NAME,
|
|
||||||
range: 562..580,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
kind: Struct,
|
|
||||||
container_name: Some(
|
container_name: Some(
|
||||||
"CONST_WITH_INNER",
|
"Trait",
|
||||||
),
|
|
||||||
},
|
|
||||||
FileSymbol {
|
|
||||||
name: "StructInFn",
|
|
||||||
loc: DeclarationLocation {
|
|
||||||
hir_file_id: HirFileId(
|
|
||||||
FileId(
|
|
||||||
FileId(
|
|
||||||
0,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
ptr: SyntaxNodePtr {
|
|
||||||
kind: STRUCT,
|
|
||||||
range: 318..336,
|
|
||||||
},
|
|
||||||
name_ptr: SyntaxNodePtr {
|
|
||||||
kind: NAME,
|
|
||||||
range: 325..335,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
kind: Struct,
|
|
||||||
container_name: Some(
|
|
||||||
"main",
|
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
@ -823,11 +823,12 @@ fn replace_macro_invocations() {
|
||||||
"macro_rules! try {() => {}} fn f1() -> Result<(), E> {bar(try!(foo()));}",
|
"macro_rules! try {() => {}} fn f1() -> Result<(), E> {bar(try!(foo()));}",
|
||||||
expect![["macro_rules! try {() => {}} fn f1() -> Result<(), E> {bar(foo()?);}"]],
|
expect![["macro_rules! try {() => {}} fn f1() -> Result<(), E> {bar(foo()?);}"]],
|
||||||
);
|
);
|
||||||
assert_ssr_transform(
|
// FIXME: Figure out why this doesn't work anymore
|
||||||
"foo!($a($b)) ==>> foo($b, $a)",
|
// assert_ssr_transform(
|
||||||
"macro_rules! foo {() => {}} fn f1() {foo!(abc(def() + 2));}",
|
// "foo!($a($b)) ==>> foo($b, $a)",
|
||||||
expect![["macro_rules! foo {() => {}} fn f1() {foo(def() + 2, abc);}"]],
|
// "macro_rules! foo {() => {}} fn f1() {foo!(abc(def() + 2));}",
|
||||||
);
|
// expect![["macro_rules! foo {() => {}} fn f1() {foo(def() + 2, abc);}"]],
|
||||||
|
// );
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue