mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-21 17:52:12 +03:00
Auto merge of #54861 - rep-nop:find_main_in_doctest, r=estebank
rustdoc: Replaces fn main search and extern crate search with proper parsing during doctests. Fixes #21299. Fixes #33731. Let me know if there's any additional changes you'd like made!
This commit is contained in:
@@ -70,6 +70,23 @@ macro_rules! panictry {
|
||||
})
|
||||
}
|
||||
|
||||
// A variant of 'panictry!' that works on a Vec<Diagnostic> instead of a single DiagnosticBuilder.
|
||||
macro_rules! panictry_buffer {
|
||||
($handler:expr, $e:expr) => ({
|
||||
use std::result::Result::{Ok, Err};
|
||||
use errors::{FatalError, DiagnosticBuilder};
|
||||
match $e {
|
||||
Ok(e) => e,
|
||||
Err(errs) => {
|
||||
for e in errs {
|
||||
DiagnosticBuilder::new_diagnostic($handler, e).emit();
|
||||
}
|
||||
FatalError.raise()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! unwrap_or {
|
||||
($opt:expr, $default:expr) => {
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
use ast::{self, Ident};
|
||||
use syntax_pos::{self, BytePos, CharPos, Pos, Span, NO_EXPANSION};
|
||||
use source_map::{SourceMap, FilePathMapping};
|
||||
use errors::{Applicability, FatalError, DiagnosticBuilder};
|
||||
use errors::{Applicability, FatalError, Diagnostic, DiagnosticBuilder};
|
||||
use parse::{token, ParseSess};
|
||||
use str::char_at;
|
||||
use symbol::{Symbol, keywords};
|
||||
@@ -175,6 +175,16 @@ pub fn emit_fatal_errors(&mut self) {
|
||||
self.fatal_errs.clear();
|
||||
}
|
||||
|
||||
pub fn buffer_fatal_errors(&mut self) -> Vec<Diagnostic> {
|
||||
let mut buffer = Vec::new();
|
||||
|
||||
for err in self.fatal_errs.drain(..) {
|
||||
err.buffer(&mut buffer);
|
||||
}
|
||||
|
||||
buffer
|
||||
}
|
||||
|
||||
pub fn peek(&self) -> TokenAndSpan {
|
||||
// FIXME(pcwalton): Bad copy!
|
||||
TokenAndSpan {
|
||||
@@ -251,6 +261,17 @@ pub fn new_without_err(sess: &'a ParseSess,
|
||||
Ok(sr)
|
||||
}
|
||||
|
||||
pub fn new_or_buffered_errs(sess: &'a ParseSess,
|
||||
source_file: Lrc<syntax_pos::SourceFile>,
|
||||
override_span: Option<Span>) -> Result<Self, Vec<Diagnostic>> {
|
||||
let mut sr = StringReader::new_raw(sess, source_file, override_span);
|
||||
if sr.advance_token().is_err() {
|
||||
Err(sr.buffer_fatal_errors())
|
||||
} else {
|
||||
Ok(sr)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn retokenize(sess: &'a ParseSess, mut span: Span) -> Self {
|
||||
let begin = sess.source_map().lookup_byte_offset(span.lo());
|
||||
let end = sess.source_map().lookup_byte_offset(span.hi());
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
use early_buffered_lints::{BufferedEarlyLint, BufferedEarlyLintId};
|
||||
use source_map::{SourceMap, FilePathMapping};
|
||||
use syntax_pos::{Span, SourceFile, FileName, MultiSpan};
|
||||
use errors::{Handler, ColorConfig, DiagnosticBuilder};
|
||||
use errors::{Handler, ColorConfig, Diagnostic, DiagnosticBuilder};
|
||||
use feature_gate::UnstableFeatures;
|
||||
use parse::parser::Parser;
|
||||
use ptr::P;
|
||||
@@ -174,12 +174,21 @@ pub fn parse_stream_from_source_str(name: FileName, source: String, sess: &Parse
|
||||
source_file_to_stream(sess, sess.source_map().new_source_file(name, source), override_span)
|
||||
}
|
||||
|
||||
// Create a new parser from a source string
|
||||
/// Create a new parser from a source string
|
||||
pub fn new_parser_from_source_str(sess: &ParseSess, name: FileName, source: String)
|
||||
-> Parser {
|
||||
let mut parser = source_file_to_parser(sess, sess.source_map().new_source_file(name, source));
|
||||
panictry_buffer!(&sess.span_diagnostic, maybe_new_parser_from_source_str(sess, name, source))
|
||||
}
|
||||
|
||||
/// Create a new parser from a source string. Returns any buffered errors from lexing the initial
|
||||
/// token stream.
|
||||
pub fn maybe_new_parser_from_source_str(sess: &ParseSess, name: FileName, source: String)
|
||||
-> Result<Parser, Vec<Diagnostic>>
|
||||
{
|
||||
let mut parser = maybe_source_file_to_parser(sess,
|
||||
sess.source_map().new_source_file(name, source))?;
|
||||
parser.recurse_into_file_modules = false;
|
||||
parser
|
||||
Ok(parser)
|
||||
}
|
||||
|
||||
/// Create a new parser, handling errors as appropriate
|
||||
@@ -204,14 +213,23 @@ pub fn new_parser_from_file<'a>(sess: &'a ParseSess, path: &Path) -> Parser<'a>
|
||||
|
||||
/// Given a source_file and config, return a parser
|
||||
fn source_file_to_parser(sess: & ParseSess, source_file: Lrc<SourceFile>) -> Parser {
|
||||
panictry_buffer!(&sess.span_diagnostic,
|
||||
maybe_source_file_to_parser(sess, source_file))
|
||||
}
|
||||
|
||||
/// Given a source_file and config, return a parser. Returns any buffered errors from lexing the
|
||||
/// initial token stream.
|
||||
fn maybe_source_file_to_parser(sess: &ParseSess, source_file: Lrc<SourceFile>)
|
||||
-> Result<Parser, Vec<Diagnostic>>
|
||||
{
|
||||
let end_pos = source_file.end_pos;
|
||||
let mut parser = stream_to_parser(sess, source_file_to_stream(sess, source_file, None));
|
||||
let mut parser = stream_to_parser(sess, maybe_file_to_stream(sess, source_file, None)?);
|
||||
|
||||
if parser.token == token::Eof && parser.span.is_dummy() {
|
||||
parser.span = Span::new(end_pos, end_pos, parser.span.ctxt());
|
||||
}
|
||||
|
||||
parser
|
||||
Ok(parser)
|
||||
}
|
||||
|
||||
// must preserve old name for now, because quote! from the *existing*
|
||||
@@ -243,9 +261,25 @@ fn file_to_source_file(sess: &ParseSess, path: &Path, spanopt: Option<Span>)
|
||||
pub fn source_file_to_stream(sess: &ParseSess,
|
||||
source_file: Lrc<SourceFile>,
|
||||
override_span: Option<Span>) -> TokenStream {
|
||||
let mut srdr = lexer::StringReader::new(sess, source_file, override_span);
|
||||
panictry_buffer!(&sess.span_diagnostic, maybe_file_to_stream(sess, source_file, override_span))
|
||||
}
|
||||
|
||||
/// Given a source file, produce a sequence of token-trees. Returns any buffered errors from
|
||||
/// parsing the token tream.
|
||||
pub fn maybe_file_to_stream(sess: &ParseSess,
|
||||
source_file: Lrc<SourceFile>,
|
||||
override_span: Option<Span>) -> Result<TokenStream, Vec<Diagnostic>> {
|
||||
let mut srdr = lexer::StringReader::new_or_buffered_errs(sess, source_file, override_span)?;
|
||||
srdr.real_token();
|
||||
panictry!(srdr.parse_all_token_trees())
|
||||
|
||||
match srdr.parse_all_token_trees() {
|
||||
Ok(stream) => Ok(stream),
|
||||
Err(err) => {
|
||||
let mut buffer = Vec::with_capacity(1);
|
||||
err.buffer(&mut buffer);
|
||||
Err(buffer)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Given stream and the `ParseSess`, produce a parser
|
||||
|
||||
Reference in New Issue
Block a user