about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNixon Enraght-Moony <nixon.emoony@gmail.com>2023-01-02 19:54:08 +0000
committerNixon Enraght-Moony <nixon.emoony@gmail.com>2023-01-03 14:54:46 +0000
commit95329080d317f01f22ddce1dec8be693ef4b29f4 (patch)
treed64308178c42b4401d199fe0fe1529964e308fde /src
parent855b7e8cf3963b9f187249f1f38b6bb2baa9c353 (diff)
downloadrust-95329080d317f01f22ddce1dec8be693ef4b29f4.tar.gz
rust-95329080d317f01f22ddce1dec8be693ef4b29f4.zip
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.
Diffstat (limited to 'src')
-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"),
+        }],
+    );
 }