Create a builder for DocTestBuilder type
This commit is contained in:
parent
5b86fa8282
commit
f4d41a5cbd
5 changed files with 123 additions and 72 deletions
|
|
@ -12,7 +12,7 @@ use std::sync::atomic::{AtomicUsize, Ordering};
|
|||
use std::sync::{Arc, Mutex};
|
||||
use std::{panic, str};
|
||||
|
||||
pub(crate) use make::DocTestBuilder;
|
||||
pub(crate) use make::{BuildDocTestBuilder, DocTestBuilder};
|
||||
pub(crate) use markdown::test as test_markdown;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet};
|
||||
use rustc_errors::emitter::HumanReadableErrorType;
|
||||
|
|
@ -972,16 +972,14 @@ impl CreateRunnableDocTests {
|
|||
);
|
||||
|
||||
let edition = scraped_test.edition(&self.rustdoc_options);
|
||||
let doctest = DocTestBuilder::new(
|
||||
&scraped_test.text,
|
||||
Some(&self.opts.crate_name),
|
||||
edition,
|
||||
self.can_merge_doctests,
|
||||
Some(test_id),
|
||||
Some(&scraped_test.langstr),
|
||||
dcx,
|
||||
scraped_test.span,
|
||||
);
|
||||
let doctest = BuildDocTestBuilder::new(&scraped_test.text)
|
||||
.crate_name(&self.opts.crate_name)
|
||||
.edition(edition)
|
||||
.can_merge_doctests(self.can_merge_doctests)
|
||||
.test_id(test_id)
|
||||
.lang_str(&scraped_test.langstr)
|
||||
.span(scraped_test.span)
|
||||
.build(dcx);
|
||||
let is_standalone = !doctest.can_be_merged
|
||||
|| scraped_test.langstr.compile_fail
|
||||
|| scraped_test.langstr.test_harness
|
||||
|
|
|
|||
|
|
@ -3,10 +3,9 @@
|
|||
//! This module contains the logic to extract doctests and output a JSON containing this
|
||||
//! information.
|
||||
|
||||
use rustc_span::DUMMY_SP;
|
||||
use serde::Serialize;
|
||||
|
||||
use super::{DocTestBuilder, ScrapedDocTest};
|
||||
use super::{BuildDocTestBuilder, ScrapedDocTest};
|
||||
use crate::config::Options as RustdocOptions;
|
||||
use crate::html::markdown;
|
||||
|
||||
|
|
@ -38,16 +37,11 @@ impl ExtractedDocTests {
|
|||
|
||||
let ScrapedDocTest { filename, line, langstr, text, name, .. } = scraped_test;
|
||||
|
||||
let doctest = DocTestBuilder::new(
|
||||
&text,
|
||||
Some(&opts.crate_name),
|
||||
edition,
|
||||
false,
|
||||
None,
|
||||
Some(&langstr),
|
||||
None,
|
||||
DUMMY_SP,
|
||||
);
|
||||
let doctest = BuildDocTestBuilder::new(&text)
|
||||
.crate_name(&opts.crate_name)
|
||||
.edition(edition)
|
||||
.lang_str(&langstr)
|
||||
.build(None);
|
||||
let (full_test_code, size) = doctest.generate_unique_doctest(
|
||||
&text,
|
||||
langstr.test_harness,
|
||||
|
|
|
|||
|
|
@ -12,10 +12,10 @@ use rustc_errors::emitter::stderr_destination;
|
|||
use rustc_errors::{ColorConfig, DiagCtxtHandle};
|
||||
use rustc_parse::new_parser_from_source_str;
|
||||
use rustc_session::parse::ParseSess;
|
||||
use rustc_span::edition::Edition;
|
||||
use rustc_span::edition::{DEFAULT_EDITION, Edition};
|
||||
use rustc_span::source_map::SourceMap;
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::{FileName, Span, kw};
|
||||
use rustc_span::{DUMMY_SP, FileName, Span, kw};
|
||||
use tracing::debug;
|
||||
|
||||
use super::GlobalTestOptions;
|
||||
|
|
@ -35,35 +35,78 @@ struct ParseSourceInfo {
|
|||
maybe_crate_attrs: String,
|
||||
}
|
||||
|
||||
/// This struct contains information about the doctest itself which is then used to generate
|
||||
/// doctest source code appropriately.
|
||||
pub(crate) struct DocTestBuilder {
|
||||
pub(crate) supports_color: bool,
|
||||
pub(crate) already_has_extern_crate: bool,
|
||||
pub(crate) has_main_fn: bool,
|
||||
pub(crate) crate_attrs: String,
|
||||
/// If this is a merged doctest, it will be put into `everything_else`, otherwise it will
|
||||
/// put into `crate_attrs`.
|
||||
pub(crate) maybe_crate_attrs: String,
|
||||
pub(crate) crates: String,
|
||||
pub(crate) everything_else: String,
|
||||
pub(crate) test_id: Option<String>,
|
||||
pub(crate) invalid_ast: bool,
|
||||
pub(crate) can_be_merged: bool,
|
||||
/// Builder type for `DocTestBuilder`.
|
||||
pub(crate) struct BuildDocTestBuilder<'a> {
|
||||
source: &'a str,
|
||||
crate_name: Option<&'a str>,
|
||||
edition: Edition,
|
||||
can_merge_doctests: bool,
|
||||
// If `test_id` is `None`, it means we're generating code for a code example "run" link.
|
||||
test_id: Option<String>,
|
||||
lang_str: Option<&'a LangString>,
|
||||
span: Span,
|
||||
}
|
||||
|
||||
impl DocTestBuilder {
|
||||
pub(crate) fn new(
|
||||
source: &str,
|
||||
crate_name: Option<&str>,
|
||||
edition: Edition,
|
||||
can_merge_doctests: bool,
|
||||
// If `test_id` is `None`, it means we're generating code for a code example "run" link.
|
||||
test_id: Option<String>,
|
||||
lang_str: Option<&LangString>,
|
||||
dcx: Option<DiagCtxtHandle<'_>>,
|
||||
span: Span,
|
||||
) -> Self {
|
||||
impl<'a> BuildDocTestBuilder<'a> {
|
||||
pub(crate) fn new(source: &'a str) -> Self {
|
||||
Self {
|
||||
source,
|
||||
crate_name: None,
|
||||
edition: DEFAULT_EDITION,
|
||||
can_merge_doctests: false,
|
||||
test_id: None,
|
||||
lang_str: None,
|
||||
span: DUMMY_SP,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn crate_name(mut self, crate_name: &'a str) -> Self {
|
||||
self.crate_name = Some(crate_name);
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn can_merge_doctests(mut self, can_merge_doctests: bool) -> Self {
|
||||
self.can_merge_doctests = can_merge_doctests;
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn test_id(mut self, test_id: String) -> Self {
|
||||
self.test_id = Some(test_id);
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn lang_str(mut self, lang_str: &'a LangString) -> Self {
|
||||
self.lang_str = Some(lang_str);
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn span(mut self, span: Span) -> Self {
|
||||
self.span = span;
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn edition(mut self, edition: Edition) -> Self {
|
||||
self.edition = edition;
|
||||
self
|
||||
}
|
||||
|
||||
pub(crate) fn build(self, dcx: Option<DiagCtxtHandle<'_>>) -> DocTestBuilder {
|
||||
let BuildDocTestBuilder {
|
||||
source,
|
||||
crate_name,
|
||||
edition,
|
||||
can_merge_doctests,
|
||||
// If `test_id` is `None`, it means we're generating code for a code example "run" link.
|
||||
test_id,
|
||||
lang_str,
|
||||
span,
|
||||
} = self;
|
||||
let can_merge_doctests = can_merge_doctests
|
||||
&& lang_str.is_some_and(|lang_str| {
|
||||
!lang_str.compile_fail && !lang_str.test_harness && !lang_str.standalone_crate
|
||||
|
|
@ -89,7 +132,7 @@ impl DocTestBuilder {
|
|||
else {
|
||||
// If the AST returned an error, we don't want this doctest to be merged with the
|
||||
// others.
|
||||
return Self::invalid(
|
||||
return DocTestBuilder::invalid(
|
||||
String::new(),
|
||||
String::new(),
|
||||
String::new(),
|
||||
|
|
@ -109,7 +152,7 @@ impl DocTestBuilder {
|
|||
// If this is a merged doctest and a defined macro uses `$crate`, then the path will
|
||||
// not work, so better not put it into merged doctests.
|
||||
&& !(has_macro_def && everything_else.contains("$crate"));
|
||||
Self {
|
||||
DocTestBuilder {
|
||||
supports_color,
|
||||
has_main_fn,
|
||||
crate_attrs,
|
||||
|
|
@ -122,7 +165,26 @@ impl DocTestBuilder {
|
|||
can_be_merged,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// This struct contains information about the doctest itself which is then used to generate
|
||||
/// doctest source code appropriately.
|
||||
pub(crate) struct DocTestBuilder {
|
||||
pub(crate) supports_color: bool,
|
||||
pub(crate) already_has_extern_crate: bool,
|
||||
pub(crate) has_main_fn: bool,
|
||||
pub(crate) crate_attrs: String,
|
||||
/// If this is a merged doctest, it will be put into `everything_else`, otherwise it will
|
||||
/// put into `crate_attrs`.
|
||||
pub(crate) maybe_crate_attrs: String,
|
||||
pub(crate) crates: String,
|
||||
pub(crate) everything_else: String,
|
||||
pub(crate) test_id: Option<String>,
|
||||
pub(crate) invalid_ast: bool,
|
||||
pub(crate) can_be_merged: bool,
|
||||
}
|
||||
|
||||
impl DocTestBuilder {
|
||||
fn invalid(
|
||||
crate_attrs: String,
|
||||
maybe_crate_attrs: String,
|
||||
|
|
|
|||
|
|
@ -1,9 +1,6 @@
|
|||
use std::path::PathBuf;
|
||||
|
||||
use rustc_span::DUMMY_SP;
|
||||
use rustc_span::edition::DEFAULT_EDITION;
|
||||
|
||||
use super::{DocTestBuilder, GlobalTestOptions};
|
||||
use super::{BuildDocTestBuilder, GlobalTestOptions};
|
||||
|
||||
fn make_test(
|
||||
test_code: &str,
|
||||
|
|
@ -12,16 +9,14 @@ fn make_test(
|
|||
opts: &GlobalTestOptions,
|
||||
test_id: Option<&str>,
|
||||
) -> (String, usize) {
|
||||
let doctest = DocTestBuilder::new(
|
||||
test_code,
|
||||
crate_name,
|
||||
DEFAULT_EDITION,
|
||||
false,
|
||||
test_id.map(|s| s.to_string()),
|
||||
None,
|
||||
None,
|
||||
DUMMY_SP,
|
||||
);
|
||||
let mut builder = BuildDocTestBuilder::new(test_code);
|
||||
if let Some(crate_name) = crate_name {
|
||||
builder = builder.crate_name(crate_name);
|
||||
}
|
||||
if let Some(test_id) = test_id {
|
||||
builder = builder.test_id(test_id.to_string());
|
||||
}
|
||||
let doctest = builder.build(None);
|
||||
let (code, line_offset) =
|
||||
doctest.generate_unique_doctest(test_code, dont_insert_main, opts, crate_name);
|
||||
(code, line_offset)
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ use rustc_middle::ty::TyCtxt;
|
|||
pub(crate) use rustc_resolve::rustdoc::main_body_opts;
|
||||
use rustc_resolve::rustdoc::may_be_doc_link;
|
||||
use rustc_span::edition::Edition;
|
||||
use rustc_span::{DUMMY_SP, Span, Symbol};
|
||||
use rustc_span::{Span, Symbol};
|
||||
use tracing::{debug, trace};
|
||||
|
||||
use crate::clean::RenderedLink;
|
||||
|
|
@ -303,9 +303,11 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
|
|||
attrs: vec![],
|
||||
args_file: PathBuf::new(),
|
||||
};
|
||||
let doctest = doctest::DocTestBuilder::new(
|
||||
&test, krate, edition, false, None, None, None, DUMMY_SP,
|
||||
);
|
||||
let mut builder = doctest::BuildDocTestBuilder::new(&test).edition(edition);
|
||||
if let Some(krate) = krate {
|
||||
builder = builder.crate_name(krate);
|
||||
}
|
||||
let doctest = builder.build(None);
|
||||
let (test, _) = doctest.generate_unique_doctest(&test, false, &opts, krate);
|
||||
let channel = if test.contains("#![feature(") { "&version=nightly" } else { "" };
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue