]> git.proxmox.com Git - rustc.git/blame - src/librustdoc/core.rs
New upstream version 1.20.0+dfsg1
[rustc.git] / src / librustdoc / core.rs
CommitLineData
1a4d82fc
JJ
1// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
1a4d82fc 10
c34b1796 11use rustc_lint;
7453a54e
SL
12use rustc_driver::{driver, target_features, abort_on_err};
13use rustc::dep_graph::DepGraph;
1a4d82fc 14use rustc::session::{self, config};
54a0048b 15use rustc::hir::def_id::DefId;
cc61c64b 16use rustc::hir::def::Def;
92a42be0 17use rustc::middle::privacy::AccessLevels;
8bb4bdeb 18use rustc::ty::{self, TyCtxt, GlobalArenas};
54a0048b 19use rustc::hir::map as hir_map;
1a4d82fc 20use rustc::lint;
8bb4bdeb 21use rustc::util::nodemap::FxHashMap;
7cac9316 22use rustc_trans;
1a4d82fc 23use rustc_trans::back::link;
85aaf69f 24use rustc_resolve as resolve;
92a42be0 25use rustc_metadata::cstore::CStore;
1a4d82fc 26
3157f602 27use syntax::{ast, codemap};
62682a34 28use syntax::feature_gate::UnstableFeatures;
3157f602
XL
29use errors;
30use errors::emitter::ColorConfig;
1a4d82fc 31
d9579d0f 32use std::cell::{RefCell, Cell};
9e0c209e 33use std::mem;
92a42be0 34use std::rc::Rc;
9e0c209e 35use std::path::PathBuf;
1a4d82fc
JJ
36
37use visit_ast::RustdocVisitor;
38use clean;
39use clean::Clean;
a7813a04 40use html::render::RenderInfo;
32a655c1 41use arena::DroplessArena;
1a4d82fc 42
85aaf69f
SL
43pub use rustc::session::config::Input;
44pub use rustc::session::search_paths::SearchPaths;
45
476ff2be 46pub type ExternalPaths = FxHashMap<DefId, (Vec<String>, clean::TypeKind)>;
1a4d82fc 47
62682a34 48pub struct DocContext<'a, 'tcx: 'a> {
476ff2be 49 pub tcx: TyCtxt<'a, 'tcx, 'tcx>,
9e0c209e 50 pub populated_all_crate_impls: Cell<bool>,
a7813a04
XL
51 // Note that external items for which `doc(hidden)` applies to are shown as
52 // non-reachable while local items aren't. This is because we're reusing
53 // the access levels from crateanalysis.
54 /// Later on moved into `clean::Crate`
55 pub access_levels: RefCell<AccessLevels<DefId>>,
56 /// Later on moved into `html::render::CACHE_KEY`
57 pub renderinfo: RefCell<RenderInfo>,
58 /// Later on moved through `clean::Crate` into `html::render::CACHE_KEY`
476ff2be 59 pub external_traits: RefCell<FxHashMap<DefId, clean::Trait>>,
9e0c209e
SL
60
61 // The current set of type and lifetime substitutions,
62 // for expanding type aliases at the HIR level:
63
64 /// Table type parameter definition -> substituted type
476ff2be 65 pub ty_substs: RefCell<FxHashMap<Def, clean::Type>>,
9e0c209e 66 /// Table node id of lifetime parameter definition -> substituted lifetime
476ff2be 67 pub lt_substs: RefCell<FxHashMap<ast::NodeId, clean::Lifetime>>,
476ff2be 68}
1a4d82fc 69
476ff2be
SL
70impl<'a, 'tcx> DocContext<'a, 'tcx> {
71 pub fn sess(&self) -> &session::Session {
72 &self.tcx.sess
1a4d82fc 73 }
9e0c209e
SL
74
75 /// Call the closure with the given parameters set as
76 /// the substitutions for a type alias' RHS.
77 pub fn enter_alias<F, R>(&self,
476ff2be
SL
78 ty_substs: FxHashMap<Def, clean::Type>,
79 lt_substs: FxHashMap<ast::NodeId, clean::Lifetime>,
9e0c209e
SL
80 f: F) -> R
81 where F: FnOnce() -> R {
82 let (old_tys, old_lts) =
83 (mem::replace(&mut *self.ty_substs.borrow_mut(), ty_substs),
84 mem::replace(&mut *self.lt_substs.borrow_mut(), lt_substs));
85 let r = f();
86 *self.ty_substs.borrow_mut() = old_tys;
87 *self.lt_substs.borrow_mut() = old_lts;
88 r
89 }
1a4d82fc
JJ
90}
91
a7813a04 92pub trait DocAccessLevels {
7cac9316 93 fn is_doc_reachable(&self, did: DefId) -> bool;
1a4d82fc
JJ
94}
95
a7813a04
XL
96impl DocAccessLevels for AccessLevels<DefId> {
97 fn is_doc_reachable(&self, did: DefId) -> bool {
98 self.is_public(did)
99 }
100}
1a4d82fc 101
1a4d82fc 102
a7813a04
XL
103pub fn run_core(search_paths: SearchPaths,
104 cfgs: Vec<String>,
5bcae85e 105 externs: config::Externs,
a7813a04 106 input: Input,
9e0c209e 107 triple: Option<String>,
7cac9316 108 maybe_sysroot: Option<PathBuf>,
041b39d2
XL
109 allow_warnings: bool,
110 force_unstable_if_unmarked: bool) -> (clean::Crate, RenderInfo)
a7813a04 111{
1a4d82fc
JJ
112 // Parse, resolve, and typecheck the given crate.
113
85aaf69f
SL
114 let cpath = match input {
115 Input::File(ref p) => Some(p.clone()),
116 _ => None
117 };
1a4d82fc
JJ
118
119 let warning_lint = lint::builtin::WARNINGS.name_lower();
120
121 let sessopts = config::Options {
9e0c209e 122 maybe_sysroot: maybe_sysroot,
1a4d82fc 123 search_paths: search_paths,
c30ab7b3 124 crate_types: vec![config::CrateTypeRlib],
7cac9316 125 lint_opts: if !allow_warnings { vec![(warning_lint, lint::Allow)] } else { vec![] },
92a42be0 126 lint_cap: Some(lint::Allow),
1a4d82fc
JJ
127 externs: externs,
128 target_triple: triple.unwrap_or(config::host_triple().to_string()),
1a4d82fc 129 // Ensure that rustdoc works even if rustc is feature-staged
62682a34 130 unstable_features: UnstableFeatures::Allow,
c30ab7b3 131 actually_rustdoc: true,
041b39d2
XL
132 debugging_opts: config::DebuggingOptions {
133 force_unstable_if_unmarked: force_unstable_if_unmarked,
134 ..config::basic_debugging_options()
135 },
1a4d82fc
JJ
136 ..config::basic_options().clone()
137 };
138
7cac9316 139 let codemap = Rc::new(codemap::CodeMap::new(sessopts.file_path_mapping()));
9cc50fc6 140 let diagnostic_handler = errors::Handler::with_tty_emitter(ColorConfig::Auto,
9cc50fc6
SL
141 true,
142 false,
5bcae85e 143 Some(codemap.clone()));
1a4d82fc 144
a7813a04
XL
145 let dep_graph = DepGraph::new(false);
146 let _ignore = dep_graph.in_ignore();
7cac9316 147 let cstore = Rc::new(CStore::new(&dep_graph, box rustc_trans::LlvmMetadataLoader));
c30ab7b3
SL
148 let mut sess = session::build_session_(
149 sessopts, &dep_graph, cpath, diagnostic_handler, codemap, cstore.clone()
150 );
7cac9316 151 rustc_trans::init(&sess);
c34b1796 152 rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
1a4d82fc 153
5bcae85e 154 let mut cfg = config::build_configuration(&sess, config::parse_cfgspecs(cfgs));
e9174d1e 155 target_features::add_configuration(&mut cfg, &sess);
c30ab7b3 156 sess.parse_sess.config = cfg;
1a4d82fc 157
c30ab7b3 158 let krate = panictry!(driver::phase_1_parse_input(&sess, &input));
1a4d82fc 159
3157f602 160 let name = link::find_crate_name(Some(&sess), &krate.attrs, &input);
1a4d82fc 161
3157f602 162 let driver::ExpansionResult { defs, analysis, resolutions, mut hir_forest, .. } = {
32a655c1
SL
163 let result = driver::phase_2_configure_and_expand(&sess,
164 &cstore,
165 krate,
166 None,
167 &name,
168 None,
169 resolve::MakeGlobMap::No,
170 |_| Ok(()));
171 abort_on_err(result, &sess)
a7813a04
XL
172 };
173
32a655c1
SL
174 let arena = DroplessArena::new();
175 let arenas = GlobalArenas::new();
a7813a04 176 let hir_map = hir_map::map_crate(&mut hir_forest, defs);
1a4d82fc 177
a7813a04 178 abort_on_err(driver::phase_3_run_analysis_passes(&sess,
7453a54e 179 hir_map,
a7813a04
XL
180 analysis,
181 resolutions,
32a655c1 182 &arena,
7453a54e
SL
183 &arenas,
184 &name,
c30ab7b3 185 |tcx, analysis, _, result| {
7453a54e 186 if let Err(_) = result {
a7813a04 187 sess.fatal("Compilation failed, aborting rustdoc");
7453a54e
SL
188 }
189
cc61c64b 190 let ty::CrateAnalysis { access_levels, .. } = analysis;
62682a34 191
b039eaaf
SL
192 // Convert from a NodeId set to a DefId set since we don't always have easy access
193 // to the map from defid -> nodeid
92a42be0 194 let access_levels = AccessLevels {
cc61c64b
XL
195 map: access_levels.map.iter()
196 .map(|(&k, &v)| (tcx.hir.local_def_id(k), v))
92a42be0
SL
197 .collect()
198 };
b039eaaf 199
62682a34 200 let ctxt = DocContext {
476ff2be 201 tcx: tcx,
9e0c209e 202 populated_all_crate_impls: Cell::new(false),
a7813a04 203 access_levels: RefCell::new(access_levels),
9e0c209e
SL
204 external_traits: Default::default(),
205 renderinfo: Default::default(),
206 ty_substs: Default::default(),
207 lt_substs: Default::default(),
62682a34 208 };
32a655c1 209 debug!("crate: {:?}", tcx.hir.krate());
62682a34 210
62682a34 211 let krate = {
a7813a04 212 let mut v = RustdocVisitor::new(&ctxt);
32a655c1 213 v.visit(tcx.hir.krate());
62682a34
SL
214 v.clean(&ctxt)
215 };
216
a7813a04
XL
217 (krate, ctxt.renderinfo.into_inner())
218 }), &sess)
1a4d82fc 219}