Skip to content

Commit 51a368e

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

File tree

4 files changed

+142
-61
lines changed

4 files changed

+142
-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

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

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)