Improve code
This commit is contained in:
parent
8327bb6ad3
commit
2004dacef2
1 changed files with 29 additions and 34 deletions
|
@ -25,7 +25,7 @@ use crate::html::markdown::LangString;
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct ParseSourceInfo {
|
struct ParseSourceInfo {
|
||||||
has_main_fn: bool,
|
has_main_fn: bool,
|
||||||
found_extern_crate: bool,
|
already_has_extern_crate: bool,
|
||||||
supports_color: bool,
|
supports_color: bool,
|
||||||
has_global_allocator: bool,
|
has_global_allocator: bool,
|
||||||
has_macro_def: bool,
|
has_macro_def: bool,
|
||||||
|
@ -48,7 +48,7 @@ pub(crate) struct DocTestBuilder {
|
||||||
pub(crate) crates: String,
|
pub(crate) crates: String,
|
||||||
pub(crate) everything_else: String,
|
pub(crate) everything_else: String,
|
||||||
pub(crate) test_id: Option<String>,
|
pub(crate) test_id: Option<String>,
|
||||||
pub(crate) failed_ast: bool,
|
pub(crate) invalid_ast: bool,
|
||||||
pub(crate) can_be_merged: bool,
|
pub(crate) can_be_merged: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ impl DocTestBuilder {
|
||||||
|
|
||||||
let Ok(Ok(ParseSourceInfo {
|
let Ok(Ok(ParseSourceInfo {
|
||||||
has_main_fn,
|
has_main_fn,
|
||||||
found_extern_crate,
|
already_has_extern_crate,
|
||||||
supports_color,
|
supports_color,
|
||||||
has_global_allocator,
|
has_global_allocator,
|
||||||
has_macro_def,
|
has_macro_def,
|
||||||
|
@ -114,9 +114,9 @@ impl DocTestBuilder {
|
||||||
maybe_crate_attrs,
|
maybe_crate_attrs,
|
||||||
crates,
|
crates,
|
||||||
everything_else,
|
everything_else,
|
||||||
already_has_extern_crate: found_extern_crate,
|
already_has_extern_crate,
|
||||||
test_id,
|
test_id,
|
||||||
failed_ast: false,
|
invalid_ast: false,
|
||||||
can_be_merged,
|
can_be_merged,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,7 +137,7 @@ impl DocTestBuilder {
|
||||||
everything_else,
|
everything_else,
|
||||||
already_has_extern_crate: false,
|
already_has_extern_crate: false,
|
||||||
test_id,
|
test_id,
|
||||||
failed_ast: true,
|
invalid_ast: true,
|
||||||
can_be_merged: false,
|
can_be_merged: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -151,10 +151,10 @@ impl DocTestBuilder {
|
||||||
opts: &GlobalTestOptions,
|
opts: &GlobalTestOptions,
|
||||||
crate_name: Option<&str>,
|
crate_name: Option<&str>,
|
||||||
) -> (String, usize) {
|
) -> (String, usize) {
|
||||||
if self.failed_ast {
|
if self.invalid_ast {
|
||||||
// If the AST failed to compile, no need to go generate a complete doctest, the error
|
// If the AST failed to compile, no need to go generate a complete doctest, the error
|
||||||
// will be better this way.
|
// will be better this way.
|
||||||
debug!("failed AST:\n{test_code}");
|
debug!("invalid AST:\n{test_code}");
|
||||||
return (test_code.to_string(), 0);
|
return (test_code.to_string(), 0);
|
||||||
}
|
}
|
||||||
let mut line_offset = 0;
|
let mut line_offset = 0;
|
||||||
|
@ -279,7 +279,7 @@ impl DocTestBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cancel_error_count(psess: &ParseSess) {
|
fn reset_error_count(psess: &ParseSess) {
|
||||||
// Reset errors so that they won't be reported as compiler bugs when dropping the
|
// Reset errors so that they won't be reported as compiler bugs when dropping the
|
||||||
// dcx. Any errors in the tests will be reported when the test file is compiled,
|
// dcx. Any errors in the tests will be reported when the test file is compiled,
|
||||||
// Note that we still need to cancel the errors above otherwise `Diag` will panic on
|
// Note that we still need to cancel the errors above otherwise `Diag` will panic on
|
||||||
|
@ -295,7 +295,7 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result<ParseSourceIn
|
||||||
use rustc_span::source_map::FilePathMapping;
|
use rustc_span::source_map::FilePathMapping;
|
||||||
|
|
||||||
let mut info =
|
let mut info =
|
||||||
ParseSourceInfo { found_extern_crate: crate_name.is_none(), ..Default::default() };
|
ParseSourceInfo { already_has_extern_crate: crate_name.is_none(), ..Default::default() };
|
||||||
|
|
||||||
let wrapped_source = format!("{DOCTEST_CODE_WRAPPER}{source}\n}}");
|
let wrapped_source = format!("{DOCTEST_CODE_WRAPPER}{source}\n}}");
|
||||||
|
|
||||||
|
@ -322,27 +322,21 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result<ParseSourceIn
|
||||||
Ok(p) => p,
|
Ok(p) => p,
|
||||||
Err(errs) => {
|
Err(errs) => {
|
||||||
errs.into_iter().for_each(|err| err.cancel());
|
errs.into_iter().for_each(|err| err.cancel());
|
||||||
cancel_error_count(&psess);
|
reset_error_count(&psess);
|
||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
fn push_to_s(
|
fn push_to_s(s: &mut String, source: &str, span: rustc_span::Span, prev_span_hi: &mut usize) {
|
||||||
s: &mut String,
|
|
||||||
source: &str,
|
|
||||||
span: rustc_span::Span,
|
|
||||||
prev_span_hi: &mut Option<usize>,
|
|
||||||
) {
|
|
||||||
let extra_len = DOCTEST_CODE_WRAPPER.len();
|
let extra_len = DOCTEST_CODE_WRAPPER.len();
|
||||||
// We need to shift by the length of `DOCTEST_CODE_WRAPPER` because we
|
// We need to shift by the length of `DOCTEST_CODE_WRAPPER` because we
|
||||||
// added it at the beginning of the source we provided to the parser.
|
// added it at the beginning of the source we provided to the parser.
|
||||||
let lo = prev_span_hi.unwrap_or(0);
|
|
||||||
let mut hi = span.hi().0 as usize - extra_len;
|
let mut hi = span.hi().0 as usize - extra_len;
|
||||||
if hi > source.len() {
|
if hi > source.len() {
|
||||||
hi = source.len();
|
hi = source.len();
|
||||||
}
|
}
|
||||||
s.push_str(&source[lo..hi]);
|
s.push_str(&source[*prev_span_hi..hi]);
|
||||||
*prev_span_hi = Some(hi);
|
*prev_span_hi = hi;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recurse through functions body. It is necessary because the doctest source code is
|
// Recurse through functions body. It is necessary because the doctest source code is
|
||||||
|
@ -354,7 +348,7 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result<ParseSourceIn
|
||||||
crate_name: &Option<&str>,
|
crate_name: &Option<&str>,
|
||||||
is_top_level: bool,
|
is_top_level: bool,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let mut is_crate = false;
|
let mut is_extern_crate = false;
|
||||||
if !info.has_global_allocator
|
if !info.has_global_allocator
|
||||||
&& item.attrs.iter().any(|attr| attr.name_or_empty() == sym::global_allocator)
|
&& item.attrs.iter().any(|attr| attr.name_or_empty() == sym::global_allocator)
|
||||||
{
|
{
|
||||||
|
@ -370,17 +364,17 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result<ParseSourceIn
|
||||||
if let Some(ref body) = fn_item.body {
|
if let Some(ref body) = fn_item.body {
|
||||||
for stmt in &body.stmts {
|
for stmt in &body.stmts {
|
||||||
if let StmtKind::Item(ref item) = stmt.kind {
|
if let StmtKind::Item(ref item) = stmt.kind {
|
||||||
is_crate |= check_item(item, info, crate_name, false);
|
is_extern_crate |= check_item(item, info, crate_name, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::ItemKind::ExternCrate(original) => {
|
ast::ItemKind::ExternCrate(original) => {
|
||||||
is_crate = true;
|
is_extern_crate = true;
|
||||||
if !info.found_extern_crate
|
if !info.already_has_extern_crate
|
||||||
&& let Some(crate_name) = crate_name
|
&& let Some(crate_name) = crate_name
|
||||||
{
|
{
|
||||||
info.found_extern_crate = match original {
|
info.already_has_extern_crate = match original {
|
||||||
Some(name) => name.as_str() == *crate_name,
|
Some(name) => name.as_str() == *crate_name,
|
||||||
None => item.ident.as_str() == *crate_name,
|
None => item.ident.as_str() == *crate_name,
|
||||||
};
|
};
|
||||||
|
@ -391,10 +385,10 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result<ParseSourceIn
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
is_crate
|
is_extern_crate
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut prev_span_hi = None;
|
let mut prev_span_hi = 0;
|
||||||
let not_crate_attrs = [sym::forbid, sym::allow, sym::warn, sym::deny, sym::expect];
|
let not_crate_attrs = [sym::forbid, sym::allow, sym::warn, sym::deny, sym::expect];
|
||||||
let parsed = parser.parse_item(rustc_parse::parser::ForceCollect::No);
|
let parsed = parser.parse_item(rustc_parse::parser::ForceCollect::No);
|
||||||
|
|
||||||
|
@ -430,13 +424,13 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result<ParseSourceIn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for stmt in &body.stmts {
|
for stmt in &body.stmts {
|
||||||
let mut is_crate = false;
|
let mut is_extern_crate = false;
|
||||||
match stmt.kind {
|
match stmt.kind {
|
||||||
StmtKind::Item(ref item) => {
|
StmtKind::Item(ref item) => {
|
||||||
is_crate = check_item(&item, &mut info, crate_name, true);
|
is_extern_crate = check_item(&item, &mut info, crate_name, true);
|
||||||
}
|
}
|
||||||
StmtKind::Expr(ref expr) if matches!(expr.kind, ast::ExprKind::Err(_)) => {
|
StmtKind::Expr(ref expr) if matches!(expr.kind, ast::ExprKind::Err(_)) => {
|
||||||
cancel_error_count(&psess);
|
reset_error_count(&psess);
|
||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
StmtKind::MacCall(ref mac_call) if !info.has_main_fn => {
|
StmtKind::MacCall(ref mac_call) if !info.has_main_fn => {
|
||||||
|
@ -471,11 +465,12 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result<ParseSourceIn
|
||||||
if info.everything_else.is_empty()
|
if info.everything_else.is_empty()
|
||||||
&& (!info.maybe_crate_attrs.is_empty() || !info.crate_attrs.is_empty())
|
&& (!info.maybe_crate_attrs.is_empty() || !info.crate_attrs.is_empty())
|
||||||
{
|
{
|
||||||
// We add potential backlines/comments if there are some in items generated
|
// To keep the doctest code "as close as possible" to the original, we insert
|
||||||
// before the wrapping function.
|
// all the code located between this new span and the previous span which
|
||||||
|
// might contain code comments and backlines.
|
||||||
push_to_s(&mut info.crates, source, span.shrink_to_lo(), &mut prev_span_hi);
|
push_to_s(&mut info.crates, source, span.shrink_to_lo(), &mut prev_span_hi);
|
||||||
}
|
}
|
||||||
if !is_crate {
|
if !is_extern_crate {
|
||||||
push_to_s(&mut info.everything_else, source, span, &mut prev_span_hi);
|
push_to_s(&mut info.everything_else, source, span, &mut prev_span_hi);
|
||||||
} else {
|
} else {
|
||||||
push_to_s(&mut info.crates, source, span, &mut prev_span_hi);
|
push_to_s(&mut info.crates, source, span, &mut prev_span_hi);
|
||||||
|
@ -490,6 +485,6 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result<ParseSourceIn
|
||||||
_ => Err(()),
|
_ => Err(()),
|
||||||
};
|
};
|
||||||
|
|
||||||
cancel_error_count(&psess);
|
reset_error_count(&psess);
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue