Skip to content

Commit 9532908

Browse files
committed
jsondoclint: Find selector for missing ID when error is created, not reported.
This is needed for json output, but even without that, it increases performance massivly. On my machine, in reduces the time to check core.json from 40.190s to 11.333s.
1 parent 855b7e8 commit 9532908

File tree

3 files changed

+64
-42
lines changed

3 files changed

+64
-42
lines changed

src/tools/jsondoclint/src/main.rs

+36-37
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ struct Error {
1616

1717
#[derive(Debug, PartialEq, Eq)]
1818
enum ErrorKind {
19-
NotFound,
19+
NotFound(Vec<json_find::Selector>),
2020
Custom(String),
2121
}
2222

@@ -37,49 +37,48 @@ fn main() -> Result<()> {
3737
let krate: Crate = serde_json::from_str(&contents)?;
3838
assert_eq!(krate.format_version, FORMAT_VERSION);
3939

40-
let mut validator = validator::Validator::new(&krate);
40+
let krate_json: Value = serde_json::from_str(&contents)?;
41+
42+
let mut validator = validator::Validator::new(&krate, krate_json);
4143
validator.check_crate();
4244

4345
if !validator.errs.is_empty() {
4446
for err in validator.errs {
4547
match err.kind {
46-
ErrorKind::NotFound => {
47-
let krate_json: Value = serde_json::from_str(&contents)?;
48-
49-
let sels =
50-
json_find::find_selector(&krate_json, &Value::String(err.id.0.clone()));
51-
match &sels[..] {
52-
[] => unreachable!(
53-
"id must be in crate, or it wouldn't be reported as not found"
54-
),
55-
[sel] => eprintln!(
56-
"{} not in index or paths, but refered to at '{}'",
57-
err.id.0,
58-
json_find::to_jsonpath(&sel)
59-
),
60-
[sel, ..] => {
61-
if verbose {
62-
let sels = sels
63-
.iter()
64-
.map(json_find::to_jsonpath)
65-
.map(|i| format!("'{i}'"))
66-
.collect::<Vec<_>>()
67-
.join(", ");
68-
eprintln!(
69-
"{} not in index or paths, but refered to at {sels}",
70-
err.id.0
71-
);
72-
} else {
73-
eprintln!(
74-
"{} not in index or paths, but refered to at '{}' and {} more",
75-
err.id.0,
76-
json_find::to_jsonpath(&sel),
77-
sels.len() - 1,
78-
)
79-
}
48+
ErrorKind::NotFound(sels) => match &sels[..] {
49+
[] => {
50+
unreachable!(
51+
"id {:?} must be in crate, or it wouldn't be reported as not found",
52+
err.id
53+
)
54+
}
55+
[sel] => eprintln!(
56+
"{} not in index or paths, but refered to at '{}'",
57+
err.id.0,
58+
json_find::to_jsonpath(&sel)
59+
),
60+
[sel, ..] => {
61+
if verbose {
62+
let sels = sels
63+
.iter()
64+
.map(json_find::to_jsonpath)
65+
.map(|i| format!("'{i}'"))
66+
.collect::<Vec<_>>()
67+
.join(", ");
68+
eprintln!(
69+
"{} not in index or paths, but refered to at {sels}",
70+
err.id.0
71+
);
72+
} else {
73+
eprintln!(
74+
"{} not in index or paths, but refered to at '{}' and {} more",
75+
err.id.0,
76+
json_find::to_jsonpath(&sel),
77+
sels.len() - 1,
78+
)
8079
}
8180
}
82-
}
81+
},
8382
ErrorKind::Custom(msg) => eprintln!("{}: {}", err.id.0, msg),
8483
}
8584
}

src/tools/jsondoclint/src/validator.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ use rustdoc_json_types::{
77
Primitive, ProcMacro, Static, Struct, StructKind, Term, Trait, TraitAlias, Type, TypeBinding,
88
TypeBindingKind, Typedef, Union, Variant, VariantKind, WherePredicate,
99
};
10+
use serde_json::Value;
1011

11-
use crate::{item_kind::Kind, Error, ErrorKind};
12+
use crate::{item_kind::Kind, json_find, Error, ErrorKind};
1213

1314
/// The Validator walks over the JSON tree, and ensures it is well formed.
1415
/// It is made of several parts.
@@ -22,6 +23,7 @@ use crate::{item_kind::Kind, Error, ErrorKind};
2223
pub struct Validator<'a> {
2324
pub(crate) errs: Vec<Error>,
2425
krate: &'a Crate,
26+
krate_json: Value,
2527
/// Worklist of Ids to check.
2628
todo: HashSet<&'a Id>,
2729
/// Ids that have already been visited, so don't need to be checked again.
@@ -39,9 +41,10 @@ enum PathKind {
3941
}
4042

4143
impl<'a> Validator<'a> {
42-
pub fn new(krate: &'a Crate) -> Self {
44+
pub fn new(krate: &'a Crate, krate_json: Value) -> Self {
4345
Self {
4446
krate,
47+
krate_json,
4548
errs: Vec::new(),
4649
seen_ids: HashSet::new(),
4750
todo: HashSet::new(),
@@ -373,7 +376,11 @@ impl<'a> Validator<'a> {
373376
} else {
374377
if !self.missing_ids.contains(id) {
375378
self.missing_ids.insert(id);
376-
self.fail(id, ErrorKind::NotFound)
379+
380+
let sels = json_find::find_selector(&self.krate_json, &Value::String(id.0.clone()));
381+
assert_ne!(sels.len(), 0);
382+
383+
self.fail(id, ErrorKind::NotFound(sels))
377384
}
378385
}
379386
}

src/tools/jsondoclint/src/validator/tests.rs

+18-2
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,16 @@ use std::collections::HashMap;
22

33
use rustdoc_json_types::{Crate, Item, Visibility};
44

5+
use crate::json_find::SelectorPart;
6+
57
use super::*;
68

79
#[track_caller]
810
fn check(krate: &Crate, errs: &[Error]) {
9-
let mut validator = Validator::new(krate);
11+
let krate_string = serde_json::to_string(krate).unwrap();
12+
let krate_json = serde_json::from_str(&krate_string).unwrap();
13+
14+
let mut validator = Validator::new(krate, krate_json);
1015
validator.check_crate();
1116

1217
assert_eq!(errs, &validator.errs[..]);
@@ -46,5 +51,16 @@ fn errors_on_missing_links() {
4651
format_version: rustdoc_json_types::FORMAT_VERSION,
4752
};
4853

49-
check(&k, &[Error { kind: ErrorKind::NotFound, id: id("1") }]);
54+
check(
55+
&k,
56+
&[Error {
57+
kind: ErrorKind::NotFound(vec![vec![
58+
SelectorPart::Field("index".to_owned()),
59+
SelectorPart::Field("0".to_owned()),
60+
SelectorPart::Field("links".to_owned()),
61+
SelectorPart::Field("Not Found".to_owned()),
62+
]]),
63+
id: id("1"),
64+
}],
65+
);
5066
}

0 commit comments

Comments
 (0)