Skip to content

Commit 0718226

Browse files
Move extracted doctest code and types into its own file
1 parent da926bf commit 0718226

File tree

4 files changed

+139
-61
lines changed

4 files changed

+139
-61
lines changed

src/librustdoc/doctest.rs

+4-46
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
mod extracted;
12
mod make;
23
mod markdown;
34
mod runner;
@@ -26,7 +27,6 @@ use rustc_span::FileName;
2627
use rustc_span::edition::Edition;
2728
use rustc_span::symbol::sym;
2829
use rustc_target::spec::{Target, TargetTuple};
29-
use serde::{Serialize, Serializer};
3030
use tempfile::{Builder as TempFileBuilder, TempDir};
3131
use tracing::debug;
3232

@@ -134,14 +134,6 @@ fn get_doctest_dir() -> io::Result<TempDir> {
134134
TempFileBuilder::new().prefix("rustdoctest").tempdir()
135135
}
136136

137-
#[derive(Serialize)]
138-
struct ExtractedDoctest {
139-
/// `None` if the code syntax is invalid.
140-
doctest_code: Option<String>,
141-
#[serde(flatten)] // We make all `ScrapedDocTest` fields at the same level as `doctest_code`.
142-
scraped_test: ScrapedDocTest,
143-
}
144-
145137
pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions) {
146138
let invalid_codeblock_attributes_name = crate::lint::INVALID_CODEBLOCK_ATTRIBUTES.name;
147139

@@ -243,34 +235,12 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions
243235
);
244236
let tests = hir_collector.collect_crate();
245237
if extract_doctests {
246-
let extracted = tests
247-
.into_iter()
248-
.map(|scraped_test| {
249-
let edition = scraped_test.edition(&options);
250-
let doctest = DocTestBuilder::new(
251-
&scraped_test.text,
252-
Some(&opts.crate_name),
253-
edition,
254-
false,
255-
None,
256-
Some(&scraped_test.langstr),
257-
);
258-
let (full_test_code, size) = doctest.generate_unique_doctest(
259-
&scraped_test.text,
260-
scraped_test.langstr.test_harness,
261-
&opts,
262-
Some(&opts.crate_name),
263-
);
264-
ExtractedDoctest {
265-
doctest_code: if size != 0 { Some(full_test_code) } else { None },
266-
scraped_test,
267-
}
268-
})
269-
.collect::<Vec<_>>();
238+
let mut collector = extracted::ExtractedDocTests::new();
239+
tests.into_iter().for_each(|t| collector.add_test(t, &opts, &options));
270240

271241
let stdout = std::io::stdout();
272242
let mut stdout = stdout.lock();
273-
if let Err(error) = serde_json::ser::to_writer(&mut stdout, &extracted) {
243+
if let Err(error) = serde_json::ser::to_writer(&mut stdout, &collector) {
274244
eprintln!();
275245
Err(format!("Failed to generate JSON output for doctests: {error:?}"))
276246
} else {
@@ -805,14 +775,6 @@ impl IndividualTestOptions {
805775
}
806776
}
807777

808-
fn filename_to_string<S: Serializer>(
809-
filename: &FileName,
810-
serializer: S,
811-
) -> Result<S::Ok, S::Error> {
812-
let filename = filename.prefer_remapped_unconditionaly().to_string();
813-
serializer.serialize_str(&filename)
814-
}
815-
816778
/// A doctest scraped from the code, ready to be turned into a runnable test.
817779
///
818780
/// The pipeline goes: [`clean`] AST -> `ScrapedDoctest` -> `RunnableDoctest`.
@@ -822,14 +784,10 @@ fn filename_to_string<S: Serializer>(
822784
/// [`clean`]: crate::clean
823785
/// [`run_merged_tests`]: crate::doctest::runner::DocTestRunner::run_merged_tests
824786
/// [`generate_unique_doctest`]: crate::doctest::make::DocTestBuilder::generate_unique_doctest
825-
#[derive(Serialize)]
826787
pub(crate) struct ScrapedDocTest {
827-
#[serde(serialize_with = "filename_to_string")]
828788
filename: FileName,
829789
line: usize,
830-
#[serde(rename = "doctest_attributes")]
831790
langstr: LangString,
832-
#[serde(rename = "original_code")]
833791
text: String,
834792
name: String,
835793
}

src/librustdoc/doctest/extracted.rs

+132
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
use serde::Serialize;
2+
3+
use super::{DocTestBuilder, ScrapedDocTest};
4+
use crate::config::Options as RustdocOptions;
5+
use crate::html::markdown;
6+
7+
const FORMAT_VERSION: u32 = 1;
8+
9+
#[derive(Serialize)]
10+
pub(crate) struct ExtractedDocTests {
11+
#[allow(non_snake_case)]
12+
format_version: u32,
13+
doctests: Vec<ExtractedDocTest>,
14+
}
15+
16+
impl ExtractedDocTests {
17+
pub(crate) fn new() -> Self {
18+
Self { format_version: FORMAT_VERSION, doctests: Vec::new() }
19+
}
20+
21+
pub(crate) fn add_test(
22+
&mut self,
23+
scraped_test: ScrapedDocTest,
24+
opts: &super::GlobalTestOptions,
25+
options: &RustdocOptions,
26+
) {
27+
let edition = scraped_test.edition(&options);
28+
29+
let ScrapedDocTest { filename, line, langstr, text, name } = scraped_test;
30+
31+
let doctest = DocTestBuilder::new(
32+
&text,
33+
Some(&opts.crate_name),
34+
edition,
35+
false,
36+
None,
37+
Some(&langstr),
38+
);
39+
let (full_test_code, size) = doctest.generate_unique_doctest(
40+
&text,
41+
langstr.test_harness,
42+
&opts,
43+
Some(&opts.crate_name),
44+
);
45+
self.doctests.push(ExtractedDocTest {
46+
file: filename.prefer_remapped_unconditionaly().to_string(),
47+
line,
48+
doctest_attributes: langstr.into(),
49+
doctest_code: if size != 0 { Some(full_test_code) } else { None },
50+
original_code: text,
51+
name,
52+
});
53+
}
54+
}
55+
56+
#[derive(Serialize)]
57+
pub(crate) struct ExtractedDocTest {
58+
file: String,
59+
line: usize,
60+
doctest_attributes: LangString,
61+
original_code: String,
62+
/// `None` if the code syntax is invalid.
63+
doctest_code: Option<String>,
64+
name: String,
65+
}
66+
67+
#[derive(Serialize)]
68+
pub(crate) enum Ignore {
69+
All,
70+
None,
71+
Some(Vec<String>),
72+
}
73+
74+
impl From<markdown::Ignore> for Ignore {
75+
fn from(original: markdown::Ignore) -> Self {
76+
match original {
77+
markdown::Ignore::All => Self::All,
78+
markdown::Ignore::None => Self::None,
79+
markdown::Ignore::Some(values) => Self::Some(values),
80+
}
81+
}
82+
}
83+
84+
#[derive(Serialize)]
85+
struct LangString {
86+
pub(crate) original: String,
87+
pub(crate) should_panic: bool,
88+
pub(crate) no_run: bool,
89+
pub(crate) ignore: Ignore,
90+
pub(crate) rust: bool,
91+
pub(crate) test_harness: bool,
92+
pub(crate) compile_fail: bool,
93+
pub(crate) standalone_crate: bool,
94+
pub(crate) error_codes: Vec<String>,
95+
pub(crate) edition: Option<String>,
96+
pub(crate) added_css_classes: Vec<String>,
97+
pub(crate) unknown: Vec<String>,
98+
}
99+
100+
impl From<markdown::LangString> for LangString {
101+
fn from(original: markdown::LangString) -> Self {
102+
let markdown::LangString {
103+
original,
104+
should_panic,
105+
no_run,
106+
ignore,
107+
rust,
108+
test_harness,
109+
compile_fail,
110+
standalone_crate,
111+
error_codes,
112+
edition,
113+
added_classes,
114+
unknown,
115+
} = original;
116+
117+
Self {
118+
original,
119+
should_panic,
120+
no_run,
121+
ignore: ignore.into(),
122+
rust,
123+
test_harness,
124+
compile_fail,
125+
standalone_crate,
126+
error_codes,
127+
edition: edition.map(|edition| edition.to_string()),
128+
added_css_classes: added_classes,
129+
unknown,
130+
}
131+
}
132+
}

src/librustdoc/html/markdown.rs

+2-14
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ pub(crate) use rustc_resolve::rustdoc::main_body_opts;
4646
use rustc_resolve::rustdoc::may_be_doc_link;
4747
use rustc_span::edition::Edition;
4848
use rustc_span::{Span, Symbol};
49-
use serde::{Serialize, Serializer};
5049
use tracing::{debug, trace};
5150

5251
use crate::clean::RenderedLink;
@@ -821,17 +820,7 @@ impl<'tcx> ExtraInfo<'tcx> {
821820
}
822821
}
823822

824-
fn edition_to_string<S: Serializer>(
825-
edition: &Option<Edition>,
826-
serializer: S,
827-
) -> Result<S::Ok, S::Error> {
828-
match edition {
829-
Some(edition) => serializer.serialize_some(&edition.to_string()),
830-
None => serializer.serialize_none(),
831-
}
832-
}
833-
834-
#[derive(Eq, PartialEq, Clone, Debug, Serialize)]
823+
#[derive(Eq, PartialEq, Clone, Debug)]
835824
pub(crate) struct LangString {
836825
pub(crate) original: String,
837826
pub(crate) should_panic: bool,
@@ -842,13 +831,12 @@ pub(crate) struct LangString {
842831
pub(crate) compile_fail: bool,
843832
pub(crate) standalone_crate: bool,
844833
pub(crate) error_codes: Vec<String>,
845-
#[serde(serialize_with = "edition_to_string")]
846834
pub(crate) edition: Option<Edition>,
847835
pub(crate) added_classes: Vec<String>,
848836
pub(crate) unknown: Vec<String>,
849837
}
850838

851-
#[derive(Eq, PartialEq, Clone, Debug, Serialize)]
839+
#[derive(Eq, PartialEq, Clone, Debug)]
852840
pub(crate) enum Ignore {
853841
All,
854842
None,
+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
[{"doctest_code":"#![allow(unused)]\nfn main() {\nlet x = 12;\nlet y = 14;\n}","filename":"$DIR/extract-doctests.rs","line":8,"doctest_attributes":{"original":"ignore (checking attributes)","should_panic":false,"no_run":false,"ignore":"All","rust":true,"test_harness":false,"compile_fail":false,"standalone_crate":false,"error_codes":[],"edition":null,"added_classes":[],"unknown":[]},"original_code":"let x = 12;\nlet y = 14;","name":"$DIR/extract-doctests.rs - (line 8)"},{"doctest_code":"#![allow(unused)]\nfn main() {\nlet\n}","filename":"$DIR/extract-doctests.rs","line":13,"doctest_attributes":{"original":"edition2018,compile_fail","should_panic":false,"no_run":true,"ignore":"None","rust":true,"test_harness":false,"compile_fail":true,"standalone_crate":false,"error_codes":[],"edition":"2018","added_classes":[],"unknown":[]},"original_code":"let","name":"$DIR/extract-doctests.rs - (line 13)"}]
1+
{"format_version":1,"doctests":[{"file":"$DIR/extract-doctests.rs","line":8,"doctest_attributes":{"original":"ignore (checking attributes)","should_panic":false,"no_run":false,"ignore":"All","rust":true,"test_harness":false,"compile_fail":false,"standalone_crate":false,"error_codes":[],"edition":null,"added_css_classes":[],"unknown":[]},"original_code":"let x = 12;\nlet y = 14;","doctest_code":"#![allow(unused)]\nfn main() {\nlet x = 12;\nlet y = 14;\n}","name":"$DIR/extract-doctests.rs - (line 8)"},{"file":"$DIR/extract-doctests.rs","line":13,"doctest_attributes":{"original":"edition2018,compile_fail","should_panic":false,"no_run":true,"ignore":"None","rust":true,"test_harness":false,"compile_fail":true,"standalone_crate":false,"error_codes":[],"edition":"2018","added_css_classes":[],"unknown":[]},"original_code":"let","doctest_code":"#![allow(unused)]\nfn main() {\nlet\n}","name":"$DIR/extract-doctests.rs - (line 13)"}]}

0 commit comments

Comments
 (0)