mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-10 23:06:23 +00:00
Resolve foreign macros
This commit is contained in:
parent
d6dd902616
commit
7ac48d793b
@ -409,7 +409,7 @@ impl<'a> Resolver<'a> {
|
|||||||
def
|
def
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_macro_to_def_inner(&mut self, scope: Mark, path: &ast::Path,
|
pub fn resolve_macro_to_def_inner(&mut self, scope: Mark, path: &ast::Path,
|
||||||
kind: MacroKind, force: bool)
|
kind: MacroKind, force: bool)
|
||||||
-> Result<Def, Determinacy> {
|
-> Result<Def, Determinacy> {
|
||||||
let ast::Path { ref segments, span } = *path;
|
let ast::Path { ref segments, span } = *path;
|
||||||
|
@ -135,7 +135,11 @@ pub fn record_extern_fqn(cx: &DocContext, did: DefId, kind: clean::TypeKind) {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let fqn = once(crate_name).chain(relative).collect();
|
let fqn = if let clean::TypeKind::Macro = kind {
|
||||||
|
vec![crate_name, relative.last().unwrap()]
|
||||||
|
} else {
|
||||||
|
once(crate_name).chain(relative).collect()
|
||||||
|
};
|
||||||
cx.renderinfo.borrow_mut().external_paths.insert(did, (fqn, kind));
|
cx.renderinfo.borrow_mut().external_paths.insert(did, (fqn, kind));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -824,6 +824,16 @@ impl AttributesExt for Attributes {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum PathKind {
|
||||||
|
/// can be either value or type, not a macro
|
||||||
|
Unknown,
|
||||||
|
/// macro
|
||||||
|
Macro,
|
||||||
|
/// values, functions, consts, statics, everything in the value namespace
|
||||||
|
Value,
|
||||||
|
/// types, traits, everything in the type namespace
|
||||||
|
Type
|
||||||
|
}
|
||||||
impl Clean<Attributes> for [ast::Attribute] {
|
impl Clean<Attributes> for [ast::Attribute] {
|
||||||
fn clean(&self, cx: &DocContext) -> Attributes {
|
fn clean(&self, cx: &DocContext) -> Attributes {
|
||||||
let mut attrs = Attributes::from_ast(cx.sess().diagnostic(), self);
|
let mut attrs = Attributes::from_ast(cx.sess().diagnostic(), self);
|
||||||
@ -831,27 +841,26 @@ impl Clean<Attributes> for [ast::Attribute] {
|
|||||||
if UnstableFeatures::from_environment().is_nightly_build() {
|
if UnstableFeatures::from_environment().is_nightly_build() {
|
||||||
let dox = attrs.collapsed_doc_value().unwrap_or_else(String::new);
|
let dox = attrs.collapsed_doc_value().unwrap_or_else(String::new);
|
||||||
for link in markdown_links(&dox, cx.render_type) {
|
for link in markdown_links(&dox, cx.render_type) {
|
||||||
let path = {
|
let def = {
|
||||||
let is_value;
|
let mut kind = PathKind::Unknown;
|
||||||
let path_str = if let Some(prefix) =
|
let path_str = if let Some(prefix) =
|
||||||
["struct", "enum", "type",
|
["struct", "enum", "type",
|
||||||
"trait", "union"].iter()
|
"trait", "union"].iter()
|
||||||
.find(|p| link.starts_with(**p)) {
|
.find(|p| link.starts_with(**p)) {
|
||||||
is_value = Some(false);
|
kind = PathKind::Type;
|
||||||
link.trim_left_matches(prefix).trim()
|
link.trim_left_matches(prefix).trim()
|
||||||
} else if let Some(prefix) =
|
} else if let Some(prefix) =
|
||||||
["const", "static"].iter()
|
["const", "static"].iter()
|
||||||
.find(|p| link.starts_with(**p)) {
|
.find(|p| link.starts_with(**p)) {
|
||||||
is_value = Some(true);
|
kind = PathKind::Value;
|
||||||
link.trim_left_matches(prefix).trim()
|
link.trim_left_matches(prefix).trim()
|
||||||
} else if link.ends_with("()") {
|
} else if link.ends_with("()") {
|
||||||
is_value = Some(true);
|
kind = PathKind::Value;
|
||||||
link.trim_right_matches("()").trim()
|
link.trim_right_matches("()").trim()
|
||||||
} else if link.ends_with("!") {
|
} else if link.ends_with('!') {
|
||||||
// FIXME (misdreavus): macros are resolved with different machinery
|
kind = PathKind::Macro;
|
||||||
continue;
|
link.trim_right_matches('!').trim()
|
||||||
} else {
|
} else {
|
||||||
is_value = None;
|
|
||||||
link.trim()
|
link.trim()
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -879,34 +888,68 @@ impl Clean<Attributes> for [ast::Attribute] {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(is_value) = is_value {
|
match kind {
|
||||||
if let Ok(path) = resolve(is_value) {
|
PathKind::Value => {
|
||||||
path
|
if let Ok(path) = resolve(true) {
|
||||||
} else {
|
path.def
|
||||||
// this could just be a normal link or a broken link
|
} else {
|
||||||
// we could potentially check if something is
|
// this could just be a normal link or a broken link
|
||||||
// "intra-doc-link-like" and warn in that case
|
// we could potentially check if something is
|
||||||
continue;
|
// "intra-doc-link-like" and warn in that case
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
PathKind::Type => {
|
||||||
// try both!
|
if let Ok(path) = resolve(false) {
|
||||||
// It is imperative we search for not-a-value first
|
path.def
|
||||||
// Otherwise we will find struct ctors for when we are looking
|
} else {
|
||||||
// for structs, etc, and the link won't work.
|
// this could just be a normal link
|
||||||
if let Ok(path) = resolve(false) {
|
continue;
|
||||||
path
|
}
|
||||||
} else if let Ok(path) = resolve(true) {
|
}
|
||||||
path
|
PathKind::Unknown => {
|
||||||
} else {
|
// try both!
|
||||||
// this could just be a normal link
|
// It is imperative we search for not-a-value first
|
||||||
continue;
|
// Otherwise we will find struct ctors for when we are looking
|
||||||
|
// for structs, etc, and the link won't work.
|
||||||
|
if let Ok(path) = resolve(false) {
|
||||||
|
path.def
|
||||||
|
} else if let Ok(path) = resolve(true) {
|
||||||
|
path.def
|
||||||
|
} else {
|
||||||
|
// this could just be a normal link
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PathKind::Macro => {
|
||||||
|
use syntax::ext::base::MacroKind;
|
||||||
|
use syntax::ext::hygiene::Mark;
|
||||||
|
let segment = ast::PathSegment {
|
||||||
|
identifier: ast::Ident::from_str(path_str),
|
||||||
|
span: DUMMY_SP,
|
||||||
|
parameters: None,
|
||||||
|
};
|
||||||
|
let path = ast::Path {
|
||||||
|
span: DUMMY_SP,
|
||||||
|
segments: vec![segment],
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut resolver = cx.resolver.borrow_mut();
|
||||||
|
let mark = Mark::root();
|
||||||
|
let res = resolver
|
||||||
|
.resolve_macro_to_def_inner(mark, &path, MacroKind::Bang, false);
|
||||||
|
if let Ok(def) = res {
|
||||||
|
def
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
register_def(cx, def);
|
|
||||||
|
|
||||||
attrs.links.push((link, path.def.def_id()));
|
register_def(cx, def);
|
||||||
|
attrs.links.push((link, def.def_id()));
|
||||||
}
|
}
|
||||||
|
|
||||||
cx.sess().abort_if_errors();
|
cx.sess().abort_if_errors();
|
||||||
@ -1970,6 +2013,7 @@ pub enum TypeKind {
|
|||||||
Variant,
|
Variant,
|
||||||
Typedef,
|
Typedef,
|
||||||
Foreign,
|
Foreign,
|
||||||
|
Macro,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait GetDefId {
|
pub trait GetDefId {
|
||||||
@ -3271,6 +3315,7 @@ fn register_def(cx: &DocContext, def: Def) -> DefId {
|
|||||||
Def::TyForeign(i) => (i, TypeKind::Foreign),
|
Def::TyForeign(i) => (i, TypeKind::Foreign),
|
||||||
Def::Static(i, _) => (i, TypeKind::Static),
|
Def::Static(i, _) => (i, TypeKind::Static),
|
||||||
Def::Variant(i) => (cx.tcx.parent_def_id(i).unwrap(), TypeKind::Enum),
|
Def::Variant(i) => (cx.tcx.parent_def_id(i).unwrap(), TypeKind::Enum),
|
||||||
|
Def::Macro(i, _) => (i, TypeKind::Macro),
|
||||||
Def::SelfTy(Some(def_id), _) => (def_id, TypeKind::Trait),
|
Def::SelfTy(Some(def_id), _) => (def_id, TypeKind::Trait),
|
||||||
Def::SelfTy(_, Some(impl_def_id)) => {
|
Def::SelfTy(_, Some(impl_def_id)) => {
|
||||||
return impl_def_id
|
return impl_def_id
|
||||||
|
@ -102,6 +102,7 @@ impl From<clean::TypeKind> for ItemType {
|
|||||||
clean::TypeKind::Variant => ItemType::Variant,
|
clean::TypeKind::Variant => ItemType::Variant,
|
||||||
clean::TypeKind::Typedef => ItemType::Typedef,
|
clean::TypeKind::Typedef => ItemType::Typedef,
|
||||||
clean::TypeKind::Foreign => ItemType::ForeignType,
|
clean::TypeKind::Foreign => ItemType::ForeignType,
|
||||||
|
clean::TypeKind::Macro => ItemType::Macro,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1284,7 +1284,7 @@ impl DocFolder for Cache {
|
|||||||
clean::FunctionItem(..) | clean::ModuleItem(..) |
|
clean::FunctionItem(..) | clean::ModuleItem(..) |
|
||||||
clean::ForeignFunctionItem(..) | clean::ForeignStaticItem(..) |
|
clean::ForeignFunctionItem(..) | clean::ForeignStaticItem(..) |
|
||||||
clean::ConstantItem(..) | clean::StaticItem(..) |
|
clean::ConstantItem(..) | clean::StaticItem(..) |
|
||||||
clean::UnionItem(..) | clean::ForeignTypeItem
|
clean::UnionItem(..) | clean::ForeignTypeItem | clean::MacroItem(..)
|
||||||
if !self.stripped_mod => {
|
if !self.stripped_mod => {
|
||||||
// Re-exported items mean that the same id can show up twice
|
// Re-exported items mean that the same id can show up twice
|
||||||
// in the rustdoc ast that we're looking at. We know,
|
// in the rustdoc ast that we're looking at. We know,
|
||||||
|
Loading…
Reference in New Issue
Block a user