Reorganise code

This commit is contained in:
Zac Pullar-Strecker
2020-08-24 20:26:45 +12:00
parent b34ad4bc8a
commit 4f5f608b49
9 changed files with 347 additions and 260 deletions

View File

@@ -16,7 +16,7 @@ use hir_def::{
type_ref::{Mutability, TypeRef},
AdtId, AssocContainerId, ConstId, DefWithBodyId, EnumId, FunctionId, GenericDefId, HasModule,
ImplId, LocalEnumVariantId, LocalFieldId, LocalModuleId, Lookup, ModuleId, StaticId, StructId,
TraitId, TypeAliasId, TypeParamId, UnionId,
TraitId, TypeAliasId, TypeParamId, UnionId, VariantId,
};
use hir_expand::{
diagnostics::DiagnosticSink,
@@ -35,12 +35,14 @@ use ra_syntax::{
ast::{self, AttrsOwner, NameOwner},
AstNode,
};
use ra_tt::{Ident, Leaf, Literal, TokenTree};
use rustc_hash::FxHashSet;
use stdx::impl_from;
use crate::{
db::{DefDatabase, HirDatabase},
has_source::HasSource,
link_rewrite::Resolvable,
HirDisplay, InFile, Name,
};
@@ -120,6 +122,33 @@ impl Crate {
pub fn all(db: &dyn HirDatabase) -> Vec<Crate> {
db.crate_graph().iter().map(|id| Crate { id }).collect()
}
/// Try to get the root URL of the documentation of a crate.
pub fn get_doc_url(self: &Crate, db: &dyn HirDatabase) -> Option<String> {
// Look for #![doc(html_root_url = "...")]
let attrs = db.attrs(AttrDef::from(self.root_module(db)?).into());
let doc_attr_q = attrs.by_key("doc");
let doc_url = if doc_attr_q.exists() {
doc_attr_q.tt_values().map(|tt| {
let name = tt.token_trees.iter()
.skip_while(|tt| !matches!(tt, TokenTree::Leaf(Leaf::Ident(Ident{text: ref ident, ..})) if ident == "html_root_url"))
.skip(2)
.next();
match name {
Some(TokenTree::Leaf(Leaf::Literal(Literal{ref text, ..}))) => Some(text),
_ => None
}
}).flat_map(|t| t).next().map(|s| s.to_string())
} else {
None
};
doc_url
.map(|s| s.trim_matches('"').trim_end_matches("/").to_owned() + "/")
.map(|s| s.to_string())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -1709,3 +1738,76 @@ pub trait HasVisibility {
vis.is_visible_from(db.upcast(), module.id)
}
}
impl Resolvable for ModuleDef {
fn resolver<D: DefDatabase + HirDatabase>(&self, db: &D) -> Option<Resolver> {
Some(match self {
ModuleDef::Module(m) => ModuleId::from(m.clone()).resolver(db),
ModuleDef::Function(f) => FunctionId::from(f.clone()).resolver(db),
ModuleDef::Adt(adt) => AdtId::from(adt.clone()).resolver(db),
ModuleDef::EnumVariant(ev) => {
GenericDefId::from(GenericDef::from(ev.clone())).resolver(db)
}
ModuleDef::Const(c) => GenericDefId::from(GenericDef::from(c.clone())).resolver(db),
ModuleDef::Static(s) => StaticId::from(s.clone()).resolver(db),
ModuleDef::Trait(t) => TraitId::from(t.clone()).resolver(db),
ModuleDef::TypeAlias(t) => ModuleId::from(t.module(db)).resolver(db),
// FIXME: This should be a resolver relative to `std/core`
ModuleDef::BuiltinType(_t) => None?,
})
}
fn try_into_module_def(self) -> Option<ModuleDef> {
Some(self)
}
}
impl Resolvable for TypeParam {
fn resolver<D: DefDatabase + HirDatabase>(&self, db: &D) -> Option<Resolver> {
Some(Into::<ModuleId>::into(self.module(db)).resolver(db))
}
fn try_into_module_def(self) -> Option<ModuleDef> {
None
}
}
impl Resolvable for MacroDef {
fn resolver<D: DefDatabase + HirDatabase>(&self, db: &D) -> Option<Resolver> {
Some(Into::<ModuleId>::into(self.module(db)?).resolver(db))
}
fn try_into_module_def(self) -> Option<ModuleDef> {
None
}
}
impl Resolvable for Field {
fn resolver<D: DefDatabase + HirDatabase>(&self, db: &D) -> Option<Resolver> {
Some(Into::<VariantId>::into(Into::<VariantDef>::into(self.parent_def(db))).resolver(db))
}
fn try_into_module_def(self) -> Option<ModuleDef> {
None
}
}
impl Resolvable for ImplDef {
fn resolver<D: DefDatabase + HirDatabase>(&self, db: &D) -> Option<Resolver> {
Some(Into::<ModuleId>::into(self.module(db)).resolver(db))
}
fn try_into_module_def(self) -> Option<ModuleDef> {
None
}
}
impl Resolvable for Local {
fn resolver<D: DefDatabase + HirDatabase>(&self, db: &D) -> Option<Resolver> {
Some(Into::<ModuleId>::into(self.module(db)).resolver(db))
}
fn try_into_module_def(self) -> Option<ModuleDef> {
None
}
}