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.
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
::*;
13 use rustc_driver
::driver
;
14 use rustc
::session
::{self, config}
;
15 use rustc
::session
::config
::UnstableFeatures
;
16 use rustc
::middle
::{privacy, ty}
;
18 use rustc_trans
::back
::link
;
19 use rustc_resolve
as resolve
;
21 use syntax
::{ast, ast_map, codemap, diagnostic}
;
23 use std
::cell
::{RefCell, Cell}
;
24 use std
::collections
::{HashMap, HashSet}
;
26 use visit_ast
::RustdocVisitor
;
30 pub use rustc
::session
::config
::Input
;
31 pub use rustc
::session
::search_paths
::SearchPaths
;
33 /// Are we generating documentation (`Typed`) or tests (`NotTyped`)?
34 pub enum MaybeTyped
<'tcx
> {
35 Typed(ty
::ctxt
<'tcx
>),
36 NotTyped(session
::Session
)
39 pub type ExternalPaths
= RefCell
<Option
<HashMap
<ast
::DefId
,
40 (Vec
<String
>, clean
::TypeKind
)>>>;
42 pub struct DocContext
<'tcx
> {
43 pub krate
: &'tcx ast
::Crate
,
44 pub maybe_typed
: MaybeTyped
<'tcx
>,
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 pub deref_trait_did
: Cell
<Option
<ast
::DefId
>>,
54 impl<'tcx
> DocContext
<'tcx
> {
55 pub fn sess
<'a
>(&'a
self) -> &'a session
::Session
{
56 match self.maybe_typed
{
57 Typed(ref tcx
) => &tcx
.sess
,
58 NotTyped(ref sess
) => sess
62 pub fn tcx_opt
<'a
>(&'a
self) -> Option
<&'a ty
::ctxt
<'tcx
>> {
63 match self.maybe_typed
{
64 Typed(ref tcx
) => Some(tcx
),
69 pub fn tcx
<'a
>(&'a
self) -> &'a ty
::ctxt
<'tcx
> {
70 let tcx_opt
= self.tcx_opt();
71 tcx_opt
.expect("tcx not present")
75 pub struct CrateAnalysis
{
76 pub exported_items
: privacy
::ExportedItems
,
77 pub public_items
: privacy
::PublicItems
,
78 pub external_paths
: ExternalPaths
,
79 pub external_typarams
: RefCell
<Option
<HashMap
<ast
::DefId
, String
>>>,
80 pub inlined
: RefCell
<Option
<HashSet
<ast
::DefId
>>>,
81 pub deref_trait_did
: Option
<ast
::DefId
>,
84 pub type Externs
= HashMap
<String
, Vec
<String
>>;
86 pub fn run_core(search_paths
: SearchPaths
, cfgs
: Vec
<String
>, externs
: Externs
,
87 input
: Input
, triple
: Option
<String
>)
88 -> (clean
::Crate
, CrateAnalysis
) {
90 // Parse, resolve, and typecheck the given crate.
92 let cpath
= match input
{
93 Input
::File(ref p
) => Some(p
.clone()),
97 let warning_lint
= lint
::builtin
::WARNINGS
.name_lower();
99 let sessopts
= config
::Options
{
101 search_paths
: search_paths
,
102 crate_types
: vec
!(config
::CrateTypeRlib
),
103 lint_opts
: vec
!((warning_lint
, lint
::Allow
)),
105 target_triple
: triple
.unwrap_or(config
::host_triple().to_string()),
106 cfg
: config
::parse_cfgspecs(cfgs
),
107 // Ensure that rustdoc works even if rustc is feature-staged
108 unstable_features
: UnstableFeatures
::Default
,
109 ..config
::basic_options().clone()
112 let codemap
= codemap
::CodeMap
::new();
113 let diagnostic_handler
= diagnostic
::default_handler(diagnostic
::Auto
, None
, true);
114 let span_diagnostic_handler
=
115 diagnostic
::mk_span_handler(diagnostic_handler
, codemap
);
117 let sess
= session
::build_session_(sessopts
, cpath
,
118 span_diagnostic_handler
);
119 rustc_lint
::register_builtins(&mut sess
.lint_store
.borrow_mut(), Some(&sess
));
121 let cfg
= config
::build_configuration(&sess
);
123 let krate
= driver
::phase_1_parse_input(&sess
, cfg
, &input
);
125 let name
= link
::find_crate_name(Some(&sess
), &krate
.attrs
,
128 let krate
= driver
::phase_2_configure_and_expand(&sess
, krate
, &name
, None
)
129 .expect("phase_2_configure_and_expand aborted in rustdoc!");
131 let mut forest
= ast_map
::Forest
::new(krate
);
132 let arenas
= ty
::CtxtArenas
::new();
133 let ast_map
= driver
::assign_node_ids_and_map(&sess
, &mut forest
);
135 let ty
::CrateAnalysis
{
136 exported_items
, public_items
, ty_cx
, ..
137 } = driver
::phase_3_run_analysis_passes(sess
,
141 resolve
::MakeGlobMap
::No
);
143 let ctxt
= DocContext
{
144 krate
: ty_cx
.map
.krate(),
145 maybe_typed
: Typed(ty_cx
),
147 external_traits
: RefCell
::new(Some(HashMap
::new())),
148 external_typarams
: RefCell
::new(Some(HashMap
::new())),
149 external_paths
: RefCell
::new(Some(HashMap
::new())),
150 inlined
: RefCell
::new(Some(HashSet
::new())),
151 populated_crate_impls
: RefCell
::new(HashSet
::new()),
152 deref_trait_did
: Cell
::new(None
),
154 debug
!("crate: {:?}", ctxt
.krate
);
156 let mut analysis
= CrateAnalysis
{
157 exported_items
: exported_items
,
158 public_items
: public_items
,
159 external_paths
: RefCell
::new(None
),
160 external_typarams
: RefCell
::new(None
),
161 inlined
: RefCell
::new(None
),
162 deref_trait_did
: None
,
166 let mut v
= RustdocVisitor
::new(&ctxt
, Some(&analysis
));
171 let external_paths
= ctxt
.external_paths
.borrow_mut().take();
172 *analysis
.external_paths
.borrow_mut() = external_paths
;
173 let map
= ctxt
.external_typarams
.borrow_mut().take();
174 *analysis
.external_typarams
.borrow_mut() = map
;
175 let map
= ctxt
.inlined
.borrow_mut().take();
176 *analysis
.inlined
.borrow_mut() = map
;
177 analysis
.deref_trait_did
= ctxt
.deref_trait_did
.get();