@@ -141,6 +141,10 @@ pub struct Cache {
141
141
/// necessary.
142
142
pub paths : HashMap < ast:: DefId , ( Vec < String > , ItemType ) > ,
143
143
144
+ /// Similar to `paths`, but only holds external paths. This is only used for
145
+ /// generating explicit hyperlinks to other crates.
146
+ pub external_paths : HashMap < ast:: DefId , Vec < StrBuf > > ,
147
+
144
148
/// This map contains information about all known traits of this crate.
145
149
/// Implementations of a crate should inherit the documentation of the
146
150
/// parent trait if no extra documentation is specified, and default methods
@@ -249,7 +253,8 @@ pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> {
249
253
let analysis = :: analysiskey. get ( ) ;
250
254
let public_items = analysis. as_ref ( ) . map ( |a| a. public_items . clone ( ) ) ;
251
255
let public_items = public_items. unwrap_or ( NodeSet :: new ( ) ) ;
252
- let paths = analysis. as_ref ( ) . map ( |a| {
256
+ let paths: HashMap < ast:: DefId , ( Vec < StrBuf > , ItemType ) > =
257
+ analysis. as_ref ( ) . map ( |a| {
253
258
let paths = a. external_paths . borrow_mut ( ) . take_unwrap ( ) ;
254
259
paths. move_iter ( ) . map ( |( k, ( v, t) ) | {
255
260
( k, ( v, match t {
@@ -265,6 +270,8 @@ pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> {
265
270
} ) . unwrap_or ( HashMap :: new ( ) ) ;
266
271
let mut cache = Cache {
267
272
impls : HashMap :: new ( ) ,
273
+ external_paths : paths. iter ( ) . map ( |( & k, & ( ref v, _) ) | ( k, v. clone ( ) ) )
274
+ . collect ( ) ,
268
275
paths : paths,
269
276
implementors : HashMap :: new ( ) ,
270
277
stack : Vec :: new ( ) ,
@@ -496,13 +503,15 @@ pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> {
496
503
seen : HashSet :: new ( ) ,
497
504
cx : & mut cx,
498
505
} ;
506
+ // skip all invalid spans
507
+ folder. seen . insert ( "" . to_strbuf ( ) ) ;
499
508
krate = folder. fold_crate ( krate) ;
500
509
}
501
510
502
511
for & ( n, ref e) in krate. externs . iter ( ) {
503
512
cache. extern_locations . insert ( n, extern_location ( e, & cx. dst ) ) ;
504
513
let did = ast:: DefId { krate : n, node : ast:: CRATE_NODE_ID } ;
505
- cache. paths . insert ( did, ( Vec :: new ( ) , item_type:: Module ) ) ;
514
+ cache. paths . insert ( did, ( vec ! [ e . name . to_strbuf ( ) ] , item_type:: Module ) ) ;
506
515
}
507
516
508
517
// And finally render the whole crate's documentation
@@ -1032,23 +1041,38 @@ impl<'a> Item<'a> {
1032
1041
}
1033
1042
}
1034
1043
1035
- fn link ( & self ) -> String {
1036
- let mut path = Vec :: new ( ) ;
1037
- clean_srcpath ( self . item . source . filename . as_bytes ( ) , |component| {
1038
- path. push ( component. to_owned ( ) ) ;
1039
- } ) ;
1040
- let href = if self . item . source . loline == self . item . source . hiline {
1041
- format_strbuf ! ( "{}" , self . item. source. loline)
1044
+ fn link ( & self ) -> Option < String > {
1045
+ if ast_util:: is_local ( self . item . def_id ) {
1046
+ let mut path = Vec :: new ( ) ;
1047
+ clean_srcpath ( self . item . source . filename . as_bytes ( ) , |component| {
1048
+ path. push ( component. to_owned ( ) ) ;
1049
+ } ) ;
1050
+ let href = if self . item . source . loline == self . item . source . hiline {
1051
+ format ! ( "{}" , self . item. source. loline)
1052
+ } else {
1053
+ format ! ( "{}-{}" ,
1054
+ self . item. source. loline,
1055
+ self . item. source. hiline)
1056
+ } ;
1057
+ Some ( format ! ( "{root}src/{krate}/{path}.html\\ #{href}" ,
1058
+ root = self . cx. root_path,
1059
+ krate = self . cx. layout. krate,
1060
+ path = path. connect( "/" ) ,
1061
+ href = href) )
1042
1062
} else {
1043
- format_strbuf ! ( "{}-{}" ,
1044
- self . item. source. loline,
1045
- self . item. source. hiline)
1046
- } ;
1047
- format_strbuf ! ( "{root}src/{krate}/{path}.html\\ #{href}" ,
1048
- root = self . cx. root_path,
1049
- krate = self . cx. layout. krate,
1050
- path = path. connect( "/" ) ,
1051
- href = href)
1063
+ let cache = cache_key. get ( ) . unwrap ( ) ;
1064
+ let path = cache. external_paths . get ( & self . item . def_id ) ;
1065
+ let root = match * cache. extern_locations . get ( & self . item . def_id . krate ) {
1066
+ Remote ( ref s) => s. to_strbuf ( ) ,
1067
+ Local => format ! ( "{}/.." , self . cx. root_path) ,
1068
+ Unknown => return None ,
1069
+ } ;
1070
+ Some ( format ! ( "{root}/{path}/{file}?gotosrc={goto}" ,
1071
+ root = root,
1072
+ path = path. slice_to( path. len( ) - 1 ) . connect( "/" ) ,
1073
+ file = item_path( self . item) ,
1074
+ goto = self . item. def_id. node) )
1075
+ }
1052
1076
}
1053
1077
}
1054
1078
@@ -1097,8 +1121,15 @@ impl<'a> fmt::Show for Item<'a> {
1097
1121
1098
1122
// Write `src` tag
1099
1123
if self . cx . include_sources {
1100
- try!( write ! ( fmt, "<a class='source' href='{}'>[src]</a>" ,
1101
- self . link( ) ) ) ;
1124
+ match self . link ( ) {
1125
+ Some ( l) => {
1126
+ try!( write ! ( fmt,
1127
+ "<a class='source' id='src-{}' \
1128
+ href='{}'>[src]</a>",
1129
+ self . item. def_id. node, l) ) ;
1130
+ }
1131
+ None => { }
1132
+ }
1102
1133
}
1103
1134
try!( write ! ( fmt, "</h1>\n " ) ) ;
1104
1135
0 commit comments