internal: Flatten Definition::ModuleDef variant
This commit is contained in:
@@ -421,10 +421,7 @@ impl HirDisplay for Static {
|
|||||||
if data.mutable {
|
if data.mutable {
|
||||||
write!(f, "mut ")?;
|
write!(f, "mut ")?;
|
||||||
}
|
}
|
||||||
match &data.name {
|
write!(f, "{}: ", &data.name)?;
|
||||||
Some(name) => write!(f, "{}: ", name)?,
|
|
||||||
None => write!(f, "_: ")?,
|
|
||||||
}
|
|
||||||
data.type_ref.hir_fmt(f)?;
|
data.type_ref.hir_fmt(f)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -316,17 +316,18 @@ impl ModuleDef {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
|
pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
|
||||||
match self {
|
let name = match self {
|
||||||
ModuleDef::Adt(it) => Some(it.name(db)),
|
ModuleDef::Module(it) => it.name(db)?,
|
||||||
ModuleDef::Trait(it) => Some(it.name(db)),
|
ModuleDef::Const(it) => it.name(db)?,
|
||||||
ModuleDef::Function(it) => Some(it.name(db)),
|
ModuleDef::Adt(it) => it.name(db),
|
||||||
ModuleDef::Variant(it) => Some(it.name(db)),
|
ModuleDef::Trait(it) => it.name(db),
|
||||||
ModuleDef::TypeAlias(it) => Some(it.name(db)),
|
ModuleDef::Function(it) => it.name(db),
|
||||||
ModuleDef::Module(it) => it.name(db),
|
ModuleDef::Variant(it) => it.name(db),
|
||||||
ModuleDef::Const(it) => it.name(db),
|
ModuleDef::TypeAlias(it) => it.name(db),
|
||||||
ModuleDef::Static(it) => it.name(db),
|
ModuleDef::Static(it) => it.name(db),
|
||||||
ModuleDef::BuiltinType(it) => Some(it.name()),
|
ModuleDef::BuiltinType(it) => it.name(),
|
||||||
}
|
};
|
||||||
|
Some(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn diagnostics(self, db: &dyn HirDatabase) -> Vec<AnyDiagnostic> {
|
pub fn diagnostics(self, db: &dyn HirDatabase) -> Vec<AnyDiagnostic> {
|
||||||
@@ -1036,7 +1037,7 @@ impl DefWithBody {
|
|||||||
pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
|
pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
|
||||||
match self {
|
match self {
|
||||||
DefWithBody::Function(f) => Some(f.name(db)),
|
DefWithBody::Function(f) => Some(f.name(db)),
|
||||||
DefWithBody::Static(s) => s.name(db),
|
DefWithBody::Static(s) => Some(s.name(db)),
|
||||||
DefWithBody::Const(c) => c.name(db),
|
DefWithBody::Const(c) => c.name(db),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1484,7 +1485,7 @@ impl Static {
|
|||||||
Module { id: self.id.lookup(db.upcast()).module(db.upcast()) }
|
Module { id: self.id.lookup(db.upcast()).module(db.upcast()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
|
pub fn name(self, db: &dyn HirDatabase) -> Name {
|
||||||
db.static_data(self.id).name.clone()
|
db.static_data(self.id).name.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -273,7 +273,7 @@ impl ConstData {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct StaticData {
|
pub struct StaticData {
|
||||||
pub name: Option<Name>,
|
pub name: Name,
|
||||||
pub type_ref: Interned<TypeRef>,
|
pub type_ref: Interned<TypeRef>,
|
||||||
pub visibility: RawVisibility,
|
pub visibility: RawVisibility,
|
||||||
pub mutable: bool,
|
pub mutable: bool,
|
||||||
@@ -287,7 +287,7 @@ impl StaticData {
|
|||||||
let statik = &item_tree[node.id.value];
|
let statik = &item_tree[node.id.value];
|
||||||
|
|
||||||
Arc::new(StaticData {
|
Arc::new(StaticData {
|
||||||
name: Some(statik.name.clone()),
|
name: statik.name.clone(),
|
||||||
type_ref: statik.type_ref.clone(),
|
type_ref: statik.type_ref.clone(),
|
||||||
visibility: item_tree[statik.visibility].clone(),
|
visibility: item_tree[statik.visibility].clone(),
|
||||||
mutable: statik.mutable,
|
mutable: statik.mutable,
|
||||||
|
|||||||
@@ -159,9 +159,7 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
|
|||||||
fn infer_wait(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<InferenceResult> {
|
fn infer_wait(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<InferenceResult> {
|
||||||
let _p = profile::span("infer:wait").detail(|| match def {
|
let _p = profile::span("infer:wait").detail(|| match def {
|
||||||
DefWithBodyId::FunctionId(it) => db.function_data(it).name.to_string(),
|
DefWithBodyId::FunctionId(it) => db.function_data(it).name.to_string(),
|
||||||
DefWithBodyId::StaticId(it) => {
|
DefWithBodyId::StaticId(it) => db.static_data(it).name.clone().to_string(),
|
||||||
db.static_data(it).name.clone().unwrap_or_else(Name::missing).to_string()
|
|
||||||
}
|
|
||||||
DefWithBodyId::ConstId(it) => {
|
DefWithBodyId::ConstId(it) => {
|
||||||
db.const_data(it).name.clone().unwrap_or_else(Name::missing).to_string()
|
db.const_data(it).name.clone().unwrap_or_else(Name::missing).to_string()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -581,10 +581,7 @@ impl<'a> DeclValidator<'a> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let name = match &data.name {
|
let name = &data.name;
|
||||||
Some(name) => name,
|
|
||||||
None => return,
|
|
||||||
};
|
|
||||||
|
|
||||||
let static_name = name.to_string();
|
let static_name = name.to_string();
|
||||||
let replacement = if let Some(new_name) = to_upper_snake_case(&static_name) {
|
let replacement = if let Some(new_name) = to_upper_snake_case(&static_name) {
|
||||||
|
|||||||
@@ -47,15 +47,11 @@ pub(crate) fn incoming_calls(
|
|||||||
.find_nodes_at_offset_with_descend(file, offset)
|
.find_nodes_at_offset_with_descend(file, offset)
|
||||||
.filter_map(move |node| match node {
|
.filter_map(move |node| match node {
|
||||||
ast::NameLike::NameRef(name_ref) => match NameRefClass::classify(sema, &name_ref)? {
|
ast::NameLike::NameRef(name_ref) => match NameRefClass::classify(sema, &name_ref)? {
|
||||||
NameRefClass::Definition(
|
NameRefClass::Definition(def @ Definition::Function(_)) => Some(def),
|
||||||
def @ Definition::ModuleDef(hir::ModuleDef::Function(_)),
|
|
||||||
) => Some(def),
|
|
||||||
_ => None,
|
_ => None,
|
||||||
},
|
},
|
||||||
ast::NameLike::Name(name) => match NameClass::classify(sema, &name)? {
|
ast::NameLike::Name(name) => match NameClass::classify(sema, &name)? {
|
||||||
NameClass::Definition(def @ Definition::ModuleDef(hir::ModuleDef::Function(_))) => {
|
NameClass::Definition(def @ Definition::Function(_)) => Some(def),
|
||||||
Some(def)
|
|
||||||
}
|
|
||||||
_ => None,
|
_ => None,
|
||||||
},
|
},
|
||||||
ast::NameLike::Lifetime(_) => None,
|
ast::NameLike::Lifetime(_) => None,
|
||||||
|
|||||||
@@ -196,13 +196,21 @@ impl ToNav for FileSymbol {
|
|||||||
impl TryToNav for Definition {
|
impl TryToNav for Definition {
|
||||||
fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> {
|
fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> {
|
||||||
match self {
|
match self {
|
||||||
|
Definition::Local(it) => Some(it.to_nav(db)),
|
||||||
|
Definition::Label(it) => Some(it.to_nav(db)),
|
||||||
|
Definition::Module(it) => Some(it.to_nav(db)),
|
||||||
Definition::Macro(it) => it.try_to_nav(db),
|
Definition::Macro(it) => it.try_to_nav(db),
|
||||||
Definition::Field(it) => it.try_to_nav(db),
|
Definition::Field(it) => it.try_to_nav(db),
|
||||||
Definition::ModuleDef(it) => it.try_to_nav(db),
|
|
||||||
Definition::SelfType(it) => it.try_to_nav(db),
|
Definition::SelfType(it) => it.try_to_nav(db),
|
||||||
Definition::Local(it) => Some(it.to_nav(db)),
|
|
||||||
Definition::GenericParam(it) => it.try_to_nav(db),
|
Definition::GenericParam(it) => it.try_to_nav(db),
|
||||||
Definition::Label(it) => Some(it.to_nav(db)),
|
Definition::Function(it) => it.try_to_nav(db),
|
||||||
|
Definition::Adt(it) => it.try_to_nav(db),
|
||||||
|
Definition::Variant(it) => it.try_to_nav(db),
|
||||||
|
Definition::Const(it) => it.try_to_nav(db),
|
||||||
|
Definition::Static(it) => it.try_to_nav(db),
|
||||||
|
Definition::Trait(it) => it.try_to_nav(db),
|
||||||
|
Definition::TypeAlias(it) => it.try_to_nav(db),
|
||||||
|
Definition::BuiltinType(_) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,10 +8,7 @@ use pulldown_cmark_to_cmark::{cmark_with_options, Options as CMarkOptions};
|
|||||||
use stdx::format_to;
|
use stdx::format_to;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use hir::{
|
use hir::{db::HirDatabase, Adt, AsAssocItem, AssocItem, AssocItemContainer, Crate, HasAttrs};
|
||||||
db::HirDatabase, Adt, AsAssocItem, AssocItem, AssocItemContainer, Crate, HasAttrs, MacroDef,
|
|
||||||
ModuleDef,
|
|
||||||
};
|
|
||||||
use ide_db::{
|
use ide_db::{
|
||||||
defs::{Definition, NameClass, NameRefClass},
|
defs::{Definition, NameClass, NameRefClass},
|
||||||
helpers::pick_best_token,
|
helpers::pick_best_token,
|
||||||
@@ -53,11 +50,9 @@ pub(crate) fn rewrite_links(db: &RootDatabase, markdown: &str, definition: Defin
|
|||||||
if let Some(rewritten) = rewrite_intra_doc_link(db, definition, target, title) {
|
if let Some(rewritten) = rewrite_intra_doc_link(db, definition, target, title) {
|
||||||
return rewritten;
|
return rewritten;
|
||||||
}
|
}
|
||||||
if let Definition::ModuleDef(def) = definition {
|
if let Some(target) = rewrite_url_link(db, definition, target) {
|
||||||
if let Some(target) = rewrite_url_link(db, Either::Left(def), target) {
|
|
||||||
return (target, title.to_string());
|
return (target, title.to_string());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
(target.to_string(), title.to_string())
|
(target.to_string(), title.to_string())
|
||||||
}
|
}
|
||||||
@@ -174,25 +169,27 @@ pub(crate) fn resolve_doc_path_for_def(
|
|||||||
def: Definition,
|
def: Definition,
|
||||||
link: &str,
|
link: &str,
|
||||||
ns: Option<hir::Namespace>,
|
ns: Option<hir::Namespace>,
|
||||||
) -> Option<Either<ModuleDef, MacroDef>> {
|
) -> Option<Definition> {
|
||||||
match def {
|
let def = match def {
|
||||||
Definition::ModuleDef(def) => match def {
|
Definition::Module(it) => it.resolve_doc_path(db, link, ns),
|
||||||
hir::ModuleDef::Module(it) => it.resolve_doc_path(db, link, ns),
|
Definition::Function(it) => it.resolve_doc_path(db, link, ns),
|
||||||
hir::ModuleDef::Function(it) => it.resolve_doc_path(db, link, ns),
|
Definition::Adt(it) => it.resolve_doc_path(db, link, ns),
|
||||||
hir::ModuleDef::Adt(it) => it.resolve_doc_path(db, link, ns),
|
Definition::Variant(it) => it.resolve_doc_path(db, link, ns),
|
||||||
hir::ModuleDef::Variant(it) => it.resolve_doc_path(db, link, ns),
|
Definition::Const(it) => it.resolve_doc_path(db, link, ns),
|
||||||
hir::ModuleDef::Const(it) => it.resolve_doc_path(db, link, ns),
|
Definition::Static(it) => it.resolve_doc_path(db, link, ns),
|
||||||
hir::ModuleDef::Static(it) => it.resolve_doc_path(db, link, ns),
|
Definition::Trait(it) => it.resolve_doc_path(db, link, ns),
|
||||||
hir::ModuleDef::Trait(it) => it.resolve_doc_path(db, link, ns),
|
Definition::TypeAlias(it) => it.resolve_doc_path(db, link, ns),
|
||||||
hir::ModuleDef::TypeAlias(it) => it.resolve_doc_path(db, link, ns),
|
|
||||||
hir::ModuleDef::BuiltinType(_) => None,
|
|
||||||
},
|
|
||||||
Definition::Macro(it) => it.resolve_doc_path(db, link, ns),
|
Definition::Macro(it) => it.resolve_doc_path(db, link, ns),
|
||||||
Definition::Field(it) => it.resolve_doc_path(db, link, ns),
|
Definition::Field(it) => it.resolve_doc_path(db, link, ns),
|
||||||
Definition::SelfType(_)
|
Definition::BuiltinType(_)
|
||||||
|
| Definition::SelfType(_)
|
||||||
| 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)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,17 +199,17 @@ pub(crate) fn doc_attributes(
|
|||||||
) -> Option<(hir::AttrsWithOwner, Definition)> {
|
) -> Option<(hir::AttrsWithOwner, Definition)> {
|
||||||
match_ast! {
|
match_ast! {
|
||||||
match node {
|
match node {
|
||||||
ast::SourceFile(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::ModuleDef(hir::ModuleDef::Module(def)))),
|
ast::SourceFile(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::Module(def))),
|
||||||
ast::Module(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::ModuleDef(hir::ModuleDef::Module(def)))),
|
ast::Module(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::Module(def))),
|
||||||
ast::Fn(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::ModuleDef(hir::ModuleDef::Function(def)))),
|
ast::Fn(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::Function(def))),
|
||||||
ast::Struct(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::ModuleDef(hir::ModuleDef::Adt(hir::Adt::Struct(def))))),
|
ast::Struct(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::Adt(hir::Adt::Struct(def)))),
|
||||||
ast::Union(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::ModuleDef(hir::ModuleDef::Adt(hir::Adt::Union(def))))),
|
ast::Union(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::Adt(hir::Adt::Union(def)))),
|
||||||
ast::Enum(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::ModuleDef(hir::ModuleDef::Adt(hir::Adt::Enum(def))))),
|
ast::Enum(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::Adt(hir::Adt::Enum(def)))),
|
||||||
ast::Variant(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::ModuleDef(hir::ModuleDef::Variant(def)))),
|
ast::Variant(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::Variant(def))),
|
||||||
ast::Trait(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::ModuleDef(hir::ModuleDef::Trait(def)))),
|
ast::Trait(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::Trait(def))),
|
||||||
ast::Static(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::ModuleDef(hir::ModuleDef::Static(def)))),
|
ast::Static(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::Static(def))),
|
||||||
ast::Const(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::ModuleDef(hir::ModuleDef::Const(def)))),
|
ast::Const(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::Const(def))),
|
||||||
ast::TypeAlias(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::ModuleDef(hir::ModuleDef::TypeAlias(def)))),
|
ast::TypeAlias(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::TypeAlias(def))),
|
||||||
ast::Impl(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::SelfType(def))),
|
ast::Impl(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::SelfType(def))),
|
||||||
ast::RecordField(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::Field(def))),
|
ast::RecordField(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::Field(def))),
|
||||||
ast::TupleField(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::Field(def))),
|
ast::TupleField(it) => sema.to_def(&it).map(|def| (def.attrs(sema.db), Definition::Field(def))),
|
||||||
@@ -274,10 +271,7 @@ impl DocCommentToken {
|
|||||||
let in_expansion_relative_range = in_expansion_range - descended_prefix_len - token_start;
|
let in_expansion_relative_range = in_expansion_range - descended_prefix_len - token_start;
|
||||||
// Apply relative range to the original input comment
|
// Apply relative range to the original input comment
|
||||||
let absolute_range = in_expansion_relative_range + original_start + prefix_len;
|
let absolute_range = in_expansion_relative_range + original_start + prefix_len;
|
||||||
let def = match resolve_doc_path_for_def(sema.db, def, &link, ns)? {
|
let def = resolve_doc_path_for_def(sema.db, def, &link, ns)?;
|
||||||
Either::Left(it) => Definition::ModuleDef(it),
|
|
||||||
Either::Right(it) => Definition::Macro(it),
|
|
||||||
};
|
|
||||||
cb(def, node, absolute_range)
|
cb(def, node, absolute_range)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -299,33 +293,8 @@ fn broken_link_clone_cb<'a, 'b>(link: BrokenLink<'a>) -> Option<(CowStr<'b>, Cow
|
|||||||
//
|
//
|
||||||
// This should cease to be a problem if RFC2988 (Stable Rustdoc URLs) is implemented
|
// This should cease to be a problem if RFC2988 (Stable Rustdoc URLs) is implemented
|
||||||
// https://github.com/rust-lang/rfcs/pull/2988
|
// https://github.com/rust-lang/rfcs/pull/2988
|
||||||
fn get_doc_link(db: &RootDatabase, definition: Definition) -> Option<String> {
|
fn get_doc_link(db: &RootDatabase, def: Definition) -> Option<String> {
|
||||||
let (target, frag) = match definition {
|
let (target, file, frag) = filename_and_frag_for_def(db, def)?;
|
||||||
Definition::ModuleDef(def) => {
|
|
||||||
if let Some(assoc_item) = def.as_assoc_item(db) {
|
|
||||||
let def = match assoc_item.container(db) {
|
|
||||||
AssocItemContainer::Trait(t) => t.into(),
|
|
||||||
AssocItemContainer::Impl(i) => i.self_ty(db).as_adt()?.into(),
|
|
||||||
};
|
|
||||||
let frag = get_assoc_item_fragment(db, assoc_item)?;
|
|
||||||
(Either::Left(def), Some(frag))
|
|
||||||
} else {
|
|
||||||
(Either::Left(def), None)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Definition::Field(field) => {
|
|
||||||
let def = match field.parent_def(db) {
|
|
||||||
hir::VariantDef::Struct(it) => it.into(),
|
|
||||||
hir::VariantDef::Union(it) => it.into(),
|
|
||||||
hir::VariantDef::Variant(it) => it.into(),
|
|
||||||
};
|
|
||||||
(Either::Left(def), Some(format!("structfield.{}", field.name(db))))
|
|
||||||
}
|
|
||||||
Definition::Macro(makro) => (Either::Right(makro), None),
|
|
||||||
// FIXME impls
|
|
||||||
Definition::SelfType(_) => return None,
|
|
||||||
Definition::Local(_) | Definition::GenericParam(_) | Definition::Label(_) => return None,
|
|
||||||
};
|
|
||||||
|
|
||||||
let krate = crate_of_def(db, target)?;
|
let krate = crate_of_def(db, target)?;
|
||||||
let mut url = get_doc_base_url(db, &krate)?;
|
let mut url = get_doc_base_url(db, &krate)?;
|
||||||
@@ -334,7 +303,7 @@ fn get_doc_link(db: &RootDatabase, definition: Definition) -> Option<String> {
|
|||||||
url = url.join(&path).ok()?;
|
url = url.join(&path).ok()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
url = url.join(&get_symbol_filename(db, target)?).ok()?;
|
url = url.join(&file).ok()?;
|
||||||
url.set_fragment(frag.as_deref());
|
url.set_fragment(frag.as_deref());
|
||||||
|
|
||||||
Some(url.into())
|
Some(url.into())
|
||||||
@@ -352,73 +321,51 @@ fn rewrite_intra_doc_link(
|
|||||||
let krate = crate_of_def(db, resolved)?;
|
let krate = crate_of_def(db, resolved)?;
|
||||||
let mut url = get_doc_base_url(db, &krate)?;
|
let mut url = get_doc_base_url(db, &krate)?;
|
||||||
|
|
||||||
|
let (_, file, frag) = filename_and_frag_for_def(db, resolved)?;
|
||||||
if let Some(path) = mod_path_of_def(db, resolved) {
|
if let Some(path) = mod_path_of_def(db, resolved) {
|
||||||
url = url.join(&path).ok()?;
|
url = url.join(&path).ok()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let (resolved, frag) =
|
url = url.join(&file).ok()?;
|
||||||
if let Some(assoc_item) = resolved.left().and_then(|it| it.as_assoc_item(db)) {
|
|
||||||
let resolved = match assoc_item.container(db) {
|
|
||||||
AssocItemContainer::Trait(t) => t.into(),
|
|
||||||
AssocItemContainer::Impl(i) => i.self_ty(db).as_adt()?.into(),
|
|
||||||
};
|
|
||||||
let frag = get_assoc_item_fragment(db, assoc_item)?;
|
|
||||||
(Either::Left(resolved), Some(frag))
|
|
||||||
} else {
|
|
||||||
(resolved, None)
|
|
||||||
};
|
|
||||||
url = url.join(&get_symbol_filename(db, resolved)?).ok()?;
|
|
||||||
url.set_fragment(frag.as_deref());
|
url.set_fragment(frag.as_deref());
|
||||||
|
|
||||||
Some((url.into(), strip_prefixes_suffixes(title).to_string()))
|
Some((url.into(), strip_prefixes_suffixes(title).to_string()))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Try to resolve path to local documentation via path-based links (i.e. `../gateway/struct.Shard.html`).
|
/// Try to resolve path to local documentation via path-based links (i.e. `../gateway/struct.Shard.html`).
|
||||||
fn rewrite_url_link(
|
fn rewrite_url_link(db: &RootDatabase, def: Definition, target: &str) -> Option<String> {
|
||||||
db: &RootDatabase,
|
|
||||||
def: Either<ModuleDef, MacroDef>,
|
|
||||||
target: &str,
|
|
||||||
) -> Option<String> {
|
|
||||||
if !(target.contains('#') || target.contains(".html")) {
|
if !(target.contains('#') || target.contains(".html")) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let krate = crate_of_def(db, def)?;
|
let krate = crate_of_def(db, def)?;
|
||||||
let mut url = get_doc_base_url(db, &krate)?;
|
let mut url = get_doc_base_url(db, &krate)?;
|
||||||
|
let (def, file, frag) = filename_and_frag_for_def(db, def)?;
|
||||||
|
|
||||||
if let Some(path) = mod_path_of_def(db, def) {
|
if let Some(path) = mod_path_of_def(db, def) {
|
||||||
url = url.join(&path).ok()?;
|
url = url.join(&path).ok()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
url = url.join(&get_symbol_filename(db, def)?).ok()?;
|
url = url.join(&file).ok()?;
|
||||||
|
url.set_fragment(frag.as_deref());
|
||||||
url.join(target).ok().map(Into::into)
|
url.join(target).ok().map(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn crate_of_def(db: &RootDatabase, def: Either<ModuleDef, MacroDef>) -> Option<Crate> {
|
fn crate_of_def(db: &RootDatabase, def: Definition) -> Option<Crate> {
|
||||||
let krate = match def {
|
let krate = match def {
|
||||||
// Definition::module gives back the parent module, we don't want that as it fails for root modules
|
// Definition::module gives back the parent module, we don't want that as it fails for root modules
|
||||||
Either::Left(ModuleDef::Module(module)) => module.krate(),
|
Definition::Module(module) => module.krate(),
|
||||||
Either::Left(def) => def.module(db)?.krate(),
|
def => def.module(db)?.krate(),
|
||||||
Either::Right(def) => def.module(db)?.krate(),
|
|
||||||
};
|
};
|
||||||
Some(krate)
|
Some(krate)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mod_path_of_def(db: &RootDatabase, def: Either<ModuleDef, MacroDef>) -> Option<String> {
|
fn mod_path_of_def(db: &RootDatabase, def: Definition) -> Option<String> {
|
||||||
match def {
|
def.canonical_module_path(db).map(|it| {
|
||||||
Either::Left(def) => def.canonical_module_path(db).map(|it| {
|
|
||||||
let mut path = String::new();
|
|
||||||
it.flat_map(|it| it.name(db)).for_each(|name| format_to!(path, "{}/", name));
|
|
||||||
path
|
|
||||||
}),
|
|
||||||
Either::Right(def) => {
|
|
||||||
def.module(db).map(|it| it.path_to_root(db).into_iter().rev()).map(|it| {
|
|
||||||
let mut path = String::new();
|
let mut path = String::new();
|
||||||
it.flat_map(|it| it.name(db)).for_each(|name| format_to!(path, "{}/", name));
|
it.flat_map(|it| it.name(db)).for_each(|name| format_to!(path, "{}/", name));
|
||||||
path
|
path
|
||||||
})
|
})
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rewrites a markdown document, applying 'callback' to each link.
|
/// Rewrites a markdown document, applying 'callback' to each link.
|
||||||
@@ -496,34 +443,61 @@ fn get_doc_base_url(db: &RootDatabase, krate: &Crate) -> Option<Url> {
|
|||||||
/// https://doc.rust-lang.org/std/iter/trait.Iterator.html#tymethod.next
|
/// https://doc.rust-lang.org/std/iter/trait.Iterator.html#tymethod.next
|
||||||
/// ^^^^^^^^^^^^^^^^^^^
|
/// ^^^^^^^^^^^^^^^^^^^
|
||||||
/// ```
|
/// ```
|
||||||
fn get_symbol_filename(
|
fn filename_and_frag_for_def(
|
||||||
db: &dyn HirDatabase,
|
db: &dyn HirDatabase,
|
||||||
definition: Either<ModuleDef, MacroDef>,
|
def: Definition,
|
||||||
) -> Option<String> {
|
) -> Option<(Definition, String, Option<String>)> {
|
||||||
let res = match definition {
|
if let Some(assoc_item) = def.as_assoc_item(db) {
|
||||||
Either::Left(definition) => match definition {
|
let def = match assoc_item.container(db) {
|
||||||
ModuleDef::Adt(adt) => match adt {
|
AssocItemContainer::Trait(t) => t.into(),
|
||||||
|
AssocItemContainer::Impl(i) => i.self_ty(db).as_adt()?.into(),
|
||||||
|
};
|
||||||
|
let (_, file, _) = filename_and_frag_for_def(db, def)?;
|
||||||
|
let frag = get_assoc_item_fragment(db, assoc_item)?;
|
||||||
|
return Some((def, file, Some(frag)));
|
||||||
|
}
|
||||||
|
|
||||||
|
let res = match def {
|
||||||
|
Definition::Adt(adt) => match adt {
|
||||||
Adt::Struct(s) => format!("struct.{}.html", s.name(db)),
|
Adt::Struct(s) => format!("struct.{}.html", s.name(db)),
|
||||||
Adt::Enum(e) => format!("enum.{}.html", e.name(db)),
|
Adt::Enum(e) => format!("enum.{}.html", e.name(db)),
|
||||||
Adt::Union(u) => format!("union.{}.html", u.name(db)),
|
Adt::Union(u) => format!("union.{}.html", u.name(db)),
|
||||||
},
|
},
|
||||||
ModuleDef::Module(m) => match m.name(db) {
|
Definition::Module(m) => match m.name(db) {
|
||||||
Some(name) => format!("{}/index.html", name),
|
Some(name) => format!("{}/index.html", name),
|
||||||
None => String::from("index.html"),
|
None => String::from("index.html"),
|
||||||
},
|
},
|
||||||
ModuleDef::Trait(t) => format!("trait.{}.html", t.name(db)),
|
Definition::Trait(t) => format!("trait.{}.html", t.name(db)),
|
||||||
ModuleDef::TypeAlias(t) => format!("type.{}.html", t.name(db)),
|
Definition::TypeAlias(t) => format!("type.{}.html", t.name(db)),
|
||||||
ModuleDef::BuiltinType(t) => format!("primitive.{}.html", t.name()),
|
Definition::BuiltinType(t) => format!("primitive.{}.html", t.name()),
|
||||||
ModuleDef::Function(f) => format!("fn.{}.html", f.name(db)),
|
Definition::Function(f) => format!("fn.{}.html", f.name(db)),
|
||||||
ModuleDef::Variant(ev) => {
|
Definition::Variant(ev) => {
|
||||||
format!("enum.{}.html#variant.{}", ev.parent_enum(db).name(db), ev.name(db))
|
format!("enum.{}.html#variant.{}", ev.parent_enum(db).name(db), ev.name(db))
|
||||||
}
|
}
|
||||||
ModuleDef::Const(c) => format!("const.{}.html", c.name(db)?),
|
Definition::Const(c) => format!("const.{}.html", c.name(db)?),
|
||||||
ModuleDef::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)?),
|
||||||
Either::Right(mac) => format!("macro.{}.html", mac.name(db)?),
|
Definition::Field(field) => {
|
||||||
|
let def = match field.parent_def(db) {
|
||||||
|
hir::VariantDef::Struct(it) => Definition::Adt(it.into()),
|
||||||
|
hir::VariantDef::Union(it) => Definition::Adt(it.into()),
|
||||||
|
hir::VariantDef::Variant(it) => Definition::Variant(it),
|
||||||
};
|
};
|
||||||
Some(res)
|
let (_, file, _) = filename_and_frag_for_def(db, def)?;
|
||||||
|
return Some((def, file, Some(format!("structfield.{}", field.name(db)))));
|
||||||
|
}
|
||||||
|
Definition::SelfType(impl_) => {
|
||||||
|
let adt = impl_.self_ty(db).as_adt()?.into();
|
||||||
|
let (_, file, _) = filename_and_frag_for_def(db, adt)?;
|
||||||
|
// FIXME fragment numbering
|
||||||
|
return Some((adt, file, Some(String::from("impl"))));
|
||||||
|
}
|
||||||
|
Definition::Local(_) => return None,
|
||||||
|
Definition::GenericParam(_) => return None,
|
||||||
|
Definition::Label(_) => return None,
|
||||||
|
};
|
||||||
|
|
||||||
|
Some((def, res, None))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the fragment required to link to a specific field, method, associated type, or associated constant.
|
/// Get the fragment required to link to a specific field, method, associated type, or associated constant.
|
||||||
@@ -803,8 +777,6 @@ pub struct B$0ar
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rewrite_on_field() {
|
fn rewrite_on_field() {
|
||||||
// FIXME: Should be
|
|
||||||
// [Foo](https://docs.rs/test/*/test/struct.Foo.html)
|
|
||||||
check_rewrite(
|
check_rewrite(
|
||||||
r#"
|
r#"
|
||||||
//- /main.rs crate:foo
|
//- /main.rs crate:foo
|
||||||
@@ -813,7 +785,7 @@ pub struct Foo {
|
|||||||
fie$0ld: ()
|
fie$0ld: ()
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
expect"#]],
|
expect"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -927,17 +899,17 @@ pub struct $0Foo;
|
|||||||
) -> Option<Option<(Option<hir::Documentation>, Definition)>> {
|
) -> Option<Option<(Option<hir::Documentation>, Definition)>> {
|
||||||
Some(match_ast! {
|
Some(match_ast! {
|
||||||
match node {
|
match node {
|
||||||
ast::SourceFile(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::ModuleDef(hir::ModuleDef::Module(def)))),
|
ast::SourceFile(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::Module(def))),
|
||||||
ast::Module(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::ModuleDef(hir::ModuleDef::Module(def)))),
|
ast::Module(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::Module(def))),
|
||||||
ast::Fn(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::ModuleDef(hir::ModuleDef::Function(def)))),
|
ast::Fn(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::Function(def))),
|
||||||
ast::Struct(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::ModuleDef(hir::ModuleDef::Adt(hir::Adt::Struct(def))))),
|
ast::Struct(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::Adt(hir::Adt::Struct(def)))),
|
||||||
ast::Union(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::ModuleDef(hir::ModuleDef::Adt(hir::Adt::Union(def))))),
|
ast::Union(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::Adt(hir::Adt::Union(def)))),
|
||||||
ast::Enum(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::ModuleDef(hir::ModuleDef::Adt(hir::Adt::Enum(def))))),
|
ast::Enum(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::Adt(hir::Adt::Enum(def)))),
|
||||||
ast::Variant(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::ModuleDef(hir::ModuleDef::Variant(def)))),
|
ast::Variant(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::Variant(def))),
|
||||||
ast::Trait(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::ModuleDef(hir::ModuleDef::Trait(def)))),
|
ast::Trait(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::Trait(def))),
|
||||||
ast::Static(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::ModuleDef(hir::ModuleDef::Static(def)))),
|
ast::Static(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::Static(def))),
|
||||||
ast::Const(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::ModuleDef(hir::ModuleDef::Const(def)))),
|
ast::Const(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::Const(def))),
|
||||||
ast::TypeAlias(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::ModuleDef(hir::ModuleDef::TypeAlias(def)))),
|
ast::TypeAlias(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::TypeAlias(def))),
|
||||||
ast::Impl(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::SelfType(def))),
|
ast::Impl(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::SelfType(def))),
|
||||||
ast::RecordField(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::Field(def))),
|
ast::RecordField(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::Field(def))),
|
||||||
ast::TupleField(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::Field(def))),
|
ast::TupleField(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::Field(def))),
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ pub(crate) fn goto_declaration(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
match def? {
|
match def? {
|
||||||
Definition::ModuleDef(hir::ModuleDef::Module(module)) => {
|
Definition::Module(module) => {
|
||||||
Some(NavigationTarget::from_module_to_decl(db, module))
|
Some(NavigationTarget::from_module_to_decl(db, module))
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use std::convert::TryInto;
|
|||||||
use crate::{
|
use crate::{
|
||||||
display::TryToNav, doc_links::token_as_doc_comment, FilePosition, NavigationTarget, RangeInfo,
|
display::TryToNav, doc_links::token_as_doc_comment, FilePosition, NavigationTarget, RangeInfo,
|
||||||
};
|
};
|
||||||
use hir::{AsAssocItem, ModuleDef, Semantics};
|
use hir::{AsAssocItem, Semantics};
|
||||||
use ide_db::{
|
use ide_db::{
|
||||||
base_db::{AnchoredPath, FileId, FileLoader},
|
base_db::{AnchoredPath, FileId, FileLoader},
|
||||||
defs::Definition,
|
defs::Definition,
|
||||||
@@ -110,12 +110,7 @@ fn try_find_trait_item_definition(
|
|||||||
def: &Definition,
|
def: &Definition,
|
||||||
) -> Option<Vec<NavigationTarget>> {
|
) -> Option<Vec<NavigationTarget>> {
|
||||||
let name = def.name(db)?;
|
let name = def.name(db)?;
|
||||||
let assoc = match def {
|
let assoc = def.as_assoc_item(db)?;
|
||||||
Definition::ModuleDef(ModuleDef::Function(f)) => f.as_assoc_item(db),
|
|
||||||
Definition::ModuleDef(ModuleDef::Const(c)) => c.as_assoc_item(db),
|
|
||||||
Definition::ModuleDef(ModuleDef::TypeAlias(ty)) => ty.as_assoc_item(db),
|
|
||||||
_ => None,
|
|
||||||
}?;
|
|
||||||
|
|
||||||
let imp = match assoc.container(db) {
|
let imp = match assoc.container(db) {
|
||||||
hir::AssocItemContainer::Impl(imp) => imp,
|
hir::AssocItemContainer::Impl(imp) => imp,
|
||||||
|
|||||||
@@ -34,12 +34,11 @@ pub(crate) fn goto_implementation(
|
|||||||
_ => 0,
|
_ => 0,
|
||||||
})?;
|
})?;
|
||||||
let range = original_token.text_range();
|
let range = original_token.text_range();
|
||||||
let navs =
|
let navs = sema
|
||||||
sema.descend_into_macros(original_token)
|
.descend_into_macros(original_token)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|token| token.parent().and_then(ast::NameLike::cast))
|
.filter_map(|token| token.parent().and_then(ast::NameLike::cast))
|
||||||
.filter_map(|node| {
|
.filter_map(|node| match &node {
|
||||||
let def = match &node {
|
|
||||||
ast::NameLike::Name(name) => {
|
ast::NameLike::Name(name) => {
|
||||||
NameClass::classify(&sema, name).map(|class| match class {
|
NameClass::classify(&sema, name).map(|class| match class {
|
||||||
NameClass::Definition(it) | NameClass::ConstReference(it) => it,
|
NameClass::Definition(it) | NameClass::ConstReference(it) => it,
|
||||||
@@ -48,38 +47,33 @@ pub(crate) fn goto_implementation(
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
ast::NameLike::NameRef(name_ref) => NameRefClass::classify(&sema, name_ref)
|
ast::NameLike::NameRef(name_ref) => {
|
||||||
.map(|class| match class {
|
NameRefClass::classify(&sema, name_ref).map(|class| match class {
|
||||||
NameRefClass::Definition(def) => def,
|
NameRefClass::Definition(def) => def,
|
||||||
NameRefClass::FieldShorthand { local_ref, field_ref: _ } => {
|
NameRefClass::FieldShorthand { local_ref, field_ref: _ } => {
|
||||||
Definition::Local(local_ref)
|
Definition::Local(local_ref)
|
||||||
}
|
}
|
||||||
}),
|
})
|
||||||
ast::NameLike::Lifetime(_) => None,
|
|
||||||
}?;
|
|
||||||
|
|
||||||
match def {
|
|
||||||
Definition::ModuleDef(def) => Some(def),
|
|
||||||
_ => None,
|
|
||||||
}
|
}
|
||||||
|
ast::NameLike::Lifetime(_) => None,
|
||||||
})
|
})
|
||||||
.unique()
|
.unique()
|
||||||
.filter_map(|def| {
|
.filter_map(|def| {
|
||||||
let navs = match def {
|
let navs = match def {
|
||||||
hir::ModuleDef::Trait(trait_) => impls_for_trait(&sema, trait_),
|
Definition::Trait(trait_) => impls_for_trait(&sema, trait_),
|
||||||
hir::ModuleDef::Adt(adt) => impls_for_ty(&sema, adt.ty(sema.db)),
|
Definition::Adt(adt) => impls_for_ty(&sema, adt.ty(sema.db)),
|
||||||
hir::ModuleDef::TypeAlias(alias) => impls_for_ty(&sema, alias.ty(sema.db)),
|
Definition::TypeAlias(alias) => impls_for_ty(&sema, alias.ty(sema.db)),
|
||||||
hir::ModuleDef::BuiltinType(builtin) => {
|
Definition::BuiltinType(builtin) => {
|
||||||
let module = sema.to_module_def(position.file_id)?;
|
let module = sema.to_module_def(position.file_id)?;
|
||||||
impls_for_ty(&sema, builtin.ty(sema.db, module))
|
impls_for_ty(&sema, builtin.ty(sema.db, module))
|
||||||
}
|
}
|
||||||
hir::ModuleDef::Function(f) => {
|
Definition::Function(f) => {
|
||||||
let assoc = f.as_assoc_item(sema.db)?;
|
let assoc = f.as_assoc_item(sema.db)?;
|
||||||
let name = assoc.name(sema.db)?;
|
let name = assoc.name(sema.db)?;
|
||||||
let trait_ = assoc.containing_trait_or_trait_impl(sema.db)?;
|
let trait_ = assoc.containing_trait_or_trait_impl(sema.db)?;
|
||||||
impls_for_trait_item(&sema, trait_, name)
|
impls_for_trait_item(&sema, trait_, name)
|
||||||
}
|
}
|
||||||
hir::ModuleDef::Const(c) => {
|
Definition::Const(c) => {
|
||||||
let assoc = c.as_assoc_item(sema.db)?;
|
let assoc = c.as_assoc_item(sema.db)?;
|
||||||
let name = assoc.name(sema.db)?;
|
let name = assoc.name(sema.db)?;
|
||||||
let trait_ = assoc.containing_trait_or_trait_impl(sema.db)?;
|
let trait_ = assoc.containing_trait_or_trait_impl(sema.db)?;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use ide_db::{base_db::Upcast, helpers::pick_best_token, RootDatabase};
|
use ide_db::{base_db::Upcast, defs::Definition, helpers::pick_best_token, RootDatabase};
|
||||||
use syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxToken, T};
|
use syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxToken, T};
|
||||||
|
|
||||||
use crate::{display::TryToNav, FilePosition, NavigationTarget, RangeInfo};
|
use crate::{display::TryToNav, FilePosition, NavigationTarget, RangeInfo};
|
||||||
@@ -29,7 +29,7 @@ pub(crate) fn goto_type_definition(
|
|||||||
})?;
|
})?;
|
||||||
|
|
||||||
let mut res = Vec::new();
|
let mut res = Vec::new();
|
||||||
let mut push = |def: hir::ModuleDef| {
|
let mut push = |def: Definition| {
|
||||||
if let Some(nav) = def.try_to_nav(db) {
|
if let Some(nav) = def.try_to_nav(db) {
|
||||||
if !res.contains(&nav) {
|
if !res.contains(&nav) {
|
||||||
res.push(nav);
|
res.push(nav);
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ fn highlight_references(
|
|||||||
|
|
||||||
let declarations = defs.iter().flat_map(|def| {
|
let declarations = defs.iter().flat_map(|def| {
|
||||||
match def {
|
match def {
|
||||||
&Definition::ModuleDef(hir::ModuleDef::Module(module)) => {
|
&Definition::Module(module) => {
|
||||||
Some(NavigationTarget::from_module_to_decl(sema.db, module))
|
Some(NavigationTarget::from_module_to_decl(sema.db, module))
|
||||||
}
|
}
|
||||||
def => def.try_to_nav(sema.db),
|
def => def.try_to_nav(sema.db),
|
||||||
|
|||||||
@@ -163,9 +163,7 @@ pub(crate) fn hover_for_definition(
|
|||||||
config: &HoverConfig,
|
config: &HoverConfig,
|
||||||
) -> Option<HoverResult> {
|
) -> Option<HoverResult> {
|
||||||
let famous_defs = match &definition {
|
let famous_defs = match &definition {
|
||||||
Definition::ModuleDef(hir::ModuleDef::BuiltinType(_)) => {
|
Definition::BuiltinType(_) => Some(FamousDefs(sema, sema.scope(node).krate())),
|
||||||
Some(FamousDefs(sema, sema.scope(node).krate()))
|
|
||||||
}
|
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
if let Some(markup) = render::definition(sema.db, definition, famous_defs.as_ref(), config) {
|
if let Some(markup) = render::definition(sema.db, definition, famous_defs.as_ref(), config) {
|
||||||
@@ -260,10 +258,8 @@ fn show_implementations_action(db: &RootDatabase, def: Definition) -> Option<Hov
|
|||||||
}
|
}
|
||||||
|
|
||||||
let adt = match def {
|
let adt = match def {
|
||||||
Definition::ModuleDef(hir::ModuleDef::Trait(it)) => {
|
Definition::Trait(it) => return it.try_to_nav(db).map(to_action),
|
||||||
return it.try_to_nav(db).map(to_action)
|
Definition::Adt(it) => Some(it),
|
||||||
}
|
|
||||||
Definition::ModuleDef(hir::ModuleDef::Adt(it)) => Some(it),
|
|
||||||
Definition::SelfType(it) => it.self_ty(db).as_adt(),
|
Definition::SelfType(it) => it.self_ty(db).as_adt(),
|
||||||
_ => None,
|
_ => None,
|
||||||
}?;
|
}?;
|
||||||
@@ -272,14 +268,12 @@ fn show_implementations_action(db: &RootDatabase, def: Definition) -> Option<Hov
|
|||||||
|
|
||||||
fn show_fn_references_action(db: &RootDatabase, def: Definition) -> Option<HoverAction> {
|
fn show_fn_references_action(db: &RootDatabase, def: Definition) -> Option<HoverAction> {
|
||||||
match def {
|
match def {
|
||||||
Definition::ModuleDef(hir::ModuleDef::Function(it)) => {
|
Definition::Function(it) => it.try_to_nav(db).map(|nav_target| {
|
||||||
it.try_to_nav(db).map(|nav_target| {
|
|
||||||
HoverAction::Reference(FilePosition {
|
HoverAction::Reference(FilePosition {
|
||||||
file_id: nav_target.file_id,
|
file_id: nav_target.file_id,
|
||||||
offset: nav_target.focus_or_full_range().start(),
|
offset: nav_target.focus_or_full_range().start(),
|
||||||
})
|
})
|
||||||
})
|
}),
|
||||||
}
|
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -290,9 +284,8 @@ fn runnable_action(
|
|||||||
file_id: FileId,
|
file_id: FileId,
|
||||||
) -> Option<HoverAction> {
|
) -> Option<HoverAction> {
|
||||||
match def {
|
match def {
|
||||||
Definition::ModuleDef(it) => match it {
|
Definition::Module(it) => runnable_mod(sema, it).map(HoverAction::Runnable),
|
||||||
hir::ModuleDef::Module(it) => runnable_mod(sema, it).map(HoverAction::Runnable),
|
Definition::Function(func) => {
|
||||||
hir::ModuleDef::Function(func) => {
|
|
||||||
let src = func.source(sema.db)?;
|
let src = func.source(sema.db)?;
|
||||||
if src.file_id != file_id.into() {
|
if src.file_id != file_id.into() {
|
||||||
cov_mark::hit!(hover_macro_generated_struct_fn_doc_comment);
|
cov_mark::hit!(hover_macro_generated_struct_fn_doc_comment);
|
||||||
@@ -303,8 +296,6 @@ fn runnable_action(
|
|||||||
runnable_fn(sema, func).map(HoverAction::Runnable)
|
runnable_fn(sema, func).map(HoverAction::Runnable)
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
},
|
|
||||||
_ => None,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -242,7 +242,7 @@ pub(super) fn keyword(
|
|||||||
let docs = doc_owner.attrs(sema.db).docs()?;
|
let docs = doc_owner.attrs(sema.db).docs()?;
|
||||||
let markup = process_markup(
|
let markup = process_markup(
|
||||||
sema.db,
|
sema.db,
|
||||||
Definition::ModuleDef(doc_owner.into()),
|
Definition::Module(doc_owner),
|
||||||
&markup(Some(docs.into()), token.text().into(), None)?,
|
&markup(Some(docs.into()), token.text().into(), None)?,
|
||||||
config,
|
config,
|
||||||
);
|
);
|
||||||
@@ -311,14 +311,11 @@ fn definition_owner_name(db: &RootDatabase, def: &Definition) -> Option<String>
|
|||||||
match def {
|
match def {
|
||||||
Definition::Field(f) => Some(f.parent_def(db).name(db)),
|
Definition::Field(f) => Some(f.parent_def(db).name(db)),
|
||||||
Definition::Local(l) => l.parent(db).name(db),
|
Definition::Local(l) => l.parent(db).name(db),
|
||||||
Definition::ModuleDef(md) => match md {
|
Definition::Function(f) => match f.as_assoc_item(db)?.container(db) {
|
||||||
hir::ModuleDef::Function(f) => match f.as_assoc_item(db)?.container(db) {
|
|
||||||
hir::AssocItemContainer::Trait(t) => Some(t.name(db)),
|
hir::AssocItemContainer::Trait(t) => Some(t.name(db)),
|
||||||
hir::AssocItemContainer::Impl(i) => i.self_ty(db).as_adt().map(|adt| adt.name(db)),
|
hir::AssocItemContainer::Impl(i) => i.self_ty(db).as_adt().map(|adt| adt.name(db)),
|
||||||
},
|
},
|
||||||
hir::ModuleDef::Variant(e) => Some(e.parent_enum(db).name(db)),
|
Definition::Variant(e) => Some(e.parent_enum(db).name(db)),
|
||||||
_ => None,
|
|
||||||
},
|
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
.map(|name| name.to_string())
|
.map(|name| name.to_string())
|
||||||
@@ -351,21 +348,19 @@ pub(super) fn definition(
|
|||||||
it.attrs(db).docs(),
|
it.attrs(db).docs(),
|
||||||
),
|
),
|
||||||
Definition::Field(def) => label_and_docs(db, def),
|
Definition::Field(def) => label_and_docs(db, def),
|
||||||
Definition::ModuleDef(it) => match it {
|
Definition::Module(it) => label_and_docs(db, it),
|
||||||
hir::ModuleDef::Module(it) => label_and_docs(db, it),
|
Definition::Function(it) => label_and_docs(db, it),
|
||||||
hir::ModuleDef::Function(it) => label_and_docs(db, it),
|
Definition::Adt(it) => label_and_docs(db, it),
|
||||||
hir::ModuleDef::Adt(it) => label_and_docs(db, it),
|
Definition::Variant(it) => label_and_docs(db, it),
|
||||||
hir::ModuleDef::Variant(it) => label_and_docs(db, it),
|
Definition::Const(it) => label_and_docs(db, it),
|
||||||
hir::ModuleDef::Const(it) => label_and_docs(db, it),
|
Definition::Static(it) => label_and_docs(db, it),
|
||||||
hir::ModuleDef::Static(it) => label_and_docs(db, it),
|
Definition::Trait(it) => label_and_docs(db, it),
|
||||||
hir::ModuleDef::Trait(it) => label_and_docs(db, it),
|
Definition::TypeAlias(it) => label_and_docs(db, it),
|
||||||
hir::ModuleDef::TypeAlias(it) => label_and_docs(db, it),
|
Definition::BuiltinType(it) => {
|
||||||
hir::ModuleDef::BuiltinType(it) => {
|
|
||||||
return famous_defs
|
return famous_defs
|
||||||
.and_then(|fd| builtin(fd, it))
|
.and_then(|fd| builtin(fd, it))
|
||||||
.or_else(|| Some(Markup::fenced_block(&it.name())))
|
.or_else(|| Some(Markup::fenced_block(&it.name())))
|
||||||
}
|
}
|
||||||
},
|
|
||||||
Definition::Local(it) => return local(db, it),
|
Definition::Local(it) => return local(db, it),
|
||||||
Definition::SelfType(impl_def) => {
|
Definition::SelfType(impl_def) => {
|
||||||
impl_def.self_ty(db).as_adt().map(|adt| label_and_docs(db, adt))?
|
impl_def.self_ty(db).as_adt().map(|adt| label_and_docs(db, adt))?
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ pub(crate) fn find_all_refs(
|
|||||||
let mut usages =
|
let mut usages =
|
||||||
def.usages(sema).set_scope(search_scope.clone()).include_self_refs().all();
|
def.usages(sema).set_scope(search_scope.clone()).include_self_refs().all();
|
||||||
let declaration = match def {
|
let declaration = match def {
|
||||||
Definition::ModuleDef(hir::ModuleDef::Module(module)) => {
|
Definition::Module(module) => {
|
||||||
Some(NavigationTarget::from_module_to_decl(sema.db, module))
|
Some(NavigationTarget::from_module_to_decl(sema.db, module))
|
||||||
}
|
}
|
||||||
def => def.try_to_nav(sema.db),
|
def => def.try_to_nav(sema.db),
|
||||||
@@ -168,7 +168,7 @@ fn retain_adt_literal_usages(
|
|||||||
) {
|
) {
|
||||||
let refs = usages.references.values_mut();
|
let refs = usages.references.values_mut();
|
||||||
match def {
|
match def {
|
||||||
Definition::ModuleDef(hir::ModuleDef::Adt(hir::Adt::Enum(enum_))) => {
|
Definition::Adt(hir::Adt::Enum(enum_)) => {
|
||||||
refs.for_each(|it| {
|
refs.for_each(|it| {
|
||||||
it.retain(|reference| {
|
it.retain(|reference| {
|
||||||
reference
|
reference
|
||||||
@@ -179,7 +179,7 @@ fn retain_adt_literal_usages(
|
|||||||
});
|
});
|
||||||
usages.references.retain(|_, it| !it.is_empty());
|
usages.references.retain(|_, it| !it.is_empty());
|
||||||
}
|
}
|
||||||
Definition::ModuleDef(hir::ModuleDef::Adt(_) | hir::ModuleDef::Variant(_)) => {
|
Definition::Adt(_) | Definition::Variant(_) => {
|
||||||
refs.for_each(|it| {
|
refs.for_each(|it| {
|
||||||
it.retain(|reference| reference.name.as_name_ref().map_or(false, is_lit_name_ref))
|
it.retain(|reference| reference.name.as_name_ref().map_or(false, is_lit_name_ref))
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ pub(crate) fn will_rename_file(
|
|||||||
) -> Option<SourceChange> {
|
) -> Option<SourceChange> {
|
||||||
let sema = Semantics::new(db);
|
let sema = Semantics::new(db);
|
||||||
let module = sema.to_module_def(file_id)?;
|
let module = sema.to_module_def(file_id)?;
|
||||||
let def = Definition::ModuleDef(module.into());
|
let def = Definition::Module(module);
|
||||||
let mut change = def.rename(&sema, new_name_stem).ok()?;
|
let mut change = def.rename(&sema, new_name_stem).ok()?;
|
||||||
change.file_system_edits.clear();
|
change.file_system_edits.clear();
|
||||||
Some(change)
|
Some(change)
|
||||||
|
|||||||
@@ -246,7 +246,7 @@ fn node(
|
|||||||
fn highlight_name_ref_in_attr(sema: &Semantics<RootDatabase>, name_ref: ast::NameRef) -> Highlight {
|
fn highlight_name_ref_in_attr(sema: &Semantics<RootDatabase>, name_ref: ast::NameRef) -> Highlight {
|
||||||
match NameRefClass::classify(sema, &name_ref) {
|
match NameRefClass::classify(sema, &name_ref) {
|
||||||
Some(name_class) => match name_class {
|
Some(name_class) => match name_class {
|
||||||
NameRefClass::Definition(Definition::ModuleDef(hir::ModuleDef::Module(_)))
|
NameRefClass::Definition(Definition::Module(_))
|
||||||
if name_ref
|
if name_ref
|
||||||
.syntax()
|
.syntax()
|
||||||
.ancestors()
|
.ancestors()
|
||||||
@@ -302,9 +302,7 @@ fn highlight_name_ref(
|
|||||||
{
|
{
|
||||||
h |= HlMod::Consuming;
|
h |= HlMod::Consuming;
|
||||||
}
|
}
|
||||||
Definition::ModuleDef(hir::ModuleDef::Trait(trait_))
|
Definition::Trait(trait_) if trait_.is_unsafe(db) => {
|
||||||
if trait_.is_unsafe(db) =>
|
|
||||||
{
|
|
||||||
if ast::Impl::for_trait_name_ref(&name_ref)
|
if ast::Impl::for_trait_name_ref(&name_ref)
|
||||||
.map_or(false, |impl_| impl_.unsafe_token().is_some())
|
.map_or(false, |impl_| impl_.unsafe_token().is_some())
|
||||||
{
|
{
|
||||||
@@ -358,7 +356,7 @@ fn highlight_name(
|
|||||||
match name_kind {
|
match name_kind {
|
||||||
Some(NameClass::Definition(def)) => {
|
Some(NameClass::Definition(def)) => {
|
||||||
let mut h = highlight_def(sema, krate, def) | HlMod::Definition;
|
let mut h = highlight_def(sema, krate, def) | HlMod::Definition;
|
||||||
if let Definition::ModuleDef(hir::ModuleDef::Trait(trait_)) = &def {
|
if let Definition::Trait(trait_) = &def {
|
||||||
if trait_.is_unsafe(db) {
|
if trait_.is_unsafe(db) {
|
||||||
h |= HlMod::Unsafe;
|
h |= HlMod::Unsafe;
|
||||||
}
|
}
|
||||||
@@ -398,15 +396,14 @@ fn highlight_def(
|
|||||||
let mut h = match def {
|
let mut h = match def {
|
||||||
Definition::Macro(_) => Highlight::new(HlTag::Symbol(SymbolKind::Macro)),
|
Definition::Macro(_) => Highlight::new(HlTag::Symbol(SymbolKind::Macro)),
|
||||||
Definition::Field(_) => Highlight::new(HlTag::Symbol(SymbolKind::Field)),
|
Definition::Field(_) => Highlight::new(HlTag::Symbol(SymbolKind::Field)),
|
||||||
Definition::ModuleDef(def) => match def {
|
Definition::Module(module) => {
|
||||||
hir::ModuleDef::Module(module) => {
|
|
||||||
let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Module));
|
let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Module));
|
||||||
if module.parent(db).is_none() {
|
if module.parent(db).is_none() {
|
||||||
h |= HlMod::CrateRoot
|
h |= HlMod::CrateRoot
|
||||||
}
|
}
|
||||||
h
|
h
|
||||||
}
|
}
|
||||||
hir::ModuleDef::Function(func) => {
|
Definition::Function(func) => {
|
||||||
let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Function));
|
let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Function));
|
||||||
if let Some(item) = func.as_assoc_item(db) {
|
if let Some(item) = func.as_assoc_item(db) {
|
||||||
h |= HlMod::Associated;
|
h |= HlMod::Associated;
|
||||||
@@ -443,7 +440,7 @@ fn highlight_def(
|
|||||||
|
|
||||||
h
|
h
|
||||||
}
|
}
|
||||||
hir::ModuleDef::Adt(adt) => {
|
Definition::Adt(adt) => {
|
||||||
let h = match adt {
|
let h = match adt {
|
||||||
hir::Adt::Struct(_) => HlTag::Symbol(SymbolKind::Struct),
|
hir::Adt::Struct(_) => HlTag::Symbol(SymbolKind::Struct),
|
||||||
hir::Adt::Enum(_) => HlTag::Symbol(SymbolKind::Enum),
|
hir::Adt::Enum(_) => HlTag::Symbol(SymbolKind::Enum),
|
||||||
@@ -452,8 +449,8 @@ fn highlight_def(
|
|||||||
|
|
||||||
Highlight::new(h)
|
Highlight::new(h)
|
||||||
}
|
}
|
||||||
hir::ModuleDef::Variant(_) => Highlight::new(HlTag::Symbol(SymbolKind::Variant)),
|
Definition::Variant(_) => Highlight::new(HlTag::Symbol(SymbolKind::Variant)),
|
||||||
hir::ModuleDef::Const(konst) => {
|
Definition::Const(konst) => {
|
||||||
let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Const));
|
let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Const));
|
||||||
|
|
||||||
if let Some(item) = konst.as_assoc_item(db) {
|
if let Some(item) = konst.as_assoc_item(db) {
|
||||||
@@ -472,8 +469,8 @@ fn highlight_def(
|
|||||||
|
|
||||||
h
|
h
|
||||||
}
|
}
|
||||||
hir::ModuleDef::Trait(_) => Highlight::new(HlTag::Symbol(SymbolKind::Trait)),
|
Definition::Trait(_) => Highlight::new(HlTag::Symbol(SymbolKind::Trait)),
|
||||||
hir::ModuleDef::TypeAlias(type_) => {
|
Definition::TypeAlias(type_) => {
|
||||||
let mut h = Highlight::new(HlTag::Symbol(SymbolKind::TypeAlias));
|
let mut h = Highlight::new(HlTag::Symbol(SymbolKind::TypeAlias));
|
||||||
|
|
||||||
if let Some(item) = type_.as_assoc_item(db) {
|
if let Some(item) = type_.as_assoc_item(db) {
|
||||||
@@ -492,8 +489,8 @@ fn highlight_def(
|
|||||||
|
|
||||||
h
|
h
|
||||||
}
|
}
|
||||||
hir::ModuleDef::BuiltinType(_) => Highlight::new(HlTag::BuiltinType),
|
Definition::BuiltinType(_) => Highlight::new(HlTag::BuiltinType),
|
||||||
hir::ModuleDef::Static(s) => {
|
Definition::Static(s) => {
|
||||||
let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Static));
|
let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Static));
|
||||||
|
|
||||||
if s.is_mut(db) {
|
if s.is_mut(db) {
|
||||||
@@ -503,7 +500,6 @@ fn highlight_def(
|
|||||||
|
|
||||||
h
|
h
|
||||||
}
|
}
|
||||||
},
|
|
||||||
Definition::SelfType(_) => Highlight::new(HlTag::Symbol(SymbolKind::Impl)),
|
Definition::SelfType(_) => Highlight::new(HlTag::Symbol(SymbolKind::Impl)),
|
||||||
Definition::GenericParam(it) => match it {
|
Definition::GenericParam(it) => match it {
|
||||||
hir::GenericParam::TypeParam(_) => Highlight::new(HlTag::Symbol(SymbolKind::TypeParam)),
|
hir::GenericParam::TypeParam(_) => Highlight::new(HlTag::Symbol(SymbolKind::TypeParam)),
|
||||||
@@ -540,13 +536,13 @@ fn highlight_def(
|
|||||||
|
|
||||||
let famous_defs = FamousDefs(sema, krate);
|
let famous_defs = FamousDefs(sema, krate);
|
||||||
let def_crate = def.module(db).map(hir::Module::krate).or_else(|| match def {
|
let def_crate = def.module(db).map(hir::Module::krate).or_else(|| match def {
|
||||||
Definition::ModuleDef(hir::ModuleDef::Module(module)) => Some(module.krate()),
|
Definition::Module(module) => Some(module.krate()),
|
||||||
_ => None,
|
_ => None,
|
||||||
});
|
});
|
||||||
let is_from_other_crate = def_crate != krate;
|
let is_from_other_crate = def_crate != krate;
|
||||||
let is_from_builtin_crate =
|
let is_from_builtin_crate =
|
||||||
def_crate.map_or(false, |def_crate| famous_defs.builtin_crates().any(|it| def_crate == it));
|
def_crate.map_or(false, |def_crate| famous_defs.builtin_crates().any(|it| def_crate == it));
|
||||||
let is_builtin_type = matches!(def, Definition::ModuleDef(hir::ModuleDef::BuiltinType(_)));
|
let is_builtin_type = matches!(def, Definition::BuiltinType(_));
|
||||||
let is_public = def.visibility(db) == Some(hir::Visibility::Public);
|
let is_public = def.visibility(db) == Some(hir::Visibility::Public);
|
||||||
|
|
||||||
match (is_from_other_crate, is_builtin_type, is_public) {
|
match (is_from_other_crate, is_builtin_type, is_public) {
|
||||||
|
|||||||
@@ -4,7 +4,9 @@ use std::mem;
|
|||||||
|
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use hir::{InFile, Semantics};
|
use hir::{InFile, Semantics};
|
||||||
use ide_db::{call_info::ActiveParameter, helpers::rust_doc::is_rust_fence, SymbolKind};
|
use ide_db::{
|
||||||
|
call_info::ActiveParameter, defs::Definition, helpers::rust_doc::is_rust_fence, SymbolKind,
|
||||||
|
};
|
||||||
use syntax::{
|
use syntax::{
|
||||||
ast::{self, AstNode, IsString},
|
ast::{self, AstNode, IsString},
|
||||||
AstToken, NodeOrToken, SyntaxNode, SyntaxToken, TextRange, TextSize,
|
AstToken, NodeOrToken, SyntaxNode, SyntaxToken, TextRange, TextSize,
|
||||||
@@ -237,22 +239,29 @@ fn find_doc_string_in_attr(attr: &hir::Attr, it: &ast::Attr) -> Option<ast::Stri
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn module_def_to_hl_tag(def: Either<hir::ModuleDef, hir::MacroDef>) -> HlTag {
|
fn module_def_to_hl_tag(def: Definition) -> HlTag {
|
||||||
let symbol = match def {
|
let symbol = match def {
|
||||||
Either::Left(def) => match def {
|
Definition::Module(_) => SymbolKind::Module,
|
||||||
hir::ModuleDef::Module(_) => SymbolKind::Module,
|
Definition::Function(_) => SymbolKind::Function,
|
||||||
hir::ModuleDef::Function(_) => SymbolKind::Function,
|
Definition::Adt(hir::Adt::Struct(_)) => SymbolKind::Struct,
|
||||||
hir::ModuleDef::Adt(hir::Adt::Struct(_)) => SymbolKind::Struct,
|
Definition::Adt(hir::Adt::Enum(_)) => SymbolKind::Enum,
|
||||||
hir::ModuleDef::Adt(hir::Adt::Enum(_)) => SymbolKind::Enum,
|
Definition::Adt(hir::Adt::Union(_)) => SymbolKind::Union,
|
||||||
hir::ModuleDef::Adt(hir::Adt::Union(_)) => SymbolKind::Union,
|
Definition::Variant(_) => SymbolKind::Variant,
|
||||||
hir::ModuleDef::Variant(_) => SymbolKind::Variant,
|
Definition::Const(_) => SymbolKind::Const,
|
||||||
hir::ModuleDef::Const(_) => SymbolKind::Const,
|
Definition::Static(_) => SymbolKind::Static,
|
||||||
hir::ModuleDef::Static(_) => SymbolKind::Static,
|
Definition::Trait(_) => SymbolKind::Trait,
|
||||||
hir::ModuleDef::Trait(_) => SymbolKind::Trait,
|
Definition::TypeAlias(_) => SymbolKind::TypeAlias,
|
||||||
hir::ModuleDef::TypeAlias(_) => SymbolKind::TypeAlias,
|
Definition::BuiltinType(_) => return HlTag::BuiltinType,
|
||||||
hir::ModuleDef::BuiltinType(_) => return HlTag::BuiltinType,
|
Definition::Macro(_) => SymbolKind::Macro,
|
||||||
|
Definition::Field(_) => SymbolKind::Field,
|
||||||
|
Definition::SelfType(_) => SymbolKind::Impl,
|
||||||
|
Definition::Local(_) => SymbolKind::Local,
|
||||||
|
Definition::GenericParam(gp) => match gp {
|
||||||
|
hir::GenericParam::TypeParam(_) => SymbolKind::TypeParam,
|
||||||
|
hir::GenericParam::LifetimeParam(_) => SymbolKind::LifetimeParam,
|
||||||
|
hir::GenericParam::ConstParam(_) => SymbolKind::ConstParam,
|
||||||
},
|
},
|
||||||
Either::Right(_) => SymbolKind::Macro,
|
Definition::Label(_) => SymbolKind::Label,
|
||||||
};
|
};
|
||||||
HlTag::Symbol(symbol)
|
HlTag::Symbol(symbol)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext) -> Option<(
|
|||||||
NameRefClass::FieldShorthand { .. } => return None,
|
NameRefClass::FieldShorthand { .. } => return None,
|
||||||
};
|
};
|
||||||
let fun = match def {
|
let fun = match def {
|
||||||
Definition::ModuleDef(hir::ModuleDef::Function(it)) => it,
|
Definition::Function(it) => it,
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
let generics = hir::GenericDef::Function(fun).params(ctx.sema.db);
|
let generics = hir::GenericDef::Function(fun).params(ctx.sema.db);
|
||||||
|
|||||||
@@ -127,8 +127,8 @@ fn edit_struct_references(
|
|||||||
names: &[ast::Name],
|
names: &[ast::Name],
|
||||||
) {
|
) {
|
||||||
let strukt_def = match strukt {
|
let strukt_def = match strukt {
|
||||||
Either::Left(s) => Definition::ModuleDef(hir::ModuleDef::Adt(hir::Adt::Struct(s))),
|
Either::Left(s) => Definition::Adt(hir::Adt::Struct(s)),
|
||||||
Either::Right(v) => Definition::ModuleDef(hir::ModuleDef::Variant(v)),
|
Either::Right(v) => Definition::Variant(v),
|
||||||
};
|
};
|
||||||
let usages = strukt_def.usages(&ctx.sema).include_self_refs().all();
|
let usages = strukt_def.usages(&ctx.sema).include_self_refs().all();
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use either::Either;
|
use either::Either;
|
||||||
use hir::{AssocItem, HasVisibility, MacroDef, Module, ModuleDef, Name, PathResolution, ScopeDef};
|
use hir::{AssocItem, HasVisibility, Module, ModuleDef, Name, PathResolution, ScopeDef};
|
||||||
use ide_db::{
|
use ide_db::{
|
||||||
defs::{Definition, NameRefClass},
|
defs::{Definition, NameRefClass},
|
||||||
search::SearchScope,
|
search::SearchScope,
|
||||||
@@ -112,36 +112,27 @@ fn find_parent_and_path(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
fn def_is_referenced_in(def: Definition, ctx: &AssistContext) -> bool {
|
||||||
enum Def {
|
|
||||||
ModuleDef(ModuleDef),
|
|
||||||
MacroDef(MacroDef),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Def {
|
|
||||||
fn is_referenced_in(&self, ctx: &AssistContext) -> bool {
|
|
||||||
let def = match self {
|
|
||||||
Def::ModuleDef(def) => Definition::ModuleDef(*def),
|
|
||||||
Def::MacroDef(def) => Definition::Macro(*def),
|
|
||||||
};
|
|
||||||
|
|
||||||
let search_scope = SearchScope::single_file(ctx.file_id());
|
let search_scope = SearchScope::single_file(ctx.file_id());
|
||||||
def.usages(&ctx.sema).in_scope(search_scope).at_least_one()
|
def.usages(&ctx.sema).in_scope(search_scope).at_least_one()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct Ref {
|
struct Ref {
|
||||||
// could be alias
|
// could be alias
|
||||||
visible_name: Name,
|
visible_name: Name,
|
||||||
def: Def,
|
def: Definition,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ref {
|
impl Ref {
|
||||||
fn from_scope_def(name: Name, scope_def: ScopeDef) -> Option<Self> {
|
fn from_scope_def(name: Name, scope_def: ScopeDef) -> Option<Self> {
|
||||||
match scope_def {
|
match scope_def {
|
||||||
ScopeDef::ModuleDef(def) => Some(Ref { visible_name: name, def: Def::ModuleDef(def) }),
|
ScopeDef::ModuleDef(def) => {
|
||||||
ScopeDef::MacroDef(def) => Some(Ref { visible_name: name, def: Def::MacroDef(def) }),
|
Some(Ref { visible_name: name, def: Definition::from(def) })
|
||||||
|
}
|
||||||
|
ScopeDef::MacroDef(def) => {
|
||||||
|
Some(Ref { visible_name: name, def: Definition::Macro(def) })
|
||||||
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -157,10 +148,10 @@ impl Refs {
|
|||||||
.clone()
|
.clone()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|r| {
|
.filter(|r| {
|
||||||
if let Def::ModuleDef(ModuleDef::Trait(tr)) = r.def {
|
if let Definition::Trait(tr) = r.def {
|
||||||
if tr.items(ctx.db()).into_iter().any(|ai| {
|
if tr.items(ctx.db()).into_iter().any(|ai| {
|
||||||
if let AssocItem::Function(f) = ai {
|
if let AssocItem::Function(f) = ai {
|
||||||
Def::ModuleDef(ModuleDef::Function(f)).is_referenced_in(ctx)
|
def_is_referenced_in(Definition::Function(f), ctx)
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
@@ -169,13 +160,13 @@ impl Refs {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r.def.is_referenced_in(ctx)
|
def_is_referenced_in(r.def, ctx)
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn filter_out_by_defs(&self, defs: Vec<Def>) -> Refs {
|
fn filter_out_by_defs(&self, defs: Vec<Definition>) -> Refs {
|
||||||
Refs(self.0.clone().into_iter().filter(|r| !defs.contains(&r.def)).collect())
|
Refs(self.0.clone().into_iter().filter(|r| !defs.contains(&r.def)).collect())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -220,7 +211,7 @@ fn is_mod_visible_from(ctx: &AssistContext, module: Module, from: Module) -> boo
|
|||||||
// use foo::*$0;
|
// use foo::*$0;
|
||||||
// use baz::Baz;
|
// use baz::Baz;
|
||||||
// ↑ ---------------
|
// ↑ ---------------
|
||||||
fn find_imported_defs(ctx: &AssistContext, star: SyntaxToken) -> Option<Vec<Def>> {
|
fn find_imported_defs(ctx: &AssistContext, star: SyntaxToken) -> Option<Vec<Definition>> {
|
||||||
let parent_use_item_syntax =
|
let parent_use_item_syntax =
|
||||||
star.ancestors().find_map(|n| if ast::Use::can_cast(n.kind()) { Some(n) } else { None })?;
|
star.ancestors().find_map(|n| if ast::Use::can_cast(n.kind()) { Some(n) } else { None })?;
|
||||||
|
|
||||||
@@ -234,8 +225,19 @@ fn find_imported_defs(ctx: &AssistContext, star: SyntaxToken) -> Option<Vec<Def>
|
|||||||
})
|
})
|
||||||
.flat_map(|n| n.descendants().filter_map(ast::NameRef::cast))
|
.flat_map(|n| n.descendants().filter_map(ast::NameRef::cast))
|
||||||
.filter_map(|r| match NameRefClass::classify(&ctx.sema, &r)? {
|
.filter_map(|r| match NameRefClass::classify(&ctx.sema, &r)? {
|
||||||
NameRefClass::Definition(Definition::ModuleDef(def)) => Some(Def::ModuleDef(def)),
|
NameRefClass::Definition(
|
||||||
NameRefClass::Definition(Definition::Macro(def)) => Some(Def::MacroDef(def)),
|
def
|
||||||
|
@
|
||||||
|
(Definition::Macro(_)
|
||||||
|
| Definition::Module(_)
|
||||||
|
| Definition::Function(_)
|
||||||
|
| Definition::Adt(_)
|
||||||
|
| Definition::Variant(_)
|
||||||
|
| Definition::Const(_)
|
||||||
|
| Definition::Static(_)
|
||||||
|
| Definition::Trait(_)
|
||||||
|
| Definition::TypeAlias(_)),
|
||||||
|
) => Some(def),
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
@@ -245,7 +247,7 @@ fn find_imported_defs(ctx: &AssistContext, star: SyntaxToken) -> Option<Vec<Def>
|
|||||||
fn find_names_to_import(
|
fn find_names_to_import(
|
||||||
ctx: &AssistContext,
|
ctx: &AssistContext,
|
||||||
refs_in_target: Refs,
|
refs_in_target: Refs,
|
||||||
imported_defs: Vec<Def>,
|
imported_defs: Vec<Definition>,
|
||||||
) -> Vec<Name> {
|
) -> Vec<Name> {
|
||||||
let used_refs = refs_in_target.used_refs(ctx).filter_out_by_defs(imported_defs);
|
let used_refs = refs_in_target.used_refs(ctx).filter_out_by_defs(imported_defs);
|
||||||
used_refs.0.iter().map(|r| r.visible_name.clone()).collect()
|
used_refs.0.iter().map(|r| r.visible_name.clone()).collect()
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
|
|
||||||
use hir::{HasSource, ModuleDef, ModuleSource};
|
use hir::{HasSource, ModuleSource};
|
||||||
use ide_db::{
|
use ide_db::{
|
||||||
assists::{AssistId, AssistKind},
|
assists::{AssistId, AssistKind},
|
||||||
base_db::FileId,
|
base_db::FileId,
|
||||||
@@ -184,7 +184,7 @@ impl Module {
|
|||||||
match (item.syntax()) {
|
match (item.syntax()) {
|
||||||
ast::Adt(it) => {
|
ast::Adt(it) => {
|
||||||
if let Some( nod ) = ctx.sema.to_def(&it) {
|
if let Some( nod ) = ctx.sema.to_def(&it) {
|
||||||
let node_def = Definition::ModuleDef(nod.into());
|
let node_def = Definition::Adt(nod.into());
|
||||||
self.expand_and_group_usages_file_wise(ctx, node_def, &mut refs);
|
self.expand_and_group_usages_file_wise(ctx, node_def, &mut refs);
|
||||||
|
|
||||||
//Enum Fields are not allowed to explicitly specify pub, it is implied
|
//Enum Fields are not allowed to explicitly specify pub, it is implied
|
||||||
@@ -218,25 +218,25 @@ impl Module {
|
|||||||
},
|
},
|
||||||
ast::TypeAlias(it) => {
|
ast::TypeAlias(it) => {
|
||||||
if let Some( nod ) = ctx.sema.to_def(&it) {
|
if let Some( nod ) = ctx.sema.to_def(&it) {
|
||||||
let node_def = Definition::ModuleDef(nod.into());
|
let node_def = Definition::TypeAlias(nod.into());
|
||||||
self.expand_and_group_usages_file_wise(ctx, node_def, &mut refs);
|
self.expand_and_group_usages_file_wise(ctx, node_def, &mut refs);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ast::Const(it) => {
|
ast::Const(it) => {
|
||||||
if let Some( nod ) = ctx.sema.to_def(&it) {
|
if let Some( nod ) = ctx.sema.to_def(&it) {
|
||||||
let node_def = Definition::ModuleDef(nod.into());
|
let node_def = Definition::Const(nod.into());
|
||||||
self.expand_and_group_usages_file_wise(ctx, node_def, &mut refs);
|
self.expand_and_group_usages_file_wise(ctx, node_def, &mut refs);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ast::Static(it) => {
|
ast::Static(it) => {
|
||||||
if let Some( nod ) = ctx.sema.to_def(&it) {
|
if let Some( nod ) = ctx.sema.to_def(&it) {
|
||||||
let node_def = Definition::ModuleDef(nod.into());
|
let node_def = Definition::Static(nod.into());
|
||||||
self.expand_and_group_usages_file_wise(ctx, node_def, &mut refs);
|
self.expand_and_group_usages_file_wise(ctx, node_def, &mut refs);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ast::Fn(it) => {
|
ast::Fn(it) => {
|
||||||
if let Some( nod ) = ctx.sema.to_def(&it) {
|
if let Some( nod ) = ctx.sema.to_def(&it) {
|
||||||
let node_def = Definition::ModuleDef(nod.into());
|
let node_def = Definition::Function(nod.into());
|
||||||
self.expand_and_group_usages_file_wise(ctx, node_def, &mut refs);
|
self.expand_and_group_usages_file_wise(ctx, node_def, &mut refs);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -603,8 +603,7 @@ fn does_source_exists_outside_sel_in_same_mod(
|
|||||||
) -> bool {
|
) -> bool {
|
||||||
let mut source_exists_outside_sel_in_same_mod = false;
|
let mut source_exists_outside_sel_in_same_mod = false;
|
||||||
match def {
|
match def {
|
||||||
Definition::ModuleDef(it) => match it {
|
Definition::Module(x) => {
|
||||||
ModuleDef::Module(x) => {
|
|
||||||
let source = x.definition_source(ctx.db());
|
let source = x.definition_source(ctx.db());
|
||||||
let have_same_parent;
|
let have_same_parent;
|
||||||
if let Some(ast_module) = &curr_parent_module {
|
if let Some(ast_module) = &curr_parent_module {
|
||||||
@@ -630,13 +629,12 @@ fn does_source_exists_outside_sel_in_same_mod(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ModuleDef::Function(x) => {
|
Definition::Function(x) => {
|
||||||
if let Some(source) = x.source(ctx.db()) {
|
if let Some(source) = x.source(ctx.db()) {
|
||||||
let have_same_parent;
|
let have_same_parent;
|
||||||
if let Some(ast_module) = &curr_parent_module {
|
if let Some(ast_module) = &curr_parent_module {
|
||||||
have_same_parent =
|
have_same_parent =
|
||||||
compare_hir_and_ast_module(&ast_module, x.module(ctx.db()), ctx)
|
compare_hir_and_ast_module(&ast_module, x.module(ctx.db()), ctx).is_some();
|
||||||
.is_some();
|
|
||||||
} else {
|
} else {
|
||||||
let source_file_id = source.file_id.original_file(ctx.db());
|
let source_file_id = source.file_id.original_file(ctx.db());
|
||||||
have_same_parent = source_file_id == curr_file_id;
|
have_same_parent = source_file_id == curr_file_id;
|
||||||
@@ -648,13 +646,12 @@ fn does_source_exists_outside_sel_in_same_mod(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ModuleDef::Adt(x) => {
|
Definition::Adt(x) => {
|
||||||
if let Some(source) = x.source(ctx.db()) {
|
if let Some(source) = x.source(ctx.db()) {
|
||||||
let have_same_parent;
|
let have_same_parent;
|
||||||
if let Some(ast_module) = &curr_parent_module {
|
if let Some(ast_module) = &curr_parent_module {
|
||||||
have_same_parent =
|
have_same_parent =
|
||||||
compare_hir_and_ast_module(&ast_module, x.module(ctx.db()), ctx)
|
compare_hir_and_ast_module(&ast_module, x.module(ctx.db()), ctx).is_some();
|
||||||
.is_some();
|
|
||||||
} else {
|
} else {
|
||||||
let source_file_id = source.file_id.original_file(ctx.db());
|
let source_file_id = source.file_id.original_file(ctx.db());
|
||||||
have_same_parent = source_file_id == curr_file_id;
|
have_same_parent = source_file_id == curr_file_id;
|
||||||
@@ -666,13 +663,12 @@ fn does_source_exists_outside_sel_in_same_mod(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ModuleDef::Variant(x) => {
|
Definition::Variant(x) => {
|
||||||
if let Some(source) = x.source(ctx.db()) {
|
if let Some(source) = x.source(ctx.db()) {
|
||||||
let have_same_parent;
|
let have_same_parent;
|
||||||
if let Some(ast_module) = &curr_parent_module {
|
if let Some(ast_module) = &curr_parent_module {
|
||||||
have_same_parent =
|
have_same_parent =
|
||||||
compare_hir_and_ast_module(&ast_module, x.module(ctx.db()), ctx)
|
compare_hir_and_ast_module(&ast_module, x.module(ctx.db()), ctx).is_some();
|
||||||
.is_some();
|
|
||||||
} else {
|
} else {
|
||||||
let source_file_id = source.file_id.original_file(ctx.db());
|
let source_file_id = source.file_id.original_file(ctx.db());
|
||||||
have_same_parent = source_file_id == curr_file_id;
|
have_same_parent = source_file_id == curr_file_id;
|
||||||
@@ -684,13 +680,12 @@ fn does_source_exists_outside_sel_in_same_mod(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ModuleDef::Const(x) => {
|
Definition::Const(x) => {
|
||||||
if let Some(source) = x.source(ctx.db()) {
|
if let Some(source) = x.source(ctx.db()) {
|
||||||
let have_same_parent;
|
let have_same_parent;
|
||||||
if let Some(ast_module) = &curr_parent_module {
|
if let Some(ast_module) = &curr_parent_module {
|
||||||
have_same_parent =
|
have_same_parent =
|
||||||
compare_hir_and_ast_module(&ast_module, x.module(ctx.db()), ctx)
|
compare_hir_and_ast_module(&ast_module, x.module(ctx.db()), ctx).is_some();
|
||||||
.is_some();
|
|
||||||
} else {
|
} else {
|
||||||
let source_file_id = source.file_id.original_file(ctx.db());
|
let source_file_id = source.file_id.original_file(ctx.db());
|
||||||
have_same_parent = source_file_id == curr_file_id;
|
have_same_parent = source_file_id == curr_file_id;
|
||||||
@@ -702,13 +697,12 @@ fn does_source_exists_outside_sel_in_same_mod(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ModuleDef::Static(x) => {
|
Definition::Static(x) => {
|
||||||
if let Some(source) = x.source(ctx.db()) {
|
if let Some(source) = x.source(ctx.db()) {
|
||||||
let have_same_parent;
|
let have_same_parent;
|
||||||
if let Some(ast_module) = &curr_parent_module {
|
if let Some(ast_module) = &curr_parent_module {
|
||||||
have_same_parent =
|
have_same_parent =
|
||||||
compare_hir_and_ast_module(&ast_module, x.module(ctx.db()), ctx)
|
compare_hir_and_ast_module(&ast_module, x.module(ctx.db()), ctx).is_some();
|
||||||
.is_some();
|
|
||||||
} else {
|
} else {
|
||||||
let source_file_id = source.file_id.original_file(ctx.db());
|
let source_file_id = source.file_id.original_file(ctx.db());
|
||||||
have_same_parent = source_file_id == curr_file_id;
|
have_same_parent = source_file_id == curr_file_id;
|
||||||
@@ -720,13 +714,12 @@ fn does_source_exists_outside_sel_in_same_mod(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ModuleDef::Trait(x) => {
|
Definition::Trait(x) => {
|
||||||
if let Some(source) = x.source(ctx.db()) {
|
if let Some(source) = x.source(ctx.db()) {
|
||||||
let have_same_parent;
|
let have_same_parent;
|
||||||
if let Some(ast_module) = &curr_parent_module {
|
if let Some(ast_module) = &curr_parent_module {
|
||||||
have_same_parent =
|
have_same_parent =
|
||||||
compare_hir_and_ast_module(&ast_module, x.module(ctx.db()), ctx)
|
compare_hir_and_ast_module(&ast_module, x.module(ctx.db()), ctx).is_some();
|
||||||
.is_some();
|
|
||||||
} else {
|
} else {
|
||||||
let source_file_id = source.file_id.original_file(ctx.db());
|
let source_file_id = source.file_id.original_file(ctx.db());
|
||||||
have_same_parent = source_file_id == curr_file_id;
|
have_same_parent = source_file_id == curr_file_id;
|
||||||
@@ -738,13 +731,12 @@ fn does_source_exists_outside_sel_in_same_mod(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ModuleDef::TypeAlias(x) => {
|
Definition::TypeAlias(x) => {
|
||||||
if let Some(source) = x.source(ctx.db()) {
|
if let Some(source) = x.source(ctx.db()) {
|
||||||
let have_same_parent;
|
let have_same_parent;
|
||||||
if let Some(ast_module) = &curr_parent_module {
|
if let Some(ast_module) = &curr_parent_module {
|
||||||
have_same_parent =
|
have_same_parent =
|
||||||
compare_hir_and_ast_module(&ast_module, x.module(ctx.db()), ctx)
|
compare_hir_and_ast_module(&ast_module, x.module(ctx.db()), ctx).is_some();
|
||||||
.is_some();
|
|
||||||
} else {
|
} else {
|
||||||
let source_file_id = source.file_id.original_file(ctx.db());
|
let source_file_id = source.file_id.original_file(ctx.db());
|
||||||
have_same_parent = source_file_id == curr_file_id;
|
have_same_parent = source_file_id == curr_file_id;
|
||||||
@@ -757,8 +749,6 @@ fn does_source_exists_outside_sel_in_same_mod(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return source_exists_outside_sel_in_same_mod;
|
return source_exists_outside_sel_in_same_mod;
|
||||||
|
|||||||
@@ -63,8 +63,7 @@ pub(crate) fn extract_struct_from_enum_variant(
|
|||||||
|builder| {
|
|builder| {
|
||||||
let variant_hir_name = variant_hir.name(ctx.db());
|
let variant_hir_name = variant_hir.name(ctx.db());
|
||||||
let enum_module_def = ModuleDef::from(enum_hir);
|
let enum_module_def = ModuleDef::from(enum_hir);
|
||||||
let usages =
|
let usages = Definition::Variant(variant_hir).usages(&ctx.sema).all();
|
||||||
Definition::ModuleDef(ModuleDef::Variant(variant_hir)).usages(&ctx.sema).all();
|
|
||||||
|
|
||||||
let mut visited_modules_set = FxHashSet::default();
|
let mut visited_modules_set = FxHashSet::default();
|
||||||
let current_module = enum_hir.module(ctx.db());
|
let current_module = enum_hir.module(ctx.db());
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ fn target_data_for_def(
|
|||||||
offset_target_and_file_id(db, c)?
|
offset_target_and_file_id(db, c)?
|
||||||
}
|
}
|
||||||
hir::ModuleDef::Static(s) => {
|
hir::ModuleDef::Static(s) => {
|
||||||
target_name = s.name(db);
|
target_name = Some(s.name(db));
|
||||||
offset_target_and_file_id(db, s)?
|
offset_target_and_file_id(db, s)?
|
||||||
}
|
}
|
||||||
hir::ModuleDef::Trait(t) => {
|
hir::ModuleDef::Trait(t) => {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use rustc_hash::{FxHashMap, FxHashSet};
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
|
|
||||||
use hir::{HasSource, HirDisplay, Module, ModuleDef, Semantics, TypeInfo};
|
use hir::{HasSource, HirDisplay, Module, Semantics, TypeInfo};
|
||||||
use ide_db::helpers::FamousDefs;
|
use ide_db::helpers::FamousDefs;
|
||||||
use ide_db::{
|
use ide_db::{
|
||||||
base_db::FileId,
|
base_db::FileId,
|
||||||
@@ -482,9 +482,8 @@ fn fn_arg_name(sema: &Semantics<RootDatabase>, arg_expr: &ast::Expr) -> String {
|
|||||||
ast::Expr::CastExpr(cast_expr) => Some(fn_arg_name(sema, &cast_expr.expr()?)),
|
ast::Expr::CastExpr(cast_expr) => Some(fn_arg_name(sema, &cast_expr.expr()?)),
|
||||||
expr => {
|
expr => {
|
||||||
let name_ref = expr.syntax().descendants().filter_map(ast::NameRef::cast).last()?;
|
let name_ref = expr.syntax().descendants().filter_map(ast::NameRef::cast).last()?;
|
||||||
if let Some(NameRefClass::Definition(Definition::ModuleDef(
|
if let Some(NameRefClass::Definition(Definition::Const(_) | Definition::Static(_))) =
|
||||||
ModuleDef::Const(_) | ModuleDef::Static(_),
|
NameRefClass::classify(sema, &name_ref)
|
||||||
))) = NameRefClass::classify(sema, &name_ref)
|
|
||||||
{
|
{
|
||||||
return Some(name_ref.to_string().to_lowercase());
|
return Some(name_ref.to_string().to_lowercase());
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ pub(crate) fn inline_into_callers(acc: &mut Assists, ctx: &AssistContext) -> Opt
|
|||||||
|
|
||||||
let params = get_fn_params(ctx.sema.db, function, ¶m_list)?;
|
let params = get_fn_params(ctx.sema.db, function, ¶m_list)?;
|
||||||
|
|
||||||
let usages = Definition::ModuleDef(hir::ModuleDef::Function(function)).usages(&ctx.sema);
|
let usages = Definition::Function(function).usages(&ctx.sema);
|
||||||
if !usages.at_least_one() {
|
if !usages.at_least_one() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ pub(crate) fn remove_unused_param(acc: &mut Assists, ctx: &AssistContext) -> Opt
|
|||||||
}
|
}
|
||||||
let fn_def = {
|
let fn_def = {
|
||||||
let func = ctx.sema.to_def(&func)?;
|
let func = ctx.sema.to_def(&func)?;
|
||||||
Definition::ModuleDef(func.into())
|
Definition::Function(func)
|
||||||
};
|
};
|
||||||
|
|
||||||
let param_def = {
|
let param_def = {
|
||||||
|
|||||||
@@ -7,9 +7,11 @@
|
|||||||
|
|
||||||
use arrayvec::ArrayVec;
|
use arrayvec::ArrayVec;
|
||||||
use hir::{
|
use hir::{
|
||||||
Field, GenericParam, HasVisibility, Impl, Label, Local, MacroDef, Module, ModuleDef, Name,
|
Adt, AsAssocItem, AssocItem, BuiltinType, Const, Field, Function, GenericParam, HasVisibility,
|
||||||
PathResolution, Semantics, Visibility,
|
Impl, ItemInNs, Label, Local, MacroDef, Module, ModuleDef, Name, PathResolution, Semantics,
|
||||||
|
Static, Trait, TypeAlias, Variant, Visibility,
|
||||||
};
|
};
|
||||||
|
use stdx::impl_from;
|
||||||
use syntax::{
|
use syntax::{
|
||||||
ast::{self, AstNode},
|
ast::{self, AstNode},
|
||||||
match_ast, AstToken, SyntaxKind, SyntaxNode, SyntaxToken,
|
match_ast, AstToken, SyntaxKind, SyntaxNode, SyntaxToken,
|
||||||
@@ -22,7 +24,15 @@ use crate::{helpers::try_resolve_derive_input, RootDatabase};
|
|||||||
pub enum Definition {
|
pub enum Definition {
|
||||||
Macro(MacroDef),
|
Macro(MacroDef),
|
||||||
Field(Field),
|
Field(Field),
|
||||||
ModuleDef(ModuleDef),
|
Module(Module),
|
||||||
|
Function(Function),
|
||||||
|
Adt(Adt),
|
||||||
|
Variant(Variant),
|
||||||
|
Const(Const),
|
||||||
|
Static(Static),
|
||||||
|
Trait(Trait),
|
||||||
|
TypeAlias(TypeAlias),
|
||||||
|
BuiltinType(BuiltinType),
|
||||||
SelfType(Impl),
|
SelfType(Impl),
|
||||||
Local(Local),
|
Local(Local),
|
||||||
GenericParam(GenericParam),
|
GenericParam(GenericParam),
|
||||||
@@ -98,49 +108,65 @@ impl Definition {
|
|||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn module(&self, db: &RootDatabase) -> Option<Module> {
|
pub fn canonical_module_path(&self, db: &RootDatabase) -> Option<impl Iterator<Item = Module>> {
|
||||||
match self {
|
self.module(db).map(|it| it.path_to_root(db).into_iter().rev())
|
||||||
Definition::Macro(it) => it.module(db),
|
|
||||||
Definition::Field(it) => Some(it.parent_def(db).module(db)),
|
|
||||||
Definition::ModuleDef(it) => it.module(db),
|
|
||||||
Definition::SelfType(it) => Some(it.module(db)),
|
|
||||||
Definition::Local(it) => Some(it.module(db)),
|
|
||||||
Definition::GenericParam(it) => Some(it.module(db)),
|
|
||||||
Definition::Label(it) => Some(it.module(db)),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn module(&self, db: &RootDatabase) -> Option<Module> {
|
||||||
|
let module = match self {
|
||||||
|
Definition::Macro(it) => it.module(db)?,
|
||||||
|
Definition::Module(it) => it.parent(db)?,
|
||||||
|
Definition::Field(it) => it.parent_def(db).module(db),
|
||||||
|
Definition::Function(it) => it.module(db),
|
||||||
|
Definition::Adt(it) => it.module(db),
|
||||||
|
Definition::Const(it) => it.module(db),
|
||||||
|
Definition::Static(it) => it.module(db),
|
||||||
|
Definition::Trait(it) => it.module(db),
|
||||||
|
Definition::TypeAlias(it) => it.module(db),
|
||||||
|
Definition::Variant(it) => it.module(db),
|
||||||
|
Definition::SelfType(it) => it.module(db),
|
||||||
|
Definition::Local(it) => it.module(db),
|
||||||
|
Definition::GenericParam(it) => it.module(db),
|
||||||
|
Definition::Label(it) => it.module(db),
|
||||||
|
Definition::BuiltinType(_) => return None,
|
||||||
|
};
|
||||||
|
Some(module)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn visibility(&self, db: &RootDatabase) -> Option<Visibility> {
|
pub fn visibility(&self, db: &RootDatabase) -> Option<Visibility> {
|
||||||
match self {
|
let vis = match self {
|
||||||
Definition::Field(sf) => Some(sf.visibility(db)),
|
Definition::Field(sf) => sf.visibility(db),
|
||||||
Definition::ModuleDef(def) => Some(def.visibility(db)),
|
Definition::Module(it) => it.visibility(db),
|
||||||
Definition::Macro(_)
|
Definition::Function(it) => it.visibility(db),
|
||||||
| Definition::SelfType(_)
|
Definition::Adt(it) => it.visibility(db),
|
||||||
|
Definition::Const(it) => it.visibility(db),
|
||||||
|
Definition::Static(it) => it.visibility(db),
|
||||||
|
Definition::Trait(it) => it.visibility(db),
|
||||||
|
Definition::TypeAlias(it) => it.visibility(db),
|
||||||
|
Definition::Variant(it) => it.visibility(db),
|
||||||
|
Definition::BuiltinType(_) => Visibility::Public,
|
||||||
|
Definition::Macro(_) => return None,
|
||||||
|
Definition::SelfType(_)
|
||||||
| Definition::Local(_)
|
| Definition::Local(_)
|
||||||
| Definition::GenericParam(_)
|
| Definition::GenericParam(_)
|
||||||
| Definition::Label(_) => None,
|
| Definition::Label(_) => return None,
|
||||||
}
|
};
|
||||||
|
Some(vis)
|
||||||
}
|
}
|
||||||
|
|
||||||
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::ModuleDef(def) => match def {
|
Definition::Module(it) => it.name(db)?,
|
||||||
hir::ModuleDef::Module(it) => it.name(db)?,
|
Definition::Function(it) => it.name(db),
|
||||||
hir::ModuleDef::Function(it) => it.name(db),
|
Definition::Adt(it) => it.name(db),
|
||||||
hir::ModuleDef::Adt(def) => match def {
|
Definition::Variant(it) => it.name(db),
|
||||||
hir::Adt::Struct(it) => it.name(db),
|
Definition::Const(it) => it.name(db)?,
|
||||||
hir::Adt::Union(it) => it.name(db),
|
Definition::Static(it) => it.name(db),
|
||||||
hir::Adt::Enum(it) => it.name(db),
|
Definition::Trait(it) => it.name(db),
|
||||||
},
|
Definition::TypeAlias(it) => it.name(db),
|
||||||
hir::ModuleDef::Variant(it) => it.name(db),
|
Definition::BuiltinType(it) => it.name(),
|
||||||
hir::ModuleDef::Const(it) => it.name(db)?,
|
|
||||||
hir::ModuleDef::Static(it) => it.name(db)?,
|
|
||||||
hir::ModuleDef::Trait(it) => it.name(db),
|
|
||||||
hir::ModuleDef::TypeAlias(it) => it.name(db),
|
|
||||||
hir::ModuleDef::BuiltinType(it) => it.name(),
|
|
||||||
},
|
|
||||||
Definition::SelfType(_) => return None,
|
Definition::SelfType(_) => return None,
|
||||||
Definition::Local(it) => it.name(db)?,
|
Definition::Local(it) => it.name(db)?,
|
||||||
Definition::GenericParam(it) => it.name(db),
|
Definition::GenericParam(it) => it.name(db),
|
||||||
@@ -193,7 +219,7 @@ impl NameClass {
|
|||||||
|
|
||||||
if let Some(bind_pat) = ast::IdentPat::cast(parent.clone()) {
|
if let Some(bind_pat) = ast::IdentPat::cast(parent.clone()) {
|
||||||
if let Some(def) = sema.resolve_bind_pat_to_const(&bind_pat) {
|
if let Some(def) = sema.resolve_bind_pat_to_const(&bind_pat) {
|
||||||
return Some(NameClass::ConstReference(Definition::ModuleDef(def)));
|
return Some(NameClass::ConstReference(Definition::from(def)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,7 +257,7 @@ impl NameClass {
|
|||||||
let extern_crate = it.syntax().parent().and_then(ast::ExternCrate::cast)?;
|
let extern_crate = it.syntax().parent().and_then(ast::ExternCrate::cast)?;
|
||||||
let krate = sema.resolve_extern_crate(&extern_crate)?;
|
let krate = sema.resolve_extern_crate(&extern_crate)?;
|
||||||
let root_module = krate.root_module(sema.db);
|
let root_module = krate.root_module(sema.db);
|
||||||
Some(NameClass::Definition(Definition::ModuleDef(root_module.into())))
|
Some(NameClass::Definition(Definition::Module(root_module)))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ast::IdentPat(it) => {
|
ast::IdentPat(it) => {
|
||||||
@@ -257,43 +283,43 @@ impl NameClass {
|
|||||||
},
|
},
|
||||||
ast::Module(it) => {
|
ast::Module(it) => {
|
||||||
let def = sema.to_def(&it)?;
|
let def = sema.to_def(&it)?;
|
||||||
Some(NameClass::Definition(Definition::ModuleDef(def.into())))
|
Some(NameClass::Definition(Definition::Module(def)))
|
||||||
},
|
},
|
||||||
ast::Struct(it) => {
|
ast::Struct(it) => {
|
||||||
let def: hir::Struct = sema.to_def(&it)?;
|
let def: hir::Struct = sema.to_def(&it)?;
|
||||||
Some(NameClass::Definition(Definition::ModuleDef(def.into())))
|
Some(NameClass::Definition(Definition::Adt(def.into())))
|
||||||
},
|
},
|
||||||
ast::Union(it) => {
|
ast::Union(it) => {
|
||||||
let def: hir::Union = sema.to_def(&it)?;
|
let def: hir::Union = sema.to_def(&it)?;
|
||||||
Some(NameClass::Definition(Definition::ModuleDef(def.into())))
|
Some(NameClass::Definition(Definition::Adt(def.into())))
|
||||||
},
|
},
|
||||||
ast::Enum(it) => {
|
ast::Enum(it) => {
|
||||||
let def: hir::Enum = sema.to_def(&it)?;
|
let def: hir::Enum = sema.to_def(&it)?;
|
||||||
Some(NameClass::Definition(Definition::ModuleDef(def.into())))
|
Some(NameClass::Definition(Definition::Adt(def.into())))
|
||||||
},
|
},
|
||||||
ast::Trait(it) => {
|
ast::Trait(it) => {
|
||||||
let def: hir::Trait = sema.to_def(&it)?;
|
let def: hir::Trait = sema.to_def(&it)?;
|
||||||
Some(NameClass::Definition(Definition::ModuleDef(def.into())))
|
Some(NameClass::Definition(Definition::Trait(def)))
|
||||||
},
|
},
|
||||||
ast::Static(it) => {
|
ast::Static(it) => {
|
||||||
let def: hir::Static = sema.to_def(&it)?;
|
let def: hir::Static = sema.to_def(&it)?;
|
||||||
Some(NameClass::Definition(Definition::ModuleDef(def.into())))
|
Some(NameClass::Definition(Definition::Static(def)))
|
||||||
},
|
},
|
||||||
ast::Variant(it) => {
|
ast::Variant(it) => {
|
||||||
let def: hir::Variant = sema.to_def(&it)?;
|
let def: hir::Variant = sema.to_def(&it)?;
|
||||||
Some(NameClass::Definition(Definition::ModuleDef(def.into())))
|
Some(NameClass::Definition(Definition::Variant(def)))
|
||||||
},
|
},
|
||||||
ast::Fn(it) => {
|
ast::Fn(it) => {
|
||||||
let def: hir::Function = sema.to_def(&it)?;
|
let def: hir::Function = sema.to_def(&it)?;
|
||||||
Some(NameClass::Definition(Definition::ModuleDef(def.into())))
|
Some(NameClass::Definition(Definition::Function(def)))
|
||||||
},
|
},
|
||||||
ast::Const(it) => {
|
ast::Const(it) => {
|
||||||
let def: hir::Const = sema.to_def(&it)?;
|
let def: hir::Const = sema.to_def(&it)?;
|
||||||
Some(NameClass::Definition(Definition::ModuleDef(def.into())))
|
Some(NameClass::Definition(Definition::Const(def)))
|
||||||
},
|
},
|
||||||
ast::TypeAlias(it) => {
|
ast::TypeAlias(it) => {
|
||||||
let def: hir::TypeAlias = sema.to_def(&it)?;
|
let def: hir::TypeAlias = sema.to_def(&it)?;
|
||||||
Some(NameClass::Definition(Definition::ModuleDef(def.into())))
|
Some(NameClass::Definition(Definition::TypeAlias(def)))
|
||||||
},
|
},
|
||||||
ast::Macro(it) => {
|
ast::Macro(it) => {
|
||||||
let def = sema.to_def(&it)?;
|
let def = sema.to_def(&it)?;
|
||||||
@@ -360,7 +386,7 @@ impl NameRefClass {
|
|||||||
|
|
||||||
if let Some(method_call) = ast::MethodCallExpr::cast(parent.clone()) {
|
if let Some(method_call) = ast::MethodCallExpr::cast(parent.clone()) {
|
||||||
if let Some(func) = sema.resolve_method_call(&method_call) {
|
if let Some(func) = sema.resolve_method_call(&method_call) {
|
||||||
return Some(NameRefClass::Definition(Definition::ModuleDef(func.into())));
|
return Some(NameRefClass::Definition(Definition::Function(func)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -406,9 +432,7 @@ impl NameRefClass {
|
|||||||
})
|
})
|
||||||
.find(|alias| alias.name(sema.db).to_smol_str() == name_ref.text().as_str())
|
.find(|alias| alias.name(sema.db).to_smol_str() == name_ref.text().as_str())
|
||||||
{
|
{
|
||||||
return Some(NameRefClass::Definition(Definition::ModuleDef(
|
return Some(NameRefClass::Definition(Definition::TypeAlias(ty)));
|
||||||
ModuleDef::TypeAlias(ty),
|
|
||||||
)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -440,9 +464,9 @@ impl NameRefClass {
|
|||||||
.map(NameRefClass::Definition),
|
.map(NameRefClass::Definition),
|
||||||
// in case of the path being a qualifier, don't resolve to anything but a module
|
// in case of the path being a qualifier, don't resolve to anything but a module
|
||||||
Some(true) => match sema.resolve_path(&path)? {
|
Some(true) => match sema.resolve_path(&path)? {
|
||||||
PathResolution::Def(module @ ModuleDef::Module(_)) => {
|
PathResolution::Def(ModuleDef::Module(module)) => {
|
||||||
cov_mark::hit!(name_ref_classify_attr_path_qualifier);
|
cov_mark::hit!(name_ref_classify_attr_path_qualifier);
|
||||||
Some(NameRefClass::Definition(Definition::ModuleDef(module)))
|
Some(NameRefClass::Definition(Definition::Module(module)))
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
},
|
},
|
||||||
@@ -455,7 +479,7 @@ impl NameRefClass {
|
|||||||
let extern_crate = ast::ExternCrate::cast(parent)?;
|
let extern_crate = ast::ExternCrate::cast(parent)?;
|
||||||
let krate = sema.resolve_extern_crate(&extern_crate)?;
|
let krate = sema.resolve_extern_crate(&extern_crate)?;
|
||||||
let root_module = krate.root_module(sema.db);
|
let root_module = krate.root_module(sema.db);
|
||||||
Some(NameRefClass::Definition(Definition::ModuleDef(root_module.into())))
|
Some(NameRefClass::Definition(Definition::Module(root_module)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn classify_lifetime(
|
pub fn classify_lifetime(
|
||||||
@@ -492,17 +516,34 @@ impl NameRefClass {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl AsAssocItem for Definition {
|
||||||
|
fn as_assoc_item(self, db: &dyn hir::db::HirDatabase) -> Option<AssocItem> {
|
||||||
|
match self {
|
||||||
|
Definition::Function(it) => it.as_assoc_item(db),
|
||||||
|
Definition::Const(it) => it.as_assoc_item(db),
|
||||||
|
Definition::TypeAlias(it) => it.as_assoc_item(db),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_from!(
|
||||||
|
Field, Module, Function, Adt, Variant, Const, Static, Trait, TypeAlias, BuiltinType, Local,
|
||||||
|
GenericParam, Label
|
||||||
|
for Definition
|
||||||
|
);
|
||||||
|
|
||||||
impl From<PathResolution> for Definition {
|
impl From<PathResolution> for Definition {
|
||||||
fn from(path_resolution: PathResolution) -> Self {
|
fn from(path_resolution: PathResolution) -> Self {
|
||||||
match path_resolution {
|
match path_resolution {
|
||||||
PathResolution::Def(def) => Definition::ModuleDef(def),
|
PathResolution::Def(def) => def.into(),
|
||||||
PathResolution::AssocItem(item) => {
|
PathResolution::AssocItem(item) => {
|
||||||
let def = match item {
|
let def: ModuleDef = match item {
|
||||||
hir::AssocItem::Function(it) => it.into(),
|
hir::AssocItem::Function(it) => it.into(),
|
||||||
hir::AssocItem::Const(it) => it.into(),
|
hir::AssocItem::Const(it) => it.into(),
|
||||||
hir::AssocItem::TypeAlias(it) => it.into(),
|
hir::AssocItem::TypeAlias(it) => it.into(),
|
||||||
};
|
};
|
||||||
Definition::ModuleDef(def)
|
def.into()
|
||||||
}
|
}
|
||||||
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()),
|
||||||
@@ -512,3 +553,37 @@ impl From<PathResolution> for Definition {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<ModuleDef> for Definition {
|
||||||
|
fn from(def: ModuleDef) -> Self {
|
||||||
|
match def {
|
||||||
|
ModuleDef::Module(it) => Definition::Module(it),
|
||||||
|
ModuleDef::Function(it) => Definition::Function(it),
|
||||||
|
ModuleDef::Adt(it) => Definition::Adt(it),
|
||||||
|
ModuleDef::Variant(it) => Definition::Variant(it),
|
||||||
|
ModuleDef::Const(it) => Definition::Const(it),
|
||||||
|
ModuleDef::Static(it) => Definition::Static(it),
|
||||||
|
ModuleDef::Trait(it) => Definition::Trait(it),
|
||||||
|
ModuleDef::TypeAlias(it) => Definition::TypeAlias(it),
|
||||||
|
ModuleDef::BuiltinType(it) => Definition::BuiltinType(it),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Definition> for Option<ItemInNs> {
|
||||||
|
fn from(def: Definition) -> Self {
|
||||||
|
let item = match def {
|
||||||
|
Definition::Module(it) => ModuleDef::Module(it),
|
||||||
|
Definition::Function(it) => ModuleDef::Function(it),
|
||||||
|
Definition::Adt(it) => ModuleDef::Adt(it),
|
||||||
|
Definition::Variant(it) => ModuleDef::Variant(it),
|
||||||
|
Definition::Const(it) => ModuleDef::Const(it),
|
||||||
|
Definition::Static(it) => ModuleDef::Static(it),
|
||||||
|
Definition::Trait(it) => ModuleDef::Trait(it),
|
||||||
|
Definition::TypeAlias(it) => ModuleDef::TypeAlias(it),
|
||||||
|
Definition::BuiltinType(it) => ModuleDef::BuiltinType(it),
|
||||||
|
_ => return None,
|
||||||
|
};
|
||||||
|
Some(ItemInNs::from(item))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -117,9 +117,8 @@ fn find_items<'a>(
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(move |local_candidate| get_name_definition(sema, &local_candidate))
|
.filter_map(move |local_candidate| get_name_definition(sema, &local_candidate))
|
||||||
.filter_map(|name_definition_to_import| match name_definition_to_import {
|
.filter_map(|name_definition_to_import| match name_definition_to_import {
|
||||||
Definition::ModuleDef(module_def) => Some(ItemInNs::from(module_def)),
|
|
||||||
Definition::Macro(macro_def) => Some(ItemInNs::from(macro_def)),
|
Definition::Macro(macro_def) => Some(ItemInNs::from(macro_def)),
|
||||||
_ => None,
|
def => <Option<_>>::from(def),
|
||||||
});
|
});
|
||||||
|
|
||||||
external_importables.chain(local_results).filter(move |&item| match assoc_item_search {
|
external_importables.chain(local_results).filter(move |&item| match assoc_item_search {
|
||||||
|
|||||||
@@ -67,10 +67,8 @@ pub use _bail as bail;
|
|||||||
impl Definition {
|
impl Definition {
|
||||||
pub fn rename(&self, sema: &Semantics<RootDatabase>, new_name: &str) -> Result<SourceChange> {
|
pub fn rename(&self, sema: &Semantics<RootDatabase>, new_name: &str) -> Result<SourceChange> {
|
||||||
match *self {
|
match *self {
|
||||||
Definition::ModuleDef(hir::ModuleDef::Module(module)) => {
|
Definition::Module(module) => rename_mod(sema, module, new_name),
|
||||||
rename_mod(sema, module, new_name)
|
Definition::BuiltinType(_) => {
|
||||||
}
|
|
||||||
Definition::ModuleDef(hir::ModuleDef::BuiltinType(_)) => {
|
|
||||||
bail!("Cannot rename builtin type")
|
bail!("Cannot rename builtin type")
|
||||||
}
|
}
|
||||||
Definition::SelfType(_) => bail!("Cannot rename `Self`"),
|
Definition::SelfType(_) => bail!("Cannot rename `Self`"),
|
||||||
@@ -101,25 +99,23 @@ impl Definition {
|
|||||||
FieldSource::Pos(_) => None,
|
FieldSource::Pos(_) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Definition::ModuleDef(module_def) => match module_def {
|
Definition::Module(module) => {
|
||||||
hir::ModuleDef::Module(module) => {
|
|
||||||
let src = module.declaration_source(sema.db)?;
|
let src = module.declaration_source(sema.db)?;
|
||||||
let name = src.value.name()?;
|
let name = src.value.name()?;
|
||||||
src.with_value(name.syntax()).original_file_range_opt(sema.db)
|
src.with_value(name.syntax()).original_file_range_opt(sema.db)
|
||||||
}
|
}
|
||||||
hir::ModuleDef::Function(it) => name_range(it, sema),
|
Definition::Function(it) => name_range(it, sema),
|
||||||
hir::ModuleDef::Adt(adt) => match adt {
|
Definition::Adt(adt) => match adt {
|
||||||
hir::Adt::Struct(it) => name_range(it, sema),
|
hir::Adt::Struct(it) => name_range(it, sema),
|
||||||
hir::Adt::Union(it) => name_range(it, sema),
|
hir::Adt::Union(it) => name_range(it, sema),
|
||||||
hir::Adt::Enum(it) => name_range(it, sema),
|
hir::Adt::Enum(it) => name_range(it, sema),
|
||||||
},
|
},
|
||||||
hir::ModuleDef::Variant(it) => name_range(it, sema),
|
Definition::Variant(it) => name_range(it, sema),
|
||||||
hir::ModuleDef::Const(it) => name_range(it, sema),
|
Definition::Const(it) => name_range(it, sema),
|
||||||
hir::ModuleDef::Static(it) => name_range(it, sema),
|
Definition::Static(it) => name_range(it, sema),
|
||||||
hir::ModuleDef::Trait(it) => name_range(it, sema),
|
Definition::Trait(it) => name_range(it, sema),
|
||||||
hir::ModuleDef::TypeAlias(it) => name_range(it, sema),
|
Definition::TypeAlias(it) => name_range(it, sema),
|
||||||
hir::ModuleDef::BuiltinType(_) => return None,
|
Definition::BuiltinType(_) => return None,
|
||||||
},
|
|
||||||
Definition::SelfType(_) => return None,
|
Definition::SelfType(_) => return None,
|
||||||
Definition::Local(local) => {
|
Definition::Local(local) => {
|
||||||
let src = local.source(sema.db);
|
let src = local.source(sema.db);
|
||||||
@@ -200,7 +196,7 @@ fn rename_mod(
|
|||||||
_ => never!("Module source node is missing a name"),
|
_ => never!("Module source node is missing a name"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let def = Definition::ModuleDef(hir::ModuleDef::Module(module));
|
let def = Definition::Module(module);
|
||||||
let usages = def.usages(sema).all();
|
let usages = def.usages(sema).all();
|
||||||
let ref_edits = usages.iter().map(|(&file_id, references)| {
|
let ref_edits = usages.iter().map(|(&file_id, references)| {
|
||||||
(file_id, source_edit_from_references(references, def, new_name))
|
(file_id, source_edit_from_references(references, def, new_name))
|
||||||
@@ -239,35 +235,40 @@ fn rename_reference(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def = match def {
|
let assoc_item = match def {
|
||||||
// HACK: resolve trait impl items to the item def of the trait definition
|
// HACK: resolve trait impl items to the item def of the trait definition
|
||||||
// so that we properly resolve all trait item references
|
// so that we properly resolve all trait item references
|
||||||
Definition::ModuleDef(mod_def) => mod_def
|
Definition::Function(it) => it.as_assoc_item(sema.db),
|
||||||
.as_assoc_item(sema.db)
|
Definition::TypeAlias(it) => it.as_assoc_item(sema.db),
|
||||||
.and_then(|it| it.containing_trait_impl(sema.db))
|
Definition::Const(it) => it.as_assoc_item(sema.db),
|
||||||
.and_then(|it| {
|
_ => None,
|
||||||
it.items(sema.db).into_iter().find_map(|it| match (it, mod_def) {
|
};
|
||||||
(hir::AssocItem::Function(trait_func), hir::ModuleDef::Function(func))
|
def = match assoc_item {
|
||||||
|
Some(assoc) => assoc
|
||||||
|
.containing_trait_impl(sema.db)
|
||||||
|
.and_then(|trait_| {
|
||||||
|
trait_.items(sema.db).into_iter().find_map(|it| match (it, assoc) {
|
||||||
|
(hir::AssocItem::Function(trait_func), hir::AssocItem::Function(func))
|
||||||
if trait_func.name(sema.db) == func.name(sema.db) =>
|
if trait_func.name(sema.db) == func.name(sema.db) =>
|
||||||
{
|
{
|
||||||
Some(Definition::ModuleDef(hir::ModuleDef::Function(trait_func)))
|
Some(Definition::Function(trait_func))
|
||||||
}
|
}
|
||||||
(hir::AssocItem::Const(trait_konst), hir::ModuleDef::Const(konst))
|
(hir::AssocItem::Const(trait_konst), hir::AssocItem::Const(konst))
|
||||||
if trait_konst.name(sema.db) == konst.name(sema.db) =>
|
if trait_konst.name(sema.db) == konst.name(sema.db) =>
|
||||||
{
|
{
|
||||||
Some(Definition::ModuleDef(hir::ModuleDef::Const(trait_konst)))
|
Some(Definition::Const(trait_konst))
|
||||||
}
|
}
|
||||||
(
|
(
|
||||||
hir::AssocItem::TypeAlias(trait_type_alias),
|
hir::AssocItem::TypeAlias(trait_type_alias),
|
||||||
hir::ModuleDef::TypeAlias(type_alias),
|
hir::AssocItem::TypeAlias(type_alias),
|
||||||
) if trait_type_alias.name(sema.db) == type_alias.name(sema.db) => {
|
) if trait_type_alias.name(sema.db) == type_alias.name(sema.db) => {
|
||||||
Some(Definition::ModuleDef(hir::ModuleDef::TypeAlias(trait_type_alias)))
|
Some(Definition::TypeAlias(trait_type_alias))
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.unwrap_or(def),
|
.unwrap_or(def),
|
||||||
_ => def,
|
None => def,
|
||||||
};
|
};
|
||||||
let usages = def.usages(sema).all();
|
let usages = def.usages(sema).all();
|
||||||
|
|
||||||
|
|||||||
@@ -8,8 +8,7 @@ use std::{convert::TryInto, mem};
|
|||||||
|
|
||||||
use base_db::{FileId, FileRange, SourceDatabase, SourceDatabaseExt};
|
use base_db::{FileId, FileRange, SourceDatabase, SourceDatabaseExt};
|
||||||
use hir::{
|
use hir::{
|
||||||
AsAssocItem, DefWithBody, HasAttrs, HasSource, InFile, ModuleDef, ModuleSource, Semantics,
|
AsAssocItem, DefWithBody, HasAttrs, HasSource, InFile, ModuleSource, Semantics, Visibility,
|
||||||
Visibility,
|
|
||||||
};
|
};
|
||||||
use once_cell::unsync::Lazy;
|
use once_cell::unsync::Lazy;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
@@ -217,13 +216,13 @@ impl Definition {
|
|||||||
fn search_scope(&self, db: &RootDatabase) -> SearchScope {
|
fn search_scope(&self, db: &RootDatabase) -> SearchScope {
|
||||||
let _p = profile::span("search_scope");
|
let _p = profile::span("search_scope");
|
||||||
|
|
||||||
if let Definition::ModuleDef(hir::ModuleDef::BuiltinType(_)) = self {
|
if let Definition::BuiltinType(_) = self {
|
||||||
return SearchScope::crate_graph(db);
|
return SearchScope::crate_graph(db);
|
||||||
}
|
}
|
||||||
|
|
||||||
// def is crate root
|
// def is crate root
|
||||||
// FIXME: We don't do searches for crates currently, as a crate does not actually have a single name
|
// FIXME: We don't do searches for crates currently, as a crate does not actually have a single name
|
||||||
if let &Definition::ModuleDef(hir::ModuleDef::Module(module)) = self {
|
if let &Definition::Module(module) = self {
|
||||||
if module.crate_root(db) == module {
|
if module.crate_root(db) == module {
|
||||||
return SearchScope::reverse_dependencies(db, module.krate());
|
return SearchScope::reverse_dependencies(db, module.krate());
|
||||||
}
|
}
|
||||||
@@ -431,7 +430,7 @@ impl<'a> FindUsages<'a> {
|
|||||||
|
|
||||||
// search for module `self` references in our module's definition source
|
// search for module `self` references in our module's definition source
|
||||||
match self.def {
|
match self.def {
|
||||||
Definition::ModuleDef(hir::ModuleDef::Module(module)) if self.search_self_mod => {
|
Definition::Module(module) if self.search_self_mod => {
|
||||||
let src = module.definition_source(sema.db);
|
let src = module.definition_source(sema.db);
|
||||||
let file_id = src.file_id.original_file(sema.db);
|
let file_id = src.file_id.original_file(sema.db);
|
||||||
let (file_id, search_range) = match src.value {
|
let (file_id, search_range) = match src.value {
|
||||||
@@ -491,7 +490,7 @@ impl<'a> FindUsages<'a> {
|
|||||||
sink: &mut dyn FnMut(FileId, FileReference) -> bool,
|
sink: &mut dyn FnMut(FileId, FileReference) -> bool,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
match NameRefClass::classify(self.sema, name_ref) {
|
match NameRefClass::classify(self.sema, name_ref) {
|
||||||
Some(NameRefClass::Definition(def @ Definition::ModuleDef(_))) if def == self.def => {
|
Some(NameRefClass::Definition(def @ Definition::Module(_))) if def == self.def => {
|
||||||
let FileRange { file_id, range } = self.sema.original_range(name_ref.syntax());
|
let FileRange { file_id, range } = self.sema.original_range(name_ref.syntax());
|
||||||
let reference = FileReference {
|
let reference = FileReference {
|
||||||
range,
|
range,
|
||||||
@@ -604,23 +603,20 @@ impl<'a> FindUsages<'a> {
|
|||||||
sink(file_id, reference)
|
sink(file_id, reference)
|
||||||
}
|
}
|
||||||
// Resolve trait impl function definitions to the trait definition's version if self.def is the trait definition's
|
// Resolve trait impl function definitions to the trait definition's version if self.def is the trait definition's
|
||||||
Some(NameClass::Definition(Definition::ModuleDef(mod_def))) => {
|
Some(NameClass::Definition(def)) if def != self.def => {
|
||||||
/* poor man's try block */
|
/* poor man's try block */
|
||||||
(|| {
|
(|| {
|
||||||
let this = match self.def {
|
let this_trait = self
|
||||||
Definition::ModuleDef(this) if this != mod_def => this,
|
.def
|
||||||
_ => return None,
|
|
||||||
};
|
|
||||||
let this_trait = this
|
|
||||||
.as_assoc_item(self.sema.db)?
|
.as_assoc_item(self.sema.db)?
|
||||||
.containing_trait_or_trait_impl(self.sema.db)?;
|
.containing_trait_or_trait_impl(self.sema.db)?;
|
||||||
let trait_ = mod_def
|
let trait_ = def
|
||||||
.as_assoc_item(self.sema.db)?
|
.as_assoc_item(self.sema.db)?
|
||||||
.containing_trait_or_trait_impl(self.sema.db)?;
|
.containing_trait_or_trait_impl(self.sema.db)?;
|
||||||
(trait_ == this_trait
|
(trait_ == this_trait && self.def.name(self.sema.db) == def.name(self.sema.db))
|
||||||
&& self.def.name(self.sema.db) == mod_def.name(self.sema.db))
|
|
||||||
.then(|| {
|
.then(|| {
|
||||||
let FileRange { file_id, range } = self.sema.original_range(name.syntax());
|
let FileRange { file_id, range } =
|
||||||
|
self.sema.original_range(name.syntax());
|
||||||
let reference = FileReference {
|
let reference = FileReference {
|
||||||
range,
|
range,
|
||||||
name: ast::NameLike::Name(name.clone()),
|
name: ast::NameLike::Name(name.clone()),
|
||||||
@@ -638,18 +634,15 @@ impl<'a> FindUsages<'a> {
|
|||||||
|
|
||||||
fn def_to_ty(sema: &Semantics<RootDatabase>, def: &Definition) -> Option<hir::Type> {
|
fn def_to_ty(sema: &Semantics<RootDatabase>, def: &Definition) -> Option<hir::Type> {
|
||||||
match def {
|
match def {
|
||||||
Definition::ModuleDef(def) => match def {
|
Definition::Adt(adt) => Some(adt.ty(sema.db)),
|
||||||
ModuleDef::Adt(adt) => Some(adt.ty(sema.db)),
|
Definition::TypeAlias(it) => Some(it.ty(sema.db)),
|
||||||
ModuleDef::TypeAlias(it) => Some(it.ty(sema.db)),
|
Definition::BuiltinType(it) => {
|
||||||
ModuleDef::BuiltinType(it) => {
|
|
||||||
let graph = sema.db.crate_graph();
|
let graph = sema.db.crate_graph();
|
||||||
let krate = graph.iter().next()?;
|
let krate = graph.iter().next()?;
|
||||||
let root_file = graph[krate].root_file_id;
|
let root_file = graph[krate].root_file_id;
|
||||||
let module = sema.to_module_def(root_file)?;
|
let module = sema.to_module_def(root_file)?;
|
||||||
Some(it.ty(sema.db, module))
|
Some(it.ty(sema.db, module))
|
||||||
}
|
}
|
||||||
_ => None,
|
|
||||||
},
|
|
||||||
Definition::SelfType(it) => Some(it.self_ty(sema.db)),
|
Definition::SelfType(it) => Some(it.self_ty(sema.db)),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user