-fn parse_crate(
- input: Input,
- parse_session: &ParseSess,
- config: &Config,
- report: &mut FormatReport,
- directory_ownership: Option<parse::DirectoryOwnership>,
-) -> Result<ast::Crate, ErrorKind> {
- let input_is_stdin = input.is_text();
-
- let parser = match input {
- Input::File(ref file) => {
- // Use `new_sub_parser_from_file` when we the input is a submodule.
- Ok(if let Some(dir_own) = directory_ownership {
- parse::new_sub_parser_from_file(parse_session, file, dir_own, None, DUMMY_SP)
- } else {
- parse::new_parser_from_file(parse_session, file)
- })
- }
- Input::Text(text) => parse::maybe_new_parser_from_source_str(
- parse_session,
- syntax::source_map::FileName::Custom("stdin".to_owned()),
- text,
- )
- .map(|mut parser| {
- parser.recurse_into_file_modules = false;
- parser
- })
- .map_err(|diags| {
- diags
- .into_iter()
- .map(|d| DiagnosticBuilder::new_diagnostic(&parse_session.span_diagnostic, d))
- .collect::<Vec<_>>()
- }),
- };
-
- let result = match parser {
- Ok(mut parser) => {
- parser.cfg_mods = false;
- if config.skip_children() {
- parser.recurse_into_file_modules = false;
- }
-
- let mut parser = AssertUnwindSafe(parser);
- catch_unwind(move || parser.0.parse_crate_mod().map_err(|d| vec![d]))
- }
- Err(db) => Ok(Err(db)),
- };
-
- match result {
- Ok(Ok(c)) => {
- if !parse_session.span_diagnostic.has_errors() {
- return Ok(c);
- }
- }
- Ok(Err(mut diagnostics)) => diagnostics.iter_mut().for_each(DiagnosticBuilder::emit),
- Err(_) => {
- // Note that if you see this message and want more information,
- // then run the `parse_crate_mod` function above without
- // `catch_unwind` so rustfmt panics and you can get a backtrace.
- should_emit_verbose(input_is_stdin, config, || {
- println!("The Rust parser panicked")
- });
- }
- }
-
- report.add_parsing_error();
- Err(ErrorKind::ParseError)
-}
-
-/// Emitter which discards every error.
-struct SilentEmitter;
-
-impl Emitter for SilentEmitter {
- fn emit(&mut self, _db: &DiagnosticBuilder<'_>) {}
-}
-
-fn silent_emitter() -> Box<SilentEmitter> {
- Box::new(SilentEmitter {})
-}
-
-fn make_parse_sess(source_map: Rc<SourceMap>, config: &Config) -> ParseSess {
- let tty_handler = if config.hide_parse_errors() {
- let silent_emitter = silent_emitter();
- Handler::with_emitter(true, None, silent_emitter)
- } else {
- let supports_color = term::stderr().map_or(false, |term| term.supports_color());
- let color_cfg = if supports_color {
- ColorConfig::Auto
- } else {
- ColorConfig::Never
- };
- Handler::with_tty_emitter(color_cfg, true, None, Some(source_map.clone()))
- };
-
- ParseSess::with_span_handler(tty_handler, source_map)
-}
-
-fn should_emit_verbose<F>(is_stdin: bool, config: &Config, f: F)