Skip to content

Commit 99ce39b

Browse files
Load error codes via build script instead of JSON parsing
This scans the tree for `error_codes.rs` and loads all of them.
1 parent 29a5403 commit 99ce39b

File tree

4 files changed

+84
-31
lines changed

4 files changed

+84
-31
lines changed

Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -946,6 +946,7 @@ name = "error_index_generator"
946946
version = "0.0.0"
947947
dependencies = [
948948
"rustdoc",
949+
"walkdir",
949950
]
950951

951952
[[package]]

src/tools/error_index_generator/Cargo.toml

+4
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,14 @@ authors = ["The Rust Project Developers"]
33
name = "error_index_generator"
44
version = "0.0.0"
55
edition = "2018"
6+
build = "build.rs"
67

78
[dependencies]
89
rustdoc = { path = "../../librustdoc" }
910

11+
[build-dependencies]
12+
walkdir = "2"
13+
1014
[[bin]]
1115
name = "error_index_generator"
1216
path = "main.rs"
+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
use walkdir::WalkDir;
2+
use std::path::PathBuf;
3+
use std::{env, fs};
4+
5+
fn main() {
6+
// The src directory (we are in src/tools/error_index_generator)
7+
// Note that we could skip one of the .. but this ensures we at least loosely find the right
8+
// directory.
9+
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
10+
let dest = out_dir.join("error_codes.rs");
11+
let mut idx = 0;
12+
for entry in WalkDir::new("../../../src") {
13+
let entry = entry.unwrap();
14+
if entry.file_name() == "error_codes.rs" {
15+
println!("cargo:rerun-if-changed={}", entry.path().to_str().unwrap());
16+
let file = fs::read_to_string(entry.path()).unwrap()
17+
.replace("use syntax::{register_diagnostics, register_long_diagnostics};", "")
18+
.replace("use syntax::register_diagnostics;", "")
19+
.replace("use syntax::register_long_diagnostics;", "");
20+
let contents = format!("(|| {{\n{}\n}})();", file);
21+
22+
fs::write(&out_dir.join(&format!("error_{}.rs", idx)), &contents).unwrap();
23+
24+
idx += 1;
25+
}
26+
}
27+
28+
let mut all = String::new();
29+
all.push_str("fn register_all() -> Vec<(&'static str, Option<&'static str>)> {\n");
30+
all.push_str("let mut long_codes: Vec<(&'static str, Option<&'static str>)> = Vec::new();\n");
31+
all.push_str(r#"
32+
macro_rules! register_diagnostics {
33+
($($code:tt),*) => {{
34+
long_codes.extend([$(
35+
stringify!($code),
36+
)*].iter().cloned().map(|s| (s, None)).collect::<Vec<_>>());
37+
}};
38+
($($code:tt),*,) => {{
39+
long_codes.extend([$(
40+
stringify!($code),
41+
)*].iter().cloned().map(|s| (s, None)));
42+
}}
43+
}
44+
45+
macro_rules! register_long_diagnostics {
46+
($($code:tt: $description:tt),*) => {
47+
{long_codes.extend([$(
48+
(stringify!($code), Some(stringify!($description))),
49+
)*].iter());}
50+
};
51+
($($code:tt: $description:tt),*,) => {
52+
{long_codes.extend([$(
53+
(stringify!($code), Some(stringify!($description))),
54+
)*].iter());}
55+
}
56+
}"#);
57+
for idx in 0..idx {
58+
all.push_str(&format!(r#"include!(concat!(env!("OUT_DIR"), "/error_{}.rs"));"#, idx));
59+
}
60+
all.push_str("\nlong_codes\n");
61+
all.push_str("}\n");
62+
63+
fs::write(&dest, all).unwrap();
64+
}

src/tools/error_index_generator/main.rs

+15-31
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,20 @@
22

33
extern crate env_logger;
44
extern crate syntax;
5-
extern crate serialize as rustc_serialize;
65

76
use std::collections::BTreeMap;
87
use std::env;
98
use std::error::Error;
10-
use std::fs::{self, read_dir, File};
9+
use std::fs::File;
1110
use std::io::Write;
1211
use std::path::Path;
1312
use std::path::PathBuf;
1413
use std::cell::RefCell;
1514

1615
use syntax::edition::DEFAULT_EDITION;
17-
use syntax::diagnostics::metadata::{get_metadata_dir, ErrorMetadataMap, ErrorMetadata};
16+
use syntax::diagnostics::metadata::{ErrorMetadataMap, ErrorMetadata};
1817

1918
use rustdoc::html::markdown::{Markdown, IdMap, ErrorCodes, Playground};
20-
use rustc_serialize::json;
2119

2220
enum OutputFormat {
2321
HTML(HTMLFormatter),
@@ -80,11 +78,7 @@ impl Formatter for HTMLFormatter {
8078
Some(_) => "error-described",
8179
None => "error-undescribed",
8280
};
83-
let use_desc = match info.use_site {
84-
Some(_) => "error-used",
85-
None => "error-unused",
86-
};
87-
write!(output, "<div class=\"{} {}\">", desc_desc, use_desc)?;
81+
write!(output, "<div class=\"{}\">", desc_desc)?;
8882

8983
// Error title (with self-link).
9084
write!(output,
@@ -199,25 +193,6 @@ impl Formatter for MarkdownFormatter {
199193
}
200194
}
201195

202-
/// Loads all the metadata files from `metadata_dir` into an in-memory map.
203-
fn load_all_errors(metadata_dir: &Path) -> Result<ErrorMetadataMap, Box<dyn Error>> {
204-
let mut all_errors = BTreeMap::new();
205-
206-
for entry in read_dir(metadata_dir)? {
207-
let path = entry?.path();
208-
209-
let metadata_str = fs::read_to_string(&path)?;
210-
211-
let some_errors: ErrorMetadataMap = json::decode(&metadata_str)?;
212-
213-
for (err_code, info) in some_errors {
214-
all_errors.insert(err_code, info);
215-
}
216-
}
217-
218-
Ok(all_errors)
219-
}
220-
221196
/// Output an HTML page for the errors in `err_map` to `output_path`.
222197
fn render_error_page<T: Formatter>(err_map: &ErrorMetadataMap, output_path: &Path,
223198
formatter: T) -> Result<(), Box<dyn Error>> {
@@ -234,9 +209,16 @@ fn render_error_page<T: Formatter>(err_map: &ErrorMetadataMap, output_path: &Pat
234209
}
235210

236211
fn main_with_result(format: OutputFormat, dst: &Path) -> Result<(), Box<dyn Error>> {
237-
let build_arch = env::var("CFG_BUILD")?;
238-
let metadata_dir = get_metadata_dir(&build_arch);
239-
let err_map = load_all_errors(&metadata_dir)?;
212+
let long_codes = register_all();
213+
let mut err_map = BTreeMap::new();
214+
for (code, desc) in long_codes {
215+
err_map.insert(code.to_string(), ErrorMetadata {
216+
description: desc.map(String::from),
217+
// FIXME: this indicates that the error code is not used, which may not be true.
218+
// We currently do not use this information.
219+
use_site: None,
220+
});
221+
}
240222
match format {
241223
OutputFormat::Unknown(s) => panic!("Unknown output format: {}", s),
242224
OutputFormat::HTML(h) => render_error_page(&err_map, dst, h)?,
@@ -272,3 +254,5 @@ fn main() {
272254
panic!("{}", e.description());
273255
}
274256
}
257+
258+
include!(concat!(env!("OUT_DIR"), "/error_codes.rs"));

0 commit comments

Comments
 (0)