about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNixon Enraght-Moony <nixon.emoony@gmail.com>2022-08-24 20:09:37 +0100
committerNixon Enraght-Moony <nixon.emoony@gmail.com>2022-09-14 16:14:15 +0100
commit5f1bc6fc5e362c5955f6a06a7cf21e62b97c86c7 (patch)
tree79c448bfe9f3e5395f97222a9fb21c18b6720fbb
parentbb1911db393047382ae040c23598e25984244644 (diff)
downloadrust-5f1bc6fc5e362c5955f6a06a7cf21e62b97c86c7.tar.gz
rust-5f1bc6fc5e362c5955f6a06a7cf21e62b97c86c7.zip
jsondocck: Better errors
-rw-r--r--src/tools/jsondoclint/src/item_kind.rs19
-rw-r--r--src/tools/jsondoclint/src/main.rs13
-rw-r--r--src/tools/jsondoclint/src/validator.rs83
3 files changed, 70 insertions, 45 deletions
diff --git a/src/tools/jsondoclint/src/item_kind.rs b/src/tools/jsondoclint/src/item_kind.rs
index 15866ab6950..f4153245e0b 100644
--- a/src/tools/jsondoclint/src/item_kind.rs
+++ b/src/tools/jsondoclint/src/item_kind.rs
@@ -31,7 +31,6 @@ pub(crate) enum Kind {
     Keyword,
     // Not in ItemKind
     ProcMacro,
-    PrimitiveType,
 }
 
 impl Kind {
@@ -54,13 +53,13 @@ impl Kind {
             Macro => true,
             ProcMacro => true,
 
-            ForeignType => todo!("IDK"),
-            Keyword => todo!("IDK"),
-            OpaqueTy => todo!("IDK"),
-            Primitive => todo!("IDK"),
-            PrimitiveType => todo!("IDK"),
-            ProcAttribute => todo!("IDK"),
-            ProcDerive => todo!("IDK"),
+            // FIXME(adotinthevoid): I'm not sure if these are corrent
+            ForeignType => false,
+            Keyword => false,
+            OpaqueTy => false,
+            Primitive => false,
+            ProcAttribute => false,
+            ProcDerive => false,
 
             // Only in traits
             AssocConst => false,
@@ -101,7 +100,6 @@ impl Kind {
             Kind::Primitive => false,
             Kind::Keyword => false,
             Kind::ProcMacro => false,
-            Kind::PrimitiveType => false,
         }
     }
 
@@ -139,7 +137,8 @@ impl Kind {
             ItemEnum::Static(_) => Static,
             ItemEnum::Macro(_) => Macro,
             ItemEnum::ProcMacro(_) => ProcMacro,
-            ItemEnum::PrimitiveType(_) => PrimitiveType,
+            // https://github.com/rust-lang/rust/issues/100961
+            ItemEnum::PrimitiveType(_) => Primitive,
             ItemEnum::ForeignType => ForeignType,
             ItemEnum::ExternCrate { .. } => ExternCrate,
             ItemEnum::AssocConst { .. } => AssocConst,
diff --git a/src/tools/jsondoclint/src/main.rs b/src/tools/jsondoclint/src/main.rs
index b98601f7d89..4df8fbc29a2 100644
--- a/src/tools/jsondoclint/src/main.rs
+++ b/src/tools/jsondoclint/src/main.rs
@@ -9,10 +9,16 @@ mod validator;
 
 #[derive(Debug)]
 struct Error {
-    message: String,
+    kind: ErrorKind,
     id: Id,
 }
 
+#[derive(Debug)]
+enum ErrorKind {
+    NotFound,
+    Custom(String),
+}
+
 fn main() -> Result<()> {
     let path = env::args().nth(1).ok_or_else(|| anyhow!("no path given"))?;
     let contents = fs::read_to_string(path)?;
@@ -24,7 +30,10 @@ fn main() -> Result<()> {
 
     if !validator.errs.is_empty() {
         for err in validator.errs {
-            eprintln!("`{}`: `{}`", err.id.0, err.message);
+            match err.kind {
+                ErrorKind::NotFound => eprintln!("{}: Not Found", err.id.0),
+                ErrorKind::Custom(msg) => eprintln!("{}: {}", err.id.0, msg),
+            }
         }
         bail!("Errors validating json");
     }
diff --git a/src/tools/jsondoclint/src/validator.rs b/src/tools/jsondoclint/src/validator.rs
index b0e12479f92..06b114f6c2f 100644
--- a/src/tools/jsondoclint/src/validator.rs
+++ b/src/tools/jsondoclint/src/validator.rs
@@ -8,13 +8,14 @@ use rustdoc_json_types::{
     TypeBindingKind, Typedef, Union, Variant, WherePredicate,
 };
 
-use crate::{item_kind::Kind, Error};
+use crate::{item_kind::Kind, Error, ErrorKind};
 
 #[derive(Debug)]
 pub struct Validator<'a> {
     pub(crate) errs: Vec<Error>,
     krate: &'a Crate,
     seen_ids: HashSet<&'a Id>,
+    missing_ids: HashSet<&'a Id>,
     todo: HashSet<&'a Id>,
 }
 
@@ -29,7 +30,13 @@ fn set_remove<T: Hash + Eq + Clone>(set: &mut HashSet<T>) -> Option<T> {
 
 impl<'a> Validator<'a> {
     pub fn new(krate: &'a Crate) -> Self {
-        Self { krate, errs: Vec::new(), seen_ids: HashSet::new(), todo: HashSet::new() }
+        Self {
+            krate,
+            errs: Vec::new(),
+            seen_ids: HashSet::new(),
+            todo: HashSet::new(),
+            missing_ids: HashSet::new(),
+        }
     }
 
     pub fn check_crate(&mut self) {
@@ -42,32 +49,39 @@ impl<'a> Validator<'a> {
     }
 
     fn check_item(&mut self, id: &'a Id) {
-        let item = &self.krate.index[id];
-        match &item.inner {
-            ItemEnum::Import(x) => self.check_import(x),
-            ItemEnum::Union(x) => self.check_union(x),
-            ItemEnum::Struct(x) => self.check_struct(x),
-            ItemEnum::StructField(x) => self.check_struct_field(x),
-            ItemEnum::Enum(x) => self.check_enum(x),
-            ItemEnum::Variant(x) => self.check_variant(x),
-            ItemEnum::Function(x) => self.check_function(x),
-            ItemEnum::Trait(x) => self.check_trait(x),
-            ItemEnum::TraitAlias(x) => self.check_trait_alias(x),
-            ItemEnum::Method(x) => self.check_method(x),
-            ItemEnum::Impl(x) => self.check_impl(x),
-            ItemEnum::Typedef(x) => self.check_typedef(x),
-            ItemEnum::OpaqueTy(x) => self.check_opaque_ty(x),
-            ItemEnum::Constant(x) => self.check_constant(x),
-            ItemEnum::Static(x) => self.check_static(x),
-            ItemEnum::ForeignType => todo!(),
-            ItemEnum::Macro(x) => self.check_macro(x),
-            ItemEnum::ProcMacro(x) => self.check_proc_macro(x),
-            ItemEnum::PrimitiveType(x) => self.check_primitive_type(x),
-            ItemEnum::Module(x) => self.check_module(x),
-
-            ItemEnum::ExternCrate { .. } => todo!(),
-            ItemEnum::AssocConst { .. } => todo!(),
-            ItemEnum::AssocType { .. } => todo!(),
+        if let Some(item) = &self.krate.index.get(id) {
+            match &item.inner {
+                ItemEnum::Import(x) => self.check_import(x),
+                ItemEnum::Union(x) => self.check_union(x),
+                ItemEnum::Struct(x) => self.check_struct(x),
+                ItemEnum::StructField(x) => self.check_struct_field(x),
+                ItemEnum::Enum(x) => self.check_enum(x),
+                ItemEnum::Variant(x) => self.check_variant(x),
+                ItemEnum::Function(x) => self.check_function(x),
+                ItemEnum::Trait(x) => self.check_trait(x),
+                ItemEnum::TraitAlias(x) => self.check_trait_alias(x),
+                ItemEnum::Method(x) => self.check_method(x),
+                ItemEnum::Impl(x) => self.check_impl(x),
+                ItemEnum::Typedef(x) => self.check_typedef(x),
+                ItemEnum::OpaqueTy(x) => self.check_opaque_ty(x),
+                ItemEnum::Constant(x) => self.check_constant(x),
+                ItemEnum::Static(x) => self.check_static(x),
+                ItemEnum::ForeignType => todo!(),
+                ItemEnum::Macro(x) => self.check_macro(x),
+                ItemEnum::ProcMacro(x) => self.check_proc_macro(x),
+                ItemEnum::PrimitiveType(x) => self.check_primitive_type(x),
+                ItemEnum::Module(x) => self.check_module(x),
+                // FIXME: Why don't these have their own structs?
+                ItemEnum::ExternCrate { .. } => {}
+                ItemEnum::AssocConst { type_, default: _ } => self.check_type(type_),
+                ItemEnum::AssocType { generics, bounds, default } => {
+                    self.check_generics(generics);
+                    bounds.iter().for_each(|b| self.check_generic_bound(b));
+                    if let Some(ty) = default {
+                        self.check_type(ty);
+                    }
+                }
+            }
         }
     }
 
@@ -226,7 +240,7 @@ impl<'a> Validator<'a> {
                 self.check_path(trait_);
                 generic_params.iter().for_each(|gpd| self.check_generic_param_def(gpd));
             }
-            GenericBound::Outlives(_) => todo!(),
+            GenericBound::Outlives(_) => {}
         }
     }
 
@@ -337,7 +351,10 @@ impl<'a> Validator<'a> {
                 self.fail_expecting(id, expected);
             }
         } else {
-            self.fail(id, "Not found")
+            if !self.missing_ids.contains(id) {
+                self.missing_ids.insert(id);
+                self.fail(id, ErrorKind::NotFound)
+            }
         }
     }
 
@@ -368,11 +385,11 @@ impl<'a> Validator<'a> {
 
     fn fail_expecting(&mut self, id: &Id, expected: &str) {
         let kind = self.kind_of(id).unwrap(); // We know it has a kind, as it's wrong.
-        self.fail(id, format!("Expected {expected} but found {kind:?}"));
+        self.fail(id, ErrorKind::Custom(format!("Expected {expected} but found {kind:?}")));
     }
 
-    fn fail(&mut self, id: &Id, message: impl Into<String>) {
-        self.errs.push(Error { id: id.clone(), message: message.into() });
+    fn fail(&mut self, id: &Id, kind: ErrorKind) {
+        self.errs.push(Error { id: id.clone(), kind });
     }
 
     fn kind_of(&mut self, id: &Id) -> Option<Kind> {