about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/tools/jsondoclint/src/main.rs73
-rw-r--r--src/tools/jsondoclint/src/validator.rs13
-rw-r--r--src/tools/jsondoclint/src/validator/tests.rs20
3 files changed, 64 insertions, 42 deletions
diff --git a/src/tools/jsondoclint/src/main.rs b/src/tools/jsondoclint/src/main.rs
index 89965dc2403..266900ea3a2 100644
--- a/src/tools/jsondoclint/src/main.rs
+++ b/src/tools/jsondoclint/src/main.rs
@@ -16,7 +16,7 @@ struct Error {
 
 #[derive(Debug, PartialEq, Eq)]
 enum ErrorKind {
-    NotFound,
+    NotFound(Vec<json_find::Selector>),
     Custom(String),
 }
 
@@ -37,49 +37,48 @@ fn main() -> Result<()> {
     let krate: Crate = serde_json::from_str(&contents)?;
     assert_eq!(krate.format_version, FORMAT_VERSION);
 
-    let mut validator = validator::Validator::new(&krate);
+    let krate_json: Value = serde_json::from_str(&contents)?;
+
+    let mut validator = validator::Validator::new(&krate, krate_json);
     validator.check_crate();
 
     if !validator.errs.is_empty() {
         for err in validator.errs {
             match err.kind {
-                ErrorKind::NotFound => {
-                    let krate_json: Value = serde_json::from_str(&contents)?;
-
-                    let sels =
-                        json_find::find_selector(&krate_json, &Value::String(err.id.0.clone()));
-                    match &sels[..] {
-                        [] => unreachable!(
-                            "id must be in crate, or it wouldn't be reported as not found"
-                        ),
-                        [sel] => eprintln!(
-                            "{} not in index or paths, but refered to at '{}'",
-                            err.id.0,
-                            json_find::to_jsonpath(&sel)
-                        ),
-                        [sel, ..] => {
-                            if verbose {
-                                let sels = sels
-                                    .iter()
-                                    .map(json_find::to_jsonpath)
-                                    .map(|i| format!("'{i}'"))
-                                    .collect::<Vec<_>>()
-                                    .join(", ");
-                                eprintln!(
-                                    "{} not in index or paths, but refered to at {sels}",
-                                    err.id.0
-                                );
-                            } else {
-                                eprintln!(
-                                    "{} not in index or paths, but refered to at '{}' and {} more",
-                                    err.id.0,
-                                    json_find::to_jsonpath(&sel),
-                                    sels.len() - 1,
-                                )
-                            }
+                ErrorKind::NotFound(sels) => match &sels[..] {
+                    [] => {
+                        unreachable!(
+                            "id {:?} must be in crate, or it wouldn't be reported as not found",
+                            err.id
+                        )
+                    }
+                    [sel] => eprintln!(
+                        "{} not in index or paths, but refered to at '{}'",
+                        err.id.0,
+                        json_find::to_jsonpath(&sel)
+                    ),
+                    [sel, ..] => {
+                        if verbose {
+                            let sels = sels
+                                .iter()
+                                .map(json_find::to_jsonpath)
+                                .map(|i| format!("'{i}'"))
+                                .collect::<Vec<_>>()
+                                .join(", ");
+                            eprintln!(
+                                "{} not in index or paths, but refered to at {sels}",
+                                err.id.0
+                            );
+                        } else {
+                            eprintln!(
+                                "{} not in index or paths, but refered to at '{}' and {} more",
+                                err.id.0,
+                                json_find::to_jsonpath(&sel),
+                                sels.len() - 1,
+                            )
                         }
                     }
-                }
+                },
                 ErrorKind::Custom(msg) => eprintln!("{}: {}", err.id.0, msg),
             }
         }
diff --git a/src/tools/jsondoclint/src/validator.rs b/src/tools/jsondoclint/src/validator.rs
index 291d02d67bd..f1b9c1acbae 100644
--- a/src/tools/jsondoclint/src/validator.rs
+++ b/src/tools/jsondoclint/src/validator.rs
@@ -7,8 +7,9 @@ use rustdoc_json_types::{
     Primitive, ProcMacro, Static, Struct, StructKind, Term, Trait, TraitAlias, Type, TypeBinding,
     TypeBindingKind, Typedef, Union, Variant, VariantKind, WherePredicate,
 };
+use serde_json::Value;
 
-use crate::{item_kind::Kind, Error, ErrorKind};
+use crate::{item_kind::Kind, json_find, Error, ErrorKind};
 
 /// The Validator walks over the JSON tree, and ensures it is well formed.
 /// It is made of several parts.
@@ -22,6 +23,7 @@ use crate::{item_kind::Kind, Error, ErrorKind};
 pub struct Validator<'a> {
     pub(crate) errs: Vec<Error>,
     krate: &'a Crate,
+    krate_json: Value,
     /// Worklist of Ids to check.
     todo: HashSet<&'a Id>,
     /// Ids that have already been visited, so don't need to be checked again.
@@ -39,9 +41,10 @@ enum PathKind {
 }
 
 impl<'a> Validator<'a> {
-    pub fn new(krate: &'a Crate) -> Self {
+    pub fn new(krate: &'a Crate, krate_json: Value) -> Self {
         Self {
             krate,
+            krate_json,
             errs: Vec::new(),
             seen_ids: HashSet::new(),
             todo: HashSet::new(),
@@ -373,7 +376,11 @@ impl<'a> Validator<'a> {
         } else {
             if !self.missing_ids.contains(id) {
                 self.missing_ids.insert(id);
-                self.fail(id, ErrorKind::NotFound)
+
+                let sels = json_find::find_selector(&self.krate_json, &Value::String(id.0.clone()));
+                assert_ne!(sels.len(), 0);
+
+                self.fail(id, ErrorKind::NotFound(sels))
             }
         }
     }
diff --git a/src/tools/jsondoclint/src/validator/tests.rs b/src/tools/jsondoclint/src/validator/tests.rs
index c4aeee9c53b..37b826153ef 100644
--- a/src/tools/jsondoclint/src/validator/tests.rs
+++ b/src/tools/jsondoclint/src/validator/tests.rs
@@ -2,11 +2,16 @@ use std::collections::HashMap;
 
 use rustdoc_json_types::{Crate, Item, Visibility};
 
+use crate::json_find::SelectorPart;
+
 use super::*;
 
 #[track_caller]
 fn check(krate: &Crate, errs: &[Error]) {
-    let mut validator = Validator::new(krate);
+    let krate_string = serde_json::to_string(krate).unwrap();
+    let krate_json = serde_json::from_str(&krate_string).unwrap();
+
+    let mut validator = Validator::new(krate, krate_json);
     validator.check_crate();
 
     assert_eq!(errs, &validator.errs[..]);
@@ -46,5 +51,16 @@ fn errors_on_missing_links() {
         format_version: rustdoc_json_types::FORMAT_VERSION,
     };
 
-    check(&k, &[Error { kind: ErrorKind::NotFound, id: id("1") }]);
+    check(
+        &k,
+        &[Error {
+            kind: ErrorKind::NotFound(vec![vec![
+                SelectorPart::Field("index".to_owned()),
+                SelectorPart::Field("0".to_owned()),
+                SelectorPart::Field("links".to_owned()),
+                SelectorPart::Field("Not Found".to_owned()),
+            ]]),
+            id: id("1"),
+        }],
+    );
 }