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