Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
90019189
R
Rust
项目概览
int
/
Rust
12 个月 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
90019189
编写于
11月 29, 2016
作者:
E
Eduard-Mihai Burtescu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
rustdoc: link to cross-crate sources directly.
上级
177913b4
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
173 addition
and
218 deletion
+173
-218
src/librustdoc/clean/inline.rs
src/librustdoc/clean/inline.rs
+5
-5
src/librustdoc/clean/mod.rs
src/librustdoc/clean/mod.rs
+82
-93
src/librustdoc/core.rs
src/librustdoc/core.rs
+0
-2
src/librustdoc/html/format.rs
src/librustdoc/html/format.rs
+12
-10
src/librustdoc/html/render.rs
src/librustdoc/html/render.rs
+70
-96
src/librustdoc/html/static/main.js
src/librustdoc/html/static/main.js
+0
-9
src/test/rustdoc/issue-34274.rs
src/test/rustdoc/issue-34274.rs
+1
-1
src/test/rustdoc/src-links-external.rs
src/test/rustdoc/src-links-external.rs
+3
-2
未找到文件。
src/librustdoc/clean/inline.rs
浏览文件 @
90019189
...
...
@@ -115,7 +115,7 @@ fn try_inline_def(cx: &DocContext, def: Def) -> Option<Vec<clean::Item>> {
let
did
=
def
.def_id
();
cx
.renderinfo
.borrow_mut
()
.inlined
.insert
(
did
);
ret
.push
(
clean
::
Item
{
source
:
clean
::
Span
::
empty
(
),
source
:
tcx
.def_span
(
did
)
.clean
(
cx
),
name
:
Some
(
tcx
.item_name
(
did
)
.to_string
()),
attrs
:
load_attrs
(
cx
,
did
),
inner
:
inner
,
...
...
@@ -321,7 +321,7 @@ pub fn build_impl(cx: &DocContext, did: DefId, ret: &mut Vec<clean::Item>) {
clean
::
RegionBound
(
..
)
=>
unreachable!
(),
},
}),
source
:
clean
::
Span
::
empty
(
),
source
:
tcx
.def_span
(
did
)
.clean
(
cx
),
name
:
None
,
attrs
:
attrs
,
visibility
:
Some
(
clean
::
Inherited
),
...
...
@@ -357,7 +357,7 @@ pub fn build_impl(cx: &DocContext, did: DefId, ret: &mut Vec<clean::Item>) {
tcx
.item_type
(
item
.def_id
)
.clean
(
cx
),
default
,
),
source
:
clean
::
Span
::
empty
(
),
source
:
tcx
.def_span
(
item
.def_id
)
.clean
(
cx
),
attrs
:
clean
::
Attributes
::
default
(),
visibility
:
None
,
stability
:
tcx
.lookup_stability
(
item
.def_id
)
.clean
(
cx
),
...
...
@@ -404,7 +404,7 @@ pub fn build_impl(cx: &DocContext, did: DefId, ret: &mut Vec<clean::Item>) {
Some
(
clean
::
Item
{
name
:
Some
(
item
.name
.clean
(
cx
)),
inner
:
clean
::
TypedefItem
(
typedef
,
true
),
source
:
clean
::
Span
::
empty
(
),
source
:
tcx
.def_span
(
item
.def_id
)
.clean
(
cx
),
attrs
:
clean
::
Attributes
::
default
(),
visibility
:
None
,
stability
:
tcx
.lookup_stability
(
item
.def_id
)
.clean
(
cx
),
...
...
@@ -442,7 +442,7 @@ pub fn build_impl(cx: &DocContext, did: DefId, ret: &mut Vec<clean::Item>) {
items
:
trait_items
,
polarity
:
Some
(
polarity
.clean
(
cx
)),
}),
source
:
clean
::
Span
::
empty
(
),
source
:
tcx
.def_span
(
did
)
.clean
(
cx
),
name
:
None
,
attrs
:
attrs
,
visibility
:
Some
(
clean
::
Inherited
),
...
...
src/librustdoc/clean/mod.rs
浏览文件 @
90019189
...
...
@@ -27,11 +27,10 @@
use
syntax
::
symbol
::
keywords
;
use
syntax_pos
::{
self
,
DUMMY_SP
,
Pos
};
use
rustc_trans
::
back
::
link
;
use
rustc
::
middle
::
privacy
::
AccessLevels
;
use
rustc
::
middle
::
resolve_lifetime
::
DefRegion
::
*
;
use
rustc
::
hir
::
def
::{
Def
,
CtorKind
};
use
rustc
::
hir
::
def_id
::{
self
,
DefId
,
DefIndex
,
CRATE_DEF_INDEX
};
use
rustc
::
hir
::
def_id
::{
CrateNum
,
DefId
,
CRATE_DEF_INDEX
,
LOCAL_CRATE
};
use
rustc
::
hir
::
print
as
pprust
;
use
rustc
::
ty
::
subst
::
Substs
;
use
rustc
::
ty
::{
self
,
AdtKind
};
...
...
@@ -45,7 +44,6 @@
use
std
::
slice
;
use
std
::
sync
::
Arc
;
use
std
::
u32
;
use
std
::
env
::
current_dir
;
use
std
::
mem
;
use
core
::
DocContext
;
...
...
@@ -110,19 +108,16 @@ pub struct Crate {
pub
name
:
String
,
pub
src
:
PathBuf
,
pub
module
:
Option
<
Item
>
,
pub
externs
:
Vec
<
(
def_id
::
CrateNum
,
ExternalCrate
)
>
,
pub
primitives
:
Vec
<
PrimitiveType
>
,
pub
externs
:
Vec
<
(
CrateNum
,
ExternalCrate
)
>
,
pub
primitives
:
Vec
<
(
DefId
,
PrimitiveType
,
Attributes
)
>
,
pub
access_levels
:
Arc
<
AccessLevels
<
DefId
>>
,
// These are later on moved into `CACHEKEY`, leaving the map empty.
// Only here so that they can be filtered through the rustdoc passes.
pub
external_traits
:
FxHashMap
<
DefId
,
Trait
>
,
}
struct
CrateNum
(
def_id
::
CrateNum
);
impl
<
'a
,
'tcx
>
Clean
<
Crate
>
for
visit_ast
::
RustdocVisitor
<
'a
,
'tcx
>
{
fn
clean
(
&
self
,
cx
:
&
DocContext
)
->
Crate
{
use
rustc
::
session
::
config
::
Input
;
use
::
visit_lib
::
LibEmbargoVisitor
;
{
...
...
@@ -133,83 +128,41 @@ fn clean(&self, cx: &DocContext) -> Crate {
let
mut
externs
=
Vec
::
new
();
for
cnum
in
cx
.sess
()
.cstore
.crates
()
{
externs
.push
((
cnum
,
CrateNum
(
cnum
)
.clean
(
cx
)));
externs
.push
((
cnum
,
cnum
.clean
(
cx
)));
// Analyze doc-reachability for extern items
LibEmbargoVisitor
::
new
(
cx
)
.visit_lib
(
cnum
);
}
externs
.sort_by
(|
&
(
a
,
_
),
&
(
b
,
_
)|
a
.cmp
(
&
b
));
// Figure out the name of this crate
let
input
=
&
cx
.input
;
let
name
=
link
::
find_crate_name
(
None
,
&
self
.attrs
,
input
);
// Clean the crate, translating the entire libsyntax AST to one that is
// understood by rustdoc.
let
mut
module
=
self
.module
.clean
(
cx
);
// Collect all inner modules which are tagged as implementations of
// primitives.
//
// Note that this loop only searches the top-level items of the crate,
// and this is intentional. If we were to search the entire crate for an
// item tagged with `#[doc(primitive)]` then we would also have to
// search the entirety of external modules for items tagged
// `#[doc(primitive)]`, which is a pretty inefficient process (decoding
// all that metadata unconditionally).
//
// In order to keep the metadata load under control, the
// `#[doc(primitive)]` feature is explicitly designed to only allow the
// primitive tags to show up as the top level items in a crate.
//
// Also note that this does not attempt to deal with modules tagged
// duplicately for the same primitive. This is handled later on when
// rendering by delegating everything to a hash map.
let
mut
primitives
=
Vec
::
new
();
let
ExternalCrate
{
name
,
src
,
primitives
,
..
}
=
LOCAL_CRATE
.clean
(
cx
);
{
let
m
=
match
module
.inner
{
ModuleItem
(
ref
mut
m
)
=>
m
,
_
=>
unreachable!
(),
};
let
mut
tmp
=
Vec
::
new
();
for
child
in
&
mut
m
.items
{
if
!
child
.is_mod
()
{
continue
;
}
let
prim
=
match
PrimitiveType
::
find
(
&
child
.attrs
)
{
Some
(
prim
)
=>
prim
,
None
=>
continue
,
};
primitives
.push
(
prim
);
tmp
.push
(
Item
{
m
.items
.extend
(
primitives
.iter
()
.map
(|
&
(
def_id
,
prim
,
ref
attrs
)|
{
Item
{
source
:
Span
::
empty
(),
name
:
Some
(
prim
.to_url_str
()
.to_string
()),
attrs
:
child
.
attrs
.clone
(),
attrs
:
attrs
.clone
(),
visibility
:
Some
(
Public
),
stability
:
None
,
deprecation
:
None
,
def_id
:
DefId
::
local
(
prim
.to_def_index
())
,
def_id
:
def_id
,
inner
:
PrimitiveItem
(
prim
),
});
}
m
.items
.extend
(
tmp
);
}
let
src
=
match
cx
.input
{
Input
::
File
(
ref
path
)
=>
{
if
path
.is_absolute
()
{
path
.clone
()
}
else
{
current_dir
()
.unwrap
()
.join
(
path
)
}
},
Input
::
Str
{
ref
name
,
..
}
=>
PathBuf
::
from
(
name
.clone
()),
};
}));
}
let
mut
access_levels
=
cx
.access_levels
.borrow_mut
();
let
mut
external_traits
=
cx
.external_traits
.borrow_mut
();
Crate
{
name
:
name
.to_string
()
,
name
:
name
,
src
:
src
,
module
:
Some
(
module
),
externs
:
externs
,
...
...
@@ -223,21 +176,78 @@ fn clean(&self, cx: &DocContext) -> Crate {
#[derive(Clone,
RustcEncodable,
RustcDecodable,
Debug)]
pub
struct
ExternalCrate
{
pub
name
:
String
,
pub
src
:
PathBuf
,
pub
attrs
:
Attributes
,
pub
primitives
:
Vec
<
PrimitiveType
>
,
pub
primitives
:
Vec
<
(
DefId
,
PrimitiveType
,
Attributes
)
>
,
}
impl
Clean
<
ExternalCrate
>
for
CrateNum
{
fn
clean
(
&
self
,
cx
:
&
DocContext
)
->
ExternalCrate
{
let
mut
primitives
=
Vec
::
new
();
let
root
=
DefId
{
krate
:
self
.0
,
index
:
CRATE_DEF_INDEX
};
for
item
in
cx
.tcx.sess.cstore
.item_children
(
root
)
{
let
attrs
=
inline
::
load_attrs
(
cx
,
item
.def
.def_id
());
PrimitiveType
::
find
(
&
attrs
)
.map
(|
prim
|
primitives
.push
(
prim
));
}
let
root
=
DefId
{
krate
:
*
self
,
index
:
CRATE_DEF_INDEX
};
let
krate_span
=
cx
.tcx
.def_span
(
root
);
let
krate_src
=
cx
.sess
()
.codemap
()
.span_to_filename
(
krate_span
);
// Collect all inner modules which are tagged as implementations of
// primitives.
//
// Note that this loop only searches the top-level items of the crate,
// and this is intentional. If we were to search the entire crate for an
// item tagged with `#[doc(primitive)]` then we would also have to
// search the entirety of external modules for items tagged
// `#[doc(primitive)]`, which is a pretty inefficient process (decoding
// all that metadata unconditionally).
//
// In order to keep the metadata load under control, the
// `#[doc(primitive)]` feature is explicitly designed to only allow the
// primitive tags to show up as the top level items in a crate.
//
// Also note that this does not attempt to deal with modules tagged
// duplicately for the same primitive. This is handled later on when
// rendering by delegating everything to a hash map.
let
as_primitive
=
|
def
:
Def
|
{
if
let
Def
::
Mod
(
def_id
)
=
def
{
let
attrs
=
cx
.tcx
.get_attrs
(
def_id
)
.clean
(
cx
);
let
mut
prim
=
None
;
for
attr
in
attrs
.lists
(
"doc"
)
{
if
let
Some
(
v
)
=
attr
.value_str
()
{
if
attr
.check_name
(
"primitive"
)
{
prim
=
PrimitiveType
::
from_str
(
&
v
.as_str
());
if
prim
.is_some
()
{
break
;
}
}
}
}
return
prim
.map
(|
p
|
(
def_id
,
p
,
attrs
));
}
None
};
let
primitives
=
if
root
.is_local
()
{
cx
.tcx.map
.krate
()
.module.item_ids
.iter
()
.filter_map
(|
&
id
|
{
let
item
=
cx
.tcx.map
.expect_item
(
id
.id
);
match
item
.node
{
hir
::
ItemMod
(
_
)
=>
{
as_primitive
(
Def
::
Mod
(
cx
.tcx.map
.local_def_id
(
id
.id
)))
}
hir
::
ItemUse
(
ref
path
,
hir
::
UseKind
::
Single
)
if
item
.vis
==
hir
::
Visibility
::
Public
=>
{
as_primitive
(
path
.def
)
.map
(|(
_
,
prim
,
attrs
)|
{
// Pretend the primitive is local.
(
cx
.tcx.map
.local_def_id
(
id
.id
),
prim
,
attrs
)
})
}
_
=>
None
}
})
.collect
()
}
else
{
cx
.tcx.sess.cstore
.item_children
(
root
)
.iter
()
.map
(|
item
|
item
.def
)
.filter_map
(
as_primitive
)
.collect
()
};
ExternalCrate
{
name
:
cx
.sess
()
.cstore
.crate_name
(
self
.0
)
.to_string
(),
attrs
:
cx
.sess
()
.cstore
.item_attrs
(
root
)
.clean
(
cx
),
name
:
cx
.tcx
.crate_name
(
*
self
)
.to_string
(),
src
:
PathBuf
::
from
(
krate_src
),
attrs
:
cx
.tcx
.get_attrs
(
root
)
.clean
(
cx
),
primitives
:
primitives
,
}
}
...
...
@@ -1460,7 +1470,7 @@ fn clean(&self, cx: &DocContext) -> Item {
deprecation
:
get_deprecation
(
cx
,
self
.def_id
),
def_id
:
self
.def_id
,
attrs
:
inline
::
load_attrs
(
cx
,
self
.def_id
),
source
:
Span
::
empty
(
),
source
:
cx
.tcx
.def_span
(
self
.def_id
)
.clean
(
cx
),
inner
:
inner
,
}
}
...
...
@@ -1618,19 +1628,6 @@ fn from_str(s: &str) -> Option<PrimitiveType> {
}
}
fn
find
(
attrs
:
&
Attributes
)
->
Option
<
PrimitiveType
>
{
for
attr
in
attrs
.lists
(
"doc"
)
{
if
let
Some
(
v
)
=
attr
.value_str
()
{
if
attr
.check_name
(
"primitive"
)
{
if
let
ret
@
Some
(
..
)
=
PrimitiveType
::
from_str
(
&
v
.as_str
())
{
return
ret
;
}
}
}
}
None
}
pub
fn
as_str
(
&
self
)
->
&
'static
str
{
match
*
self
{
PrimitiveType
::
Isize
=>
"isize"
,
...
...
@@ -1658,14 +1655,6 @@ pub fn as_str(&self) -> &'static str {
pub
fn
to_url_str
(
&
self
)
->
&
'static
str
{
self
.as_str
()
}
/// Creates a rustdoc-specific node id for primitive types.
///
/// These node ids are generally never used by the AST itself.
pub
fn
to_def_index
(
&
self
)
->
DefIndex
{
let
x
=
u32
::
MAX
-
1
-
(
*
self
as
u32
);
DefIndex
::
new
(
x
as
usize
)
}
}
impl
From
<
ast
::
IntTy
>
for
PrimitiveType
{
...
...
@@ -1948,7 +1937,7 @@ fn clean(&self, cx: &DocContext) -> Item {
Item
{
name
:
Some
(
self
.name
)
.clean
(
cx
),
attrs
:
cx
.tcx
.get_attrs
(
self
.did
)
.clean
(
cx
),
source
:
Span
::
empty
(
),
source
:
cx
.tcx
.def_span
(
self
.did
)
.clean
(
cx
),
visibility
:
self
.vis
.clean
(
cx
),
stability
:
get_stability
(
cx
,
self
.did
),
deprecation
:
get_deprecation
(
cx
,
self
.did
),
...
...
@@ -2115,7 +2104,7 @@ fn clean(&self, cx: &DocContext) -> Item {
fields_stripped
:
false
,
fields
:
self
.fields
.iter
()
.map
(|
field
|
{
Item
{
source
:
Span
::
empty
(
),
source
:
cx
.tcx
.def_span
(
field
.did
)
.clean
(
cx
),
name
:
Some
(
field
.name
.clean
(
cx
)),
attrs
:
cx
.tcx
.get_attrs
(
field
.did
)
.clean
(
cx
),
visibility
:
field
.vis
.clean
(
cx
),
...
...
@@ -2131,7 +2120,7 @@ fn clean(&self, cx: &DocContext) -> Item {
Item
{
name
:
Some
(
self
.name
.clean
(
cx
)),
attrs
:
inline
::
load_attrs
(
cx
,
self
.did
),
source
:
Span
::
empty
(
),
source
:
cx
.tcx
.def_span
(
self
.did
)
.clean
(
cx
),
visibility
:
Some
(
Inherited
),
def_id
:
self
.did
,
inner
:
VariantItem
(
Variant
{
kind
:
kind
}),
...
...
src/librustdoc/core.rs
浏览文件 @
90019189
...
...
@@ -45,7 +45,6 @@
pub
struct
DocContext
<
'a
,
'tcx
:
'a
>
{
pub
tcx
:
TyCtxt
<
'a
,
'tcx
,
'tcx
>
,
pub
input
:
Input
,
pub
populated_all_crate_impls
:
Cell
<
bool
>
,
// Note that external items for which `doc(hidden)` applies to are shown as
// non-reachable while local items aren't. This is because we're reusing
...
...
@@ -187,7 +186,6 @@ pub fn run_core(search_paths: SearchPaths,
let
ctxt
=
DocContext
{
tcx
:
tcx
,
input
:
input
,
populated_all_crate_impls
:
Cell
::
new
(
false
),
access_levels
:
RefCell
::
new
(
access_levels
),
external_traits
:
Default
::
default
(),
...
...
src/librustdoc/html/format.rs
浏览文件 @
90019189
...
...
@@ -18,7 +18,7 @@
use
std
::
fmt
;
use
std
::
iter
::
repeat
;
use
rustc
::
hir
::
def_id
::
{
DefId
,
LOCAL_CRATE
}
;
use
rustc
::
hir
::
def_id
::
DefId
;
use
syntax
::
abi
::
Abi
;
use
rustc
::
hir
;
...
...
@@ -403,9 +403,9 @@ pub fn href(did: DefId) -> Option<(String, ItemType, Vec<String>)> {
None
=>
match
cache
.external_paths
.get
(
&
did
)
{
Some
(
&
(
ref
fqp
,
shortty
))
=>
{
(
fqp
,
shortty
,
match
cache
.extern_locations
[
&
did
.krate
]
{
(
_
,
render
::
Remote
(
ref
s
))
=>
s
.to_string
(),
(
_
,
render
::
Local
)
=>
repeat
(
"../"
)
.take
(
loc
.len
())
.collect
(),
(
_
,
render
::
Unknown
)
=>
return
None
,
(
..
,
render
::
Remote
(
ref
s
))
=>
s
.to_string
(),
(
..
,
render
::
Local
)
=>
repeat
(
"../"
)
.take
(
loc
.len
())
.collect
(),
(
..
,
render
::
Unknown
)
=>
return
None
,
})
}
None
=>
return
None
,
...
...
@@ -479,7 +479,7 @@ fn primitive_link(f: &mut fmt::Formatter,
let
mut
needs_termination
=
false
;
if
!
f
.alternate
()
{
match
m
.primitive_locations
.get
(
&
prim
)
{
Some
(
&
LOCAL_CRATE
)
=>
{
Some
(
&
def_id
)
if
def_id
.is_local
(
)
=>
{
let
len
=
CURRENT_LOCATION_KEY
.with
(|
s
|
s
.borrow
()
.len
());
let
len
=
if
len
==
0
{
0
}
else
{
len
-
1
};
write!
(
f
,
"<a class='primitive' href='{}primitive.{}.html'>"
,
...
...
@@ -487,14 +487,16 @@ fn primitive_link(f: &mut fmt::Formatter,
prim
.to_url_str
())
?
;
needs_termination
=
true
;
}
Some
(
&
cnum
)
=>
{
let
loc
=
match
m
.extern_locations
[
&
cnum
]
{
(
ref
cname
,
render
::
Remote
(
ref
s
))
=>
Some
((
cname
,
s
.to_string
())),
(
ref
cname
,
render
::
Local
)
=>
{
Some
(
&
def_id
)
=>
{
let
loc
=
match
m
.extern_locations
[
&
def_id
.krate
]
{
(
ref
cname
,
_
,
render
::
Remote
(
ref
s
))
=>
{
Some
((
cname
,
s
.to_string
()))
}
(
ref
cname
,
_
,
render
::
Local
)
=>
{
let
len
=
CURRENT_LOCATION_KEY
.with
(|
s
|
s
.borrow
()
.len
());
Some
((
cname
,
repeat
(
"../"
)
.take
(
len
)
.collect
::
<
String
>
()))
}
(
_
,
render
::
Unknown
)
=>
None
,
(
..
,
render
::
Unknown
)
=>
None
,
};
if
let
Some
((
cname
,
root
))
=
loc
{
write!
(
f
,
"<a class='primitive' href='{}{}/primitive.{}.html'>"
,
...
...
src/librustdoc/html/render.rs
浏览文件 @
90019189
...
...
@@ -55,7 +55,7 @@
use
serialize
::
json
::{
ToJson
,
Json
,
as_json
};
use
syntax
::{
abi
,
ast
};
use
syntax
::
feature_gate
::
UnstableFeatures
;
use
rustc
::
hir
::
def_id
::{
CrateNum
,
CRATE_DEF_INDEX
,
DefId
,
LOCAL_CRATE
};
use
rustc
::
hir
::
def_id
::{
CrateNum
,
CRATE_DEF_INDEX
,
DefId
};
use
rustc
::
middle
::
privacy
::
AccessLevels
;
use
rustc
::
middle
::
stability
;
use
rustc
::
hir
;
...
...
@@ -241,10 +241,10 @@ pub struct Cache {
pub
implementors
:
FxHashMap
<
DefId
,
Vec
<
Implementor
>>
,
/// Cache of where external crate documentation can be found.
pub
extern_locations
:
FxHashMap
<
CrateNum
,
(
String
,
ExternalLocation
)
>
,
pub
extern_locations
:
FxHashMap
<
CrateNum
,
(
String
,
PathBuf
,
ExternalLocation
)
>
,
/// Cache of where documentation for primitives can be found.
pub
primitive_locations
:
FxHashMap
<
clean
::
PrimitiveType
,
CrateNum
>
,
pub
primitive_locations
:
FxHashMap
<
clean
::
PrimitiveType
,
DefId
>
,
// Note that external items for which `doc(hidden)` applies to are shown as
// non-reachable while local items aren't. This is because we're reusing
...
...
@@ -523,8 +523,13 @@ pub fn run(mut krate: clean::Crate,
// Cache where all our extern crates are located
for
&
(
n
,
ref
e
)
in
&
krate
.externs
{
cache
.extern_locations
.insert
(
n
,
(
e
.name
.clone
(),
let
src_root
=
match
Path
::
new
(
&
e
.src
)
.parent
()
{
Some
(
p
)
=>
p
.to_path_buf
(),
None
=>
PathBuf
::
new
(),
};
cache
.extern_locations
.insert
(
n
,
(
e
.name
.clone
(),
src_root
,
extern_location
(
e
,
&
cx
.dst
)));
let
did
=
DefId
{
krate
:
n
,
index
:
CRATE_DEF_INDEX
};
cache
.external_paths
.insert
(
did
,
(
vec!
[
e
.name
.to_string
()],
ItemType
::
Module
));
}
...
...
@@ -533,13 +538,13 @@ pub fn run(mut krate: clean::Crate,
//
// Favor linking to as local extern as possible, so iterate all crates in
// reverse topological order.
for
&
(
n
,
ref
e
)
in
krate
.externs
.iter
()
.rev
()
{
for
&
prim
in
&
e
.primitives
{
cache
.primitive_locations
.insert
(
prim
,
n
);
for
&
(
_
,
ref
e
)
in
krate
.externs
.iter
()
.rev
()
{
for
&
(
def_id
,
prim
,
_
)
in
&
e
.primitives
{
cache
.primitive_locations
.insert
(
prim
,
def_id
);
}
}
for
&
prim
in
&
krate
.primitives
{
cache
.primitive_locations
.insert
(
prim
,
LOCAL_CRATE
);
for
&
(
def_id
,
prim
,
_
)
in
&
krate
.primitives
{
cache
.primitive_locations
.insert
(
prim
,
def_id
);
}
cache
.stack
.push
(
krate
.name
.clone
());
...
...
@@ -875,6 +880,8 @@ fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
if
self
.scx.include_sources
// skip all invalid spans
&&
item
.source.filename
!=
""
// skip non-local items
&&
item
.def_id
.is_local
()
// Macros from other libraries get special filenames which we can
// safely ignore.
&&
!
(
item
.source.filename
.starts_with
(
"<"
)
...
...
@@ -1127,13 +1134,15 @@ fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
true
}
ref
t
=>
{
match
t
.primitive_type
()
{
Some
(
prim
)
=>
{
let
did
=
DefId
::
local
(
prim
.to_def_index
());
let
prim_did
=
t
.primitive_type
()
.and_then
(|
t
|
{
self
.primitive_locations
.get
(
&
t
)
.cloned
()
});
match
prim_did
{
Some
(
did
)
=>
{
self
.parent_stack
.push
(
did
);
true
}
_
=>
false
,
None
=>
false
,
}
}
}
...
...
@@ -1158,10 +1167,7 @@ fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
}
ref
t
=>
{
t
.primitive_type
()
.and_then
(|
t
|
{
self
.primitive_locations
.get
(
&
t
)
.map
(|
n
|
{
let
id
=
t
.to_def_index
();
DefId
{
krate
:
*
n
,
index
:
id
}
})
self
.primitive_locations
.get
(
&
t
)
.cloned
()
})
}
}
...
...
@@ -1439,79 +1445,50 @@ impl<'a> Item<'a> {
/// If `None` is returned, then a source link couldn't be generated. This
/// may happen, for example, with externally inlined items where the source
/// of their crate documentation isn't known.
fn
href
(
&
self
)
->
Option
<
String
>
{
let
href
=
if
self
.item.source.loline
==
self
.item.source.hiline
{
format!
(
"{}"
,
self
.item.source.loline
)
}
else
{
format!
(
"{}-{}"
,
self
.item.source.loline
,
self
.item.source.hiline
)
};
fn
src_href
(
&
self
)
->
Option
<
String
>
{
let
mut
root
=
self
.cx
.root_path
();
// First check to see if this is an imported macro source. In this case
// we need to handle it specially as cross-crate inlined macros have...
// odd locations!
let
imported_macro_from
=
match
self
.item.inner
{
clean
::
MacroItem
(
ref
m
)
=>
m
.imported_from
.as_ref
(),
_
=>
None
,
};
if
let
Some
(
krate
)
=
imported_macro_from
{
let
cache
=
cache
();
let
root
=
cache
.extern_locations
.values
()
.find
(|
&&
(
ref
n
,
_
)|
{
*
krate
==
*
n
})
.map
(|
l
|
&
l
.1
);
let
root
=
match
root
{
Some
(
&
Remote
(
ref
s
))
=>
s
.to_string
(),
Some
(
&
Local
)
=>
self
.cx
.root_path
(),
None
|
Some
(
&
Unknown
)
=>
return
None
,
};
Some
(
format!
(
"{root}/{krate}/macro.{name}.html?gotomacrosrc=1"
,
root
=
root
,
krate
=
krate
,
name
=
self
.item.name
.as_ref
()
.unwrap
()))
// If this item is part of the local crate, then we're guaranteed to
// know the span, so we plow forward and generate a proper url. The url
// has anchors for the line numbers that we're linking to.
}
else
if
self
.item.def_id
.is_local
()
{
let
cache
=
cache
();
let
mut
path
=
String
::
new
();
let
(
krate
,
path
)
=
if
self
.item.def_id
.is_local
()
{
let
path
=
PathBuf
::
from
(
&
self
.item.source.filename
);
self
.cx.shared.local_sources
.get
(
&
path
)
.map
(|
path
|
{
format!
(
"{root}src/{krate}/{path}#{href}"
,
root
=
self
.cx
.root_path
(),
krate
=
self
.cx.shared.layout.krate
,
path
=
path
,
href
=
href
)
})
// If this item is not part of the local crate, then things get a little
// trickier. We don't actually know the span of the external item, but
// we know that the documentation on the other end knows the span!
//
// In this case, we generate a link to the *documentation* for this type
// in the original crate. There's an extra URL parameter which says that
// we want to go somewhere else, and the JS on the destination page will
// pick it up and instantly redirect the browser to the source code.
//
// If we don't know where the external documentation for this crate is
// located, then we return `None`.
if
let
Some
(
path
)
=
self
.cx.shared.local_sources
.get
(
&
path
)
{
(
&
self
.cx.shared.layout.krate
,
path
)
}
else
{
return
None
;
}
}
else
{
let
cache
=
cache
();
let
external_path
=
match
cache
.external_paths
.get
(
&
self
.item.def_id
)
{
Some
(
&
(
ref
path
,
_
))
=>
path
,
None
=>
return
None
,
};
let
mut
path
=
match
cache
.extern_locations
.get
(
&
self
.item.def_id.krate
)
{
Some
(
&
(
_
,
Remote
(
ref
s
)))
=>
s
.to_string
(),
Some
(
&
(
_
,
Local
))
=>
self
.cx
.root_path
(),
Some
(
&
(
_
,
Unknown
))
=>
return
None
,
None
=>
return
None
,
let
(
krate
,
src_root
)
=
match
cache
.extern_locations
.get
(
&
self
.item.def_id.krate
)
{
Some
(
&
(
ref
name
,
ref
src
,
Local
))
=>
(
name
,
src
),
Some
(
&
(
ref
name
,
ref
src
,
Remote
(
ref
s
)))
=>
{
root
=
s
.to_string
();
(
name
,
src
)
}
Some
(
&
(
_
,
_
,
Unknown
))
|
None
=>
return
None
,
};
for
item
in
&
external_path
[
..
external_path
.len
()
-
1
]
{
path
.push_str
(
item
);
path
.push_str
(
"/"
);
}
Some
(
format!
(
"{path}{file}?gotosrc={goto}"
,
path
=
path
,
file
=
item_path
(
self
.item
.type_
(),
external_path
.last
()
.unwrap
()),
goto
=
self
.item.def_id.index
.as_usize
()))
}
let
file
=
Path
::
new
(
&
self
.item.source.filename
);
clean_srcpath
(
&
src_root
,
file
,
false
,
|
component
|
{
path
.push_str
(
component
);
path
.push
(
'/'
);
});
let
mut
fname
=
file
.file_name
()
.expect
(
"source has no filename"
)
.to_os_string
();
fname
.push
(
".html"
);
path
.push_str
(
&
fname
.to_string_lossy
());
(
krate
,
&
path
)
};
let
lines
=
if
self
.item.source.loline
==
self
.item.source.hiline
{
format!
(
"{}"
,
self
.item.source.loline
)
}
else
{
format!
(
"{}-{}"
,
self
.item.source.loline
,
self
.item.source.hiline
)
};
Some
(
format!
(
"{root}src/{krate}/{path}#{lines}"
,
root
=
root
,
krate
=
krate
,
path
=
path
,
lines
=
lines
))
}
}
...
...
@@ -1576,10 +1553,9 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
// this page, and this link will be auto-clicked. The `id` attribute is
// used to find the link to auto-click.
if
self
.cx.shared.include_sources
&&
!
self
.item
.is_primitive
()
{
if
let
Some
(
l
)
=
self
.href
()
{
write!
(
fmt
,
"<a id='src-{}' class='srclink'
\
href='{}' title='{}'>[src]</a>"
,
self
.item.def_id.index
.as_usize
(),
l
,
"goto source code"
)
?
;
if
let
Some
(
l
)
=
self
.src_href
()
{
write!
(
fmt
,
"<a class='srclink' href='{}' title='{}'>[src]</a>"
,
l
,
"goto source code"
)
?
;
}
}
...
...
@@ -2781,8 +2757,7 @@ fn render_deref_methods(w: &mut fmt::Formatter, cx: &Context, impl_: &Impl,
render_assoc_items
(
w
,
cx
,
container_item
,
did
,
what
)
}
else
{
if
let
Some
(
prim
)
=
target
.primitive_type
()
{
if
let
Some
(
c
)
=
cache
()
.primitive_locations
.get
(
&
prim
)
{
let
did
=
DefId
{
krate
:
*
c
,
index
:
prim
.to_def_index
()
};
if
let
Some
(
&
did
)
=
cache
()
.primitive_locations
.get
(
&
prim
)
{
render_assoc_items
(
w
,
cx
,
container_item
,
did
,
what
)
?
;
}
}
...
...
@@ -2796,12 +2771,11 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
write!
(
w
,
"<h3 class='impl'><span class='in-band'><code>{}</code>"
,
i
.inner_impl
())
?
;
write!
(
w
,
"</span><span class='out-of-band'>"
)
?
;
let
since
=
i
.impl_item.stability
.as_ref
()
.map
(|
s
|
&
s
.since
[
..
]);
if
let
Some
(
l
)
=
(
Item
{
item
:
&
i
.impl_item
,
cx
:
cx
})
.href
()
{
if
let
Some
(
l
)
=
(
Item
{
item
:
&
i
.impl_item
,
cx
:
cx
})
.
src_
href
()
{
write!
(
w
,
"<div class='ghost'></div>"
)
?
;
render_stability_since_raw
(
w
,
since
,
outer_version
)
?
;
write!
(
w
,
"<a id='src-{}' class='srclink'
\
href='{}' title='{}'>[src]</a>"
,
i
.impl_item.def_id.index
.as_usize
(),
l
,
"goto source code"
)
?
;
write!
(
w
,
"<a class='srclink' href='{}' title='{}'>[src]</a>"
,
l
,
"goto source code"
)
?
;
}
else
{
render_stability_since_raw
(
w
,
since
,
outer_version
)
?
;
}
...
...
src/librustdoc/html/static/main.js
浏览文件 @
90019189
...
...
@@ -923,15 +923,6 @@
window
.
register_implementors
(
window
.
pending_implementors
);
}
// See documentation in html/render.rs for what this is doing.
var
query
=
getQueryStringParams
();
if
(
query
[
'
gotosrc
'
])
{
window
.
location
=
$
(
'
#src-
'
+
query
[
'
gotosrc
'
]).
attr
(
'
href
'
);
}
if
(
query
[
'
gotomacrosrc
'
])
{
window
.
location
=
$
(
'
.srclink
'
).
attr
(
'
href
'
);
}
function
labelForToggleButton
(
sectionIsCollapsed
)
{
if
(
sectionIsCollapsed
)
{
// button will expand the section
...
...
src/test/rustdoc/issue-34274.rs
浏览文件 @
90019189
...
...
@@ -16,5 +16,5 @@
extern
crate
issue_34274
;
// @has foo/fn.extern_c_fn.html '//a/@href' '../
issue_34274/fn.extern_c_fn.html?gotosrc=
'
// @has foo/fn.extern_c_fn.html '//a/@href' '../
src/issue_34274/issue-34274.rs.html#12
'
pub
use
issue_34274
::
extern_c_fn
;
src/test/rustdoc/src-links-external.rs
浏览文件 @
90019189
...
...
@@ -11,12 +11,13 @@
// aux-build:src-links-external.rs
// build-aux-docs
// ignore-cross-compile
// ignore-tidy-linelength
#![crate_name
=
"foo"
]
extern
crate
src_links_external
;
// @has foo/bar/index.html '//a/@href' '../
src_links_external/index.html?gotosrc=
'
// @has foo/bar/index.html '//a/@href' '../
../src/src_links_external/src-links-external.rs.html#11
'
pub
use
src_links_external
as
bar
;
// @has foo/bar/struct.Foo.html '//a/@href' '../
src_links_external/struct.Foo.html?gotosrc=
'
// @has foo/bar/struct.Foo.html '//a/@href' '../
../src/src_links_external/src-links-external.rs.html#11
'
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录