-
Notifications
You must be signed in to change notification settings - Fork 13.3k
rustdoc: Replaces fn main search and extern crate search with proper parsing during doctests. #54861
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
rustdoc: Replaces fn main search and extern crate search with proper parsing during doctests. #54861
Changes from all commits
b79fdb8
43b65b5
cd407df
f36ed5b
d6d8c6b
8a3b5e9
0fe6aae
014c8c4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,7 +15,7 @@ use ast::{self, CrateConfig, NodeId}; | |
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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't this use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How deep do you want me to go? Should i reimplement each existing function in terms of its new There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you have the time, that'd be great. I just want to minimize code duplication. Whenever I add a fallible version of an existing method, I rewrite the callees if under a dozen, or I rewrite the infallible version to call the fallible version. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Makes sense. I've got the change written locally, i'll push once i finish my current build. |
||
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 @@ crate fn new_sub_parser_from_file<'a>(sess: &'a ParseSess, | |
|
||
/// 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 | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was this was the only API addition you needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This and the
new_or_buffered_errs
constructor. I needed a way to "handle" the errors without prematurely emitting them (in this case, to cancel them), and this felt like a natural way to get the content ofself.fatal_errs
without just exposing the Vec directly. Since bothnew
andnew_without_err
emitted the errors directly, i added this instead.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not against it, I'm surprised at how little you needed to add :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup! I just needed a version that wouldn't immediately crash the process if it ran into a problem in the first token. One thing i will ask is whether the current implementation with
buffer()
is appropriate, since plain Diagnostics don't have the destructor bomb that fullDiagnosticBuilder
s have. (Since they need aHandler
to be emitted, they don't have the same ability to forcibly print themselves.) The alternative would be to swap out the Vec entirely and return the full DiagnosticBuilder, and since theParseSess
isn't local the lifetimes would work out.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cc @petrochenkov