]> git.lizzy.rs Git - rust.git/blob - src/librustc/driver/session.rs
Store the registered lints in the Session
[rust.git] / src / librustc / driver / session.rs
1 // Copyright 2012-2013 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
11
12 use driver::config;
13 use driver::driver;
14 use front;
15 use metadata::cstore::CStore;
16 use metadata::filesearch;
17 use lint;
18 use util::nodemap::NodeMap;
19
20 use syntax::ast::NodeId;
21 use syntax::codemap::Span;
22 use syntax::diagnostic;
23 use syntax::parse;
24 use syntax::parse::token;
25 use syntax::parse::ParseSess;
26 use syntax::{ast, codemap};
27
28 use std::os;
29 use std::cell::{Cell, RefCell};
30
31
32 pub struct Session {
33     pub targ_cfg: config::Config,
34     pub opts: config::Options,
35     pub cstore: CStore,
36     pub parse_sess: ParseSess,
37     // For a library crate, this is always none
38     pub entry_fn: RefCell<Option<(NodeId, codemap::Span)>>,
39     pub entry_type: Cell<Option<config::EntryFnType>>,
40     pub plugin_registrar_fn: Cell<Option<ast::NodeId>>,
41     pub default_sysroot: Option<Path>,
42     // The name of the root source file of the crate, in the local file system. The path is always
43     // expected to be absolute. `None` means that there is no source file.
44     pub local_crate_source_file: Option<Path>,
45     pub working_dir: Path,
46     pub lint_store: RefCell<lint::LintStore>,
47     pub lints: RefCell<NodeMap<Vec<(lint::LintId, codemap::Span, String)>>>,
48     pub node_id: Cell<ast::NodeId>,
49     pub crate_types: RefCell<Vec<config::CrateType>>,
50     pub features: front::feature_gate::Features,
51
52     /// The maximum recursion limit for potentially infinitely recursive
53     /// operations such as auto-dereference and monomorphization.
54     pub recursion_limit: Cell<uint>,
55 }
56
57 impl Session {
58     pub fn span_fatal(&self, sp: Span, msg: &str) -> ! {
59         self.diagnostic().span_fatal(sp, msg)
60     }
61     pub fn fatal(&self, msg: &str) -> ! {
62         self.diagnostic().handler().fatal(msg)
63     }
64     pub fn span_err(&self, sp: Span, msg: &str) {
65         self.diagnostic().span_err(sp, msg)
66     }
67     pub fn err(&self, msg: &str) {
68         self.diagnostic().handler().err(msg)
69     }
70     pub fn err_count(&self) -> uint {
71         self.diagnostic().handler().err_count()
72     }
73     pub fn has_errors(&self) -> bool {
74         self.diagnostic().handler().has_errors()
75     }
76     pub fn abort_if_errors(&self) {
77         self.diagnostic().handler().abort_if_errors()
78     }
79     pub fn span_warn(&self, sp: Span, msg: &str) {
80         self.diagnostic().span_warn(sp, msg)
81     }
82     pub fn warn(&self, msg: &str) {
83         self.diagnostic().handler().warn(msg)
84     }
85     pub fn span_note(&self, sp: Span, msg: &str) {
86         self.diagnostic().span_note(sp, msg)
87     }
88     pub fn span_end_note(&self, sp: Span, msg: &str) {
89         self.diagnostic().span_end_note(sp, msg)
90     }
91     pub fn fileline_note(&self, sp: Span, msg: &str) {
92         self.diagnostic().fileline_note(sp, msg)
93     }
94     pub fn note(&self, msg: &str) {
95         self.diagnostic().handler().note(msg)
96     }
97     pub fn span_bug(&self, sp: Span, msg: &str) -> ! {
98         self.diagnostic().span_bug(sp, msg)
99     }
100     pub fn bug(&self, msg: &str) -> ! {
101         self.diagnostic().handler().bug(msg)
102     }
103     pub fn span_unimpl(&self, sp: Span, msg: &str) -> ! {
104         self.diagnostic().span_unimpl(sp, msg)
105     }
106     pub fn unimpl(&self, msg: &str) -> ! {
107         self.diagnostic().handler().unimpl(msg)
108     }
109     pub fn add_lint(&self,
110                     lint: &'static lint::Lint,
111                     id: ast::NodeId,
112                     sp: Span,
113                     msg: String) {
114         let lint_id = lint::LintId::of(lint);
115         let mut lints = self.lints.borrow_mut();
116         match lints.find_mut(&id) {
117             Some(arr) => { arr.push((lint_id, sp, msg)); return; }
118             None => {}
119         }
120         lints.insert(id, vec!((lint_id, sp, msg)));
121     }
122     pub fn next_node_id(&self) -> ast::NodeId {
123         self.reserve_node_ids(1)
124     }
125     pub fn reserve_node_ids(&self, count: ast::NodeId) -> ast::NodeId {
126         let v = self.node_id.get();
127
128         match v.checked_add(&count) {
129             Some(next) => { self.node_id.set(next); }
130             None => self.bug("Input too large, ran out of node ids!")
131         }
132
133         v
134     }
135     pub fn diagnostic<'a>(&'a self) -> &'a diagnostic::SpanHandler {
136         &self.parse_sess.span_diagnostic
137     }
138     pub fn debugging_opt(&self, opt: u64) -> bool {
139         (self.opts.debugging_opts & opt) != 0
140     }
141     pub fn codemap<'a>(&'a self) -> &'a codemap::CodeMap {
142         &self.parse_sess.span_diagnostic.cm
143     }
144     // This exists to help with refactoring to eliminate impossible
145     // cases later on
146     pub fn impossible_case(&self, sp: Span, msg: &str) -> ! {
147         self.span_bug(sp,
148                       format!("impossible case reached: {}", msg).as_slice());
149     }
150     pub fn verbose(&self) -> bool { self.debugging_opt(config::VERBOSE) }
151     pub fn time_passes(&self) -> bool { self.debugging_opt(config::TIME_PASSES) }
152     pub fn count_llvm_insns(&self) -> bool {
153         self.debugging_opt(config::COUNT_LLVM_INSNS)
154     }
155     pub fn count_type_sizes(&self) -> bool {
156         self.debugging_opt(config::COUNT_TYPE_SIZES)
157     }
158     pub fn time_llvm_passes(&self) -> bool {
159         self.debugging_opt(config::TIME_LLVM_PASSES)
160     }
161     pub fn trans_stats(&self) -> bool { self.debugging_opt(config::TRANS_STATS) }
162     pub fn meta_stats(&self) -> bool { self.debugging_opt(config::META_STATS) }
163     pub fn asm_comments(&self) -> bool { self.debugging_opt(config::ASM_COMMENTS) }
164     pub fn no_verify(&self) -> bool { self.debugging_opt(config::NO_VERIFY) }
165     pub fn borrowck_stats(&self) -> bool { self.debugging_opt(config::BORROWCK_STATS) }
166     pub fn print_llvm_passes(&self) -> bool {
167         self.debugging_opt(config::PRINT_LLVM_PASSES)
168     }
169     pub fn lto(&self) -> bool {
170         self.debugging_opt(config::LTO)
171     }
172     pub fn no_landing_pads(&self) -> bool {
173         self.debugging_opt(config::NO_LANDING_PADS)
174     }
175     pub fn show_span(&self) -> bool {
176         self.debugging_opt(config::SHOW_SPAN)
177     }
178     pub fn sysroot<'a>(&'a self) -> &'a Path {
179         match self.opts.maybe_sysroot {
180             Some (ref sysroot) => sysroot,
181             None => self.default_sysroot.as_ref()
182                         .expect("missing sysroot and default_sysroot in Session")
183         }
184     }
185     pub fn target_filesearch<'a>(&'a self) -> filesearch::FileSearch<'a> {
186         filesearch::FileSearch::new(self.sysroot(),
187                                     self.opts.target_triple.as_slice(),
188                                     &self.opts.addl_lib_search_paths)
189     }
190     pub fn host_filesearch<'a>(&'a self) -> filesearch::FileSearch<'a> {
191         filesearch::FileSearch::new(
192             self.sysroot(),
193             driver::host_triple(),
194             &self.opts.addl_lib_search_paths)
195     }
196 }
197
198 pub fn build_session(sopts: config::Options,
199                      local_crate_source_file: Option<Path>)
200                      -> Session {
201     let codemap = codemap::CodeMap::new();
202     let diagnostic_handler =
203         diagnostic::default_handler(sopts.color);
204     let span_diagnostic_handler =
205         diagnostic::mk_span_handler(diagnostic_handler, codemap);
206
207     build_session_(sopts, local_crate_source_file, span_diagnostic_handler)
208 }
209
210 pub fn build_session_(sopts: config::Options,
211                       local_crate_source_file: Option<Path>,
212                       span_diagnostic: diagnostic::SpanHandler)
213                       -> Session {
214     let target_cfg = config::build_target_config(&sopts);
215     let p_s = parse::new_parse_sess_special_handler(span_diagnostic);
216     let default_sysroot = match sopts.maybe_sysroot {
217         Some(_) => None,
218         None => Some(filesearch::get_or_default_sysroot())
219     };
220
221     // Make the path absolute, if necessary
222     let local_crate_source_file = local_crate_source_file.map(|path|
223         if path.is_absolute() {
224             path.clone()
225         } else {
226             os::getcwd().join(path.clone())
227         }
228     );
229
230     let sess = Session {
231         targ_cfg: target_cfg,
232         opts: sopts,
233         cstore: CStore::new(token::get_ident_interner()),
234         parse_sess: p_s,
235         // For a library crate, this is always none
236         entry_fn: RefCell::new(None),
237         entry_type: Cell::new(None),
238         plugin_registrar_fn: Cell::new(None),
239         default_sysroot: default_sysroot,
240         local_crate_source_file: local_crate_source_file,
241         working_dir: os::getcwd(),
242         lint_store: RefCell::new(lint::LintStore::new()),
243         lints: RefCell::new(NodeMap::new()),
244         node_id: Cell::new(1),
245         crate_types: RefCell::new(Vec::new()),
246         features: front::feature_gate::Features::new(),
247         recursion_limit: Cell::new(64),
248     };
249
250     sess.lint_store.borrow_mut().register_builtin(Some(&sess));
251     sess
252 }
253
254 // Seems out of place, but it uses session, so I'm putting it here
255 pub fn expect<T:Clone>(sess: &Session, opt: Option<T>, msg: || -> String)
256               -> T {
257     diagnostic::expect(sess.diagnostic(), opt, msg)
258 }