Skip to content

Commit 5f1bc6f

Browse files
committed
jsondocck: Better errors
1 parent bb1911d commit 5f1bc6f

File tree

3 files changed

+70
-45
lines changed

3 files changed

+70
-45
lines changed

src/tools/jsondoclint/src/item_kind.rs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ pub(crate) enum Kind {
3131
Keyword,
3232
// Not in ItemKind
3333
ProcMacro,
34-
PrimitiveType,
3534
}
3635

3736
impl Kind {
@@ -54,13 +53,13 @@ impl Kind {
5453
Macro => true,
5554
ProcMacro => true,
5655

57-
ForeignType => todo!("IDK"),
58-
Keyword => todo!("IDK"),
59-
OpaqueTy => todo!("IDK"),
60-
Primitive => todo!("IDK"),
61-
PrimitiveType => todo!("IDK"),
62-
ProcAttribute => todo!("IDK"),
63-
ProcDerive => todo!("IDK"),
56+
// FIXME(adotinthevoid): I'm not sure if these are corrent
57+
ForeignType => false,
58+
Keyword => false,
59+
OpaqueTy => false,
60+
Primitive => false,
61+
ProcAttribute => false,
62+
ProcDerive => false,
6463

6564
// Only in traits
6665
AssocConst => false,
@@ -101,7 +100,6 @@ impl Kind {
101100
Kind::Primitive => false,
102101
Kind::Keyword => false,
103102
Kind::ProcMacro => false,
104-
Kind::PrimitiveType => false,
105103
}
106104
}
107105

@@ -139,7 +137,8 @@ impl Kind {
139137
ItemEnum::Static(_) => Static,
140138
ItemEnum::Macro(_) => Macro,
141139
ItemEnum::ProcMacro(_) => ProcMacro,
142-
ItemEnum::PrimitiveType(_) => PrimitiveType,
140+
// https://github.com/rust-lang/rust/issues/100961
141+
ItemEnum::PrimitiveType(_) => Primitive,
143142
ItemEnum::ForeignType => ForeignType,
144143
ItemEnum::ExternCrate { .. } => ExternCrate,
145144
ItemEnum::AssocConst { .. } => AssocConst,

src/tools/jsondoclint/src/main.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,16 @@ mod validator;
99

1010
#[derive(Debug)]
1111
struct Error {
12-
message: String,
12+
kind: ErrorKind,
1313
id: Id,
1414
}
1515

16+
#[derive(Debug)]
17+
enum ErrorKind {
18+
NotFound,
19+
Custom(String),
20+
}
21+
1622
fn main() -> Result<()> {
1723
let path = env::args().nth(1).ok_or_else(|| anyhow!("no path given"))?;
1824
let contents = fs::read_to_string(path)?;
@@ -24,7 +30,10 @@ fn main() -> Result<()> {
2430

2531
if !validator.errs.is_empty() {
2632
for err in validator.errs {
27-
eprintln!("`{}`: `{}`", err.id.0, err.message);
33+
match err.kind {
34+
ErrorKind::NotFound => eprintln!("{}: Not Found", err.id.0),
35+
ErrorKind::Custom(msg) => eprintln!("{}: {}", err.id.0, msg),
36+
}
2837
}
2938
bail!("Errors validating json");
3039
}

src/tools/jsondoclint/src/validator.rs

Lines changed: 50 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@ use rustdoc_json_types::{
88
TypeBindingKind, Typedef, Union, Variant, WherePredicate,
99
};
1010

11-
use crate::{item_kind::Kind, Error};
11+
use crate::{item_kind::Kind, Error, ErrorKind};
1212

1313
#[derive(Debug)]
1414
pub struct Validator<'a> {
1515
pub(crate) errs: Vec<Error>,
1616
krate: &'a Crate,
1717
seen_ids: HashSet<&'a Id>,
18+
missing_ids: HashSet<&'a Id>,
1819
todo: HashSet<&'a Id>,
1920
}
2021

@@ -29,7 +30,13 @@ fn set_remove<T: Hash + Eq + Clone>(set: &mut HashSet<T>) -> Option<T> {
2930

3031
impl<'a> Validator<'a> {
3132
pub fn new(krate: &'a Crate) -> Self {
32-
Self { krate, errs: Vec::new(), seen_ids: HashSet::new(), todo: HashSet::new() }
33+
Self {
34+
krate,
35+
errs: Vec::new(),
36+
seen_ids: HashSet::new(),
37+
todo: HashSet::new(),
38+
missing_ids: HashSet::new(),
39+
}
3340
}
3441

3542
pub fn check_crate(&mut self) {
@@ -42,32 +49,39 @@ impl<'a> Validator<'a> {
4249
}
4350

4451
fn check_item(&mut self, id: &'a Id) {
45-
let item = &self.krate.index[id];
46-
match &item.inner {
47-
ItemEnum::Import(x) => self.check_import(x),
48-
ItemEnum::Union(x) => self.check_union(x),
49-
ItemEnum::Struct(x) => self.check_struct(x),
50-
ItemEnum::StructField(x) => self.check_struct_field(x),
51-
ItemEnum::Enum(x) => self.check_enum(x),
52-
ItemEnum::Variant(x) => self.check_variant(x),
53-
ItemEnum::Function(x) => self.check_function(x),
54-
ItemEnum::Trait(x) => self.check_trait(x),
55-
ItemEnum::TraitAlias(x) => self.check_trait_alias(x),
56-
ItemEnum::Method(x) => self.check_method(x),
57-
ItemEnum::Impl(x) => self.check_impl(x),
58-
ItemEnum::Typedef(x) => self.check_typedef(x),
59-
ItemEnum::OpaqueTy(x) => self.check_opaque_ty(x),
60-
ItemEnum::Constant(x) => self.check_constant(x),
61-
ItemEnum::Static(x) => self.check_static(x),
62-
ItemEnum::ForeignType => todo!(),
63-
ItemEnum::Macro(x) => self.check_macro(x),
64-
ItemEnum::ProcMacro(x) => self.check_proc_macro(x),
65-
ItemEnum::PrimitiveType(x) => self.check_primitive_type(x),
66-
ItemEnum::Module(x) => self.check_module(x),
67-
68-
ItemEnum::ExternCrate { .. } => todo!(),
69-
ItemEnum::AssocConst { .. } => todo!(),
70-
ItemEnum::AssocType { .. } => todo!(),
52+
if let Some(item) = &self.krate.index.get(id) {
53+
match &item.inner {
54+
ItemEnum::Import(x) => self.check_import(x),
55+
ItemEnum::Union(x) => self.check_union(x),
56+
ItemEnum::Struct(x) => self.check_struct(x),
57+
ItemEnum::StructField(x) => self.check_struct_field(x),
58+
ItemEnum::Enum(x) => self.check_enum(x),
59+
ItemEnum::Variant(x) => self.check_variant(x),
60+
ItemEnum::Function(x) => self.check_function(x),
61+
ItemEnum::Trait(x) => self.check_trait(x),
62+
ItemEnum::TraitAlias(x) => self.check_trait_alias(x),
63+
ItemEnum::Method(x) => self.check_method(x),
64+
ItemEnum::Impl(x) => self.check_impl(x),
65+
ItemEnum::Typedef(x) => self.check_typedef(x),
66+
ItemEnum::OpaqueTy(x) => self.check_opaque_ty(x),
67+
ItemEnum::Constant(x) => self.check_constant(x),
68+
ItemEnum::Static(x) => self.check_static(x),
69+
ItemEnum::ForeignType => todo!(),
70+
ItemEnum::Macro(x) => self.check_macro(x),
71+
ItemEnum::ProcMacro(x) => self.check_proc_macro(x),
72+
ItemEnum::PrimitiveType(x) => self.check_primitive_type(x),
73+
ItemEnum::Module(x) => self.check_module(x),
74+
// FIXME: Why don't these have their own structs?
75+
ItemEnum::ExternCrate { .. } => {}
76+
ItemEnum::AssocConst { type_, default: _ } => self.check_type(type_),
77+
ItemEnum::AssocType { generics, bounds, default } => {
78+
self.check_generics(generics);
79+
bounds.iter().for_each(|b| self.check_generic_bound(b));
80+
if let Some(ty) = default {
81+
self.check_type(ty);
82+
}
83+
}
84+
}
7185
}
7286
}
7387

@@ -226,7 +240,7 @@ impl<'a> Validator<'a> {
226240
self.check_path(trait_);
227241
generic_params.iter().for_each(|gpd| self.check_generic_param_def(gpd));
228242
}
229-
GenericBound::Outlives(_) => todo!(),
243+
GenericBound::Outlives(_) => {}
230244
}
231245
}
232246

@@ -337,7 +351,10 @@ impl<'a> Validator<'a> {
337351
self.fail_expecting(id, expected);
338352
}
339353
} else {
340-
self.fail(id, "Not found")
354+
if !self.missing_ids.contains(id) {
355+
self.missing_ids.insert(id);
356+
self.fail(id, ErrorKind::NotFound)
357+
}
341358
}
342359
}
343360

@@ -368,11 +385,11 @@ impl<'a> Validator<'a> {
368385

369386
fn fail_expecting(&mut self, id: &Id, expected: &str) {
370387
let kind = self.kind_of(id).unwrap(); // We know it has a kind, as it's wrong.
371-
self.fail(id, format!("Expected {expected} but found {kind:?}"));
388+
self.fail(id, ErrorKind::Custom(format!("Expected {expected} but found {kind:?}")));
372389
}
373390

374-
fn fail(&mut self, id: &Id, message: impl Into<String>) {
375-
self.errs.push(Error { id: id.clone(), message: message.into() });
391+
fn fail(&mut self, id: &Id, kind: ErrorKind) {
392+
self.errs.push(Error { id: id.clone(), kind });
376393
}
377394

378395
fn kind_of(&mut self, id: &Id) -> Option<Kind> {

0 commit comments

Comments
 (0)