]>
Commit | Line | Data |
---|---|---|
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. | |
10 | pub use self::MaybeTyped::*; | |
11 | ||
c34b1796 | 12 | use rustc_lint; |
1a4d82fc JJ |
13 | use rustc_driver::driver; |
14 | use rustc::session::{self, config}; | |
15 | use rustc::session::config::UnstableFeatures; | |
1a4d82fc JJ |
16 | use rustc::middle::{privacy, ty}; |
17 | use rustc::lint; | |
18 | use rustc_trans::back::link; | |
85aaf69f | 19 | use rustc_resolve as resolve; |
1a4d82fc JJ |
20 | |
21 | use syntax::{ast, ast_map, codemap, diagnostic}; | |
22 | ||
23 | use std::cell::RefCell; | |
24 | use std::collections::{HashMap, HashSet}; | |
25 | ||
26 | use visit_ast::RustdocVisitor; | |
27 | use clean; | |
28 | use clean::Clean; | |
29 | ||
85aaf69f SL |
30 | pub use rustc::session::config::Input; |
31 | pub use rustc::session::search_paths::SearchPaths; | |
32 | ||
1a4d82fc JJ |
33 | /// Are we generating documentation (`Typed`) or tests (`NotTyped`)? |
34 | pub enum MaybeTyped<'tcx> { | |
35 | Typed(ty::ctxt<'tcx>), | |
36 | NotTyped(session::Session) | |
37 | } | |
38 | ||
39 | pub type ExternalPaths = RefCell<Option<HashMap<ast::DefId, | |
40 | (Vec<String>, clean::TypeKind)>>>; | |
41 | ||
42 | pub struct DocContext<'tcx> { | |
43 | pub krate: &'tcx ast::Crate, | |
44 | pub maybe_typed: MaybeTyped<'tcx>, | |
85aaf69f | 45 | pub input: Input, |
1a4d82fc JJ |
46 | pub external_paths: ExternalPaths, |
47 | pub external_traits: RefCell<Option<HashMap<ast::DefId, clean::Trait>>>, | |
48 | pub external_typarams: RefCell<Option<HashMap<ast::DefId, String>>>, | |
49 | pub inlined: RefCell<Option<HashSet<ast::DefId>>>, | |
50 | pub populated_crate_impls: RefCell<HashSet<ast::CrateNum>>, | |
51 | } | |
52 | ||
53 | impl<'tcx> DocContext<'tcx> { | |
54 | pub fn sess<'a>(&'a self) -> &'a session::Session { | |
55 | match self.maybe_typed { | |
56 | Typed(ref tcx) => &tcx.sess, | |
57 | NotTyped(ref sess) => sess | |
58 | } | |
59 | } | |
60 | ||
61 | pub fn tcx_opt<'a>(&'a self) -> Option<&'a ty::ctxt<'tcx>> { | |
62 | match self.maybe_typed { | |
63 | Typed(ref tcx) => Some(tcx), | |
64 | NotTyped(_) => None | |
65 | } | |
66 | } | |
67 | ||
68 | pub fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx> { | |
69 | let tcx_opt = self.tcx_opt(); | |
70 | tcx_opt.expect("tcx not present") | |
71 | } | |
72 | } | |
73 | ||
74 | pub struct CrateAnalysis { | |
75 | pub exported_items: privacy::ExportedItems, | |
76 | pub public_items: privacy::PublicItems, | |
77 | pub external_paths: ExternalPaths, | |
1a4d82fc JJ |
78 | pub external_typarams: RefCell<Option<HashMap<ast::DefId, String>>>, |
79 | pub inlined: RefCell<Option<HashSet<ast::DefId>>>, | |
80 | } | |
81 | ||
82 | pub type Externs = HashMap<String, Vec<String>>; | |
83 | ||
84 | pub fn run_core(search_paths: SearchPaths, cfgs: Vec<String>, externs: Externs, | |
85aaf69f | 85 | input: Input, triple: Option<String>) |
1a4d82fc JJ |
86 | -> (clean::Crate, CrateAnalysis) { |
87 | ||
88 | // Parse, resolve, and typecheck the given crate. | |
89 | ||
85aaf69f SL |
90 | let cpath = match input { |
91 | Input::File(ref p) => Some(p.clone()), | |
92 | _ => None | |
93 | }; | |
1a4d82fc JJ |
94 | |
95 | let warning_lint = lint::builtin::WARNINGS.name_lower(); | |
96 | ||
97 | let sessopts = config::Options { | |
98 | maybe_sysroot: None, | |
99 | search_paths: search_paths, | |
100 | crate_types: vec!(config::CrateTypeRlib), | |
101 | lint_opts: vec!((warning_lint, lint::Allow)), | |
102 | externs: externs, | |
103 | target_triple: triple.unwrap_or(config::host_triple().to_string()), | |
104 | cfg: config::parse_cfgspecs(cfgs), | |
105 | // Ensure that rustdoc works even if rustc is feature-staged | |
106 | unstable_features: UnstableFeatures::Default, | |
107 | ..config::basic_options().clone() | |
108 | }; | |
109 | ||
110 | let codemap = codemap::CodeMap::new(); | |
85aaf69f | 111 | let diagnostic_handler = diagnostic::default_handler(diagnostic::Auto, None, true); |
1a4d82fc JJ |
112 | let span_diagnostic_handler = |
113 | diagnostic::mk_span_handler(diagnostic_handler, codemap); | |
114 | ||
85aaf69f | 115 | let sess = session::build_session_(sessopts, cpath, |
1a4d82fc | 116 | span_diagnostic_handler); |
c34b1796 | 117 | rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess)); |
1a4d82fc JJ |
118 | |
119 | let cfg = config::build_configuration(&sess); | |
120 | ||
121 | let krate = driver::phase_1_parse_input(&sess, cfg, &input); | |
122 | ||
85aaf69f | 123 | let name = link::find_crate_name(Some(&sess), &krate.attrs, |
1a4d82fc JJ |
124 | &input); |
125 | ||
85aaf69f | 126 | let krate = driver::phase_2_configure_and_expand(&sess, krate, &name, None) |
1a4d82fc JJ |
127 | .expect("phase_2_configure_and_expand aborted in rustdoc!"); |
128 | ||
129 | let mut forest = ast_map::Forest::new(krate); | |
85aaf69f | 130 | let arenas = ty::CtxtArenas::new(); |
1a4d82fc JJ |
131 | let ast_map = driver::assign_node_ids_and_map(&sess, &mut forest); |
132 | ||
1a4d82fc JJ |
133 | let ty::CrateAnalysis { |
134 | exported_items, public_items, ty_cx, .. | |
85aaf69f SL |
135 | } = driver::phase_3_run_analysis_passes(sess, |
136 | ast_map, | |
137 | &arenas, | |
138 | name, | |
139 | resolve::MakeGlobMap::No); | |
1a4d82fc JJ |
140 | |
141 | let ctxt = DocContext { | |
142 | krate: ty_cx.map.krate(), | |
143 | maybe_typed: Typed(ty_cx), | |
85aaf69f | 144 | input: input, |
1a4d82fc JJ |
145 | external_traits: RefCell::new(Some(HashMap::new())), |
146 | external_typarams: RefCell::new(Some(HashMap::new())), | |
147 | external_paths: RefCell::new(Some(HashMap::new())), | |
148 | inlined: RefCell::new(Some(HashSet::new())), | |
149 | populated_crate_impls: RefCell::new(HashSet::new()), | |
150 | }; | |
151 | debug!("crate: {:?}", ctxt.krate); | |
152 | ||
153 | let analysis = CrateAnalysis { | |
154 | exported_items: exported_items, | |
155 | public_items: public_items, | |
156 | external_paths: RefCell::new(None), | |
1a4d82fc JJ |
157 | external_typarams: RefCell::new(None), |
158 | inlined: RefCell::new(None), | |
159 | }; | |
160 | ||
161 | let krate = { | |
162 | let mut v = RustdocVisitor::new(&ctxt, Some(&analysis)); | |
163 | v.visit(ctxt.krate); | |
164 | v.clean(&ctxt) | |
165 | }; | |
166 | ||
167 | let external_paths = ctxt.external_paths.borrow_mut().take(); | |
168 | *analysis.external_paths.borrow_mut() = external_paths; | |
1a4d82fc JJ |
169 | let map = ctxt.external_typarams.borrow_mut().take(); |
170 | *analysis.external_typarams.borrow_mut() = map; | |
171 | let map = ctxt.inlined.borrow_mut().take(); | |
172 | *analysis.inlined.borrow_mut() = map; | |
173 | (krate, analysis) | |
174 | } |