jsondoclint: Document validator
This commit is contained in:
parent
c98c7cbfa5
commit
5956b56ab2
@ -1,7 +1,6 @@
|
||||
use rustdoc_json_types::{Item, ItemEnum, ItemKind, ItemSummary};
|
||||
|
||||
// We want a univeral way to represent an `ItemEnum` or `ItemKind`
|
||||
|
||||
/// A univeral way to represent an [`ItemEnum`] or [`ItemKind`]
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum Kind {
|
||||
Module,
|
||||
|
@ -25,8 +25,6 @@ fn main() -> Result<()> {
|
||||
let path = env::args().nth(1).ok_or_else(|| anyhow!("no path given"))?;
|
||||
let contents = fs::read_to_string(&path)?;
|
||||
let krate: Crate = serde_json::from_str(&contents)?;
|
||||
// TODO: Only load if nessessary.
|
||||
let krate_json: Value = serde_json::from_str(&contents)?;
|
||||
assert_eq!(krate.format_version, FORMAT_VERSION);
|
||||
|
||||
let mut validator = validator::Validator::new(&krate);
|
||||
@ -36,6 +34,8 @@ fn main() -> Result<()> {
|
||||
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[..] {
|
||||
|
@ -10,22 +10,24 @@
|
||||
|
||||
use crate::{item_kind::Kind, Error, ErrorKind};
|
||||
|
||||
/// The Validator walks over the JSON tree, and ensures it is well formed.
|
||||
/// It is made of several parts.
|
||||
///
|
||||
/// - `check_*`: These take a type from [`rustdoc_json_types`], and check that
|
||||
/// it is well formed. This involves calling `check_*` functions on
|
||||
/// fields of that item, and `add_*` functions on [`Id`]s.
|
||||
/// - `add_*`: These add an [`Id`] to the worklist, after validating it to check if
|
||||
/// the `Id` is a kind expected in this suituation.
|
||||
#[derive(Debug)]
|
||||
pub struct Validator<'a> {
|
||||
pub(crate) errs: Vec<Error>,
|
||||
krate: &'a Crate,
|
||||
seen_ids: HashSet<&'a Id>,
|
||||
missing_ids: HashSet<&'a Id>,
|
||||
/// Worklist of Ids to check.
|
||||
todo: HashSet<&'a Id>,
|
||||
}
|
||||
|
||||
fn set_remove<T: Hash + Eq + Clone>(set: &mut HashSet<T>) -> Option<T> {
|
||||
if let Some(id) = set.iter().next() {
|
||||
let id = id.clone();
|
||||
set.take(&id)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
/// Ids that have already been visited, so don't need to be checked again.
|
||||
seen_ids: HashSet<&'a Id>,
|
||||
/// Ids that have already been reported missing.
|
||||
missing_ids: HashSet<&'a Id>,
|
||||
}
|
||||
|
||||
impl<'a> Validator<'a> {
|
||||
@ -82,6 +84,8 @@ fn check_item(&mut self, id: &'a Id) {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
assert!(self.krate.paths.contains_key(id));
|
||||
}
|
||||
}
|
||||
|
||||
@ -336,17 +340,12 @@ fn check_function_pointer(&mut self, fp: &'a FunctionPointer) {
|
||||
fp.generic_params.iter().for_each(|gpd| self.check_generic_param_def(gpd));
|
||||
}
|
||||
|
||||
// Aux functions
|
||||
fn add_id(&mut self, id: &'a Id) {
|
||||
if !self.seen_ids.contains(id) {
|
||||
self.todo.insert(id);
|
||||
}
|
||||
}
|
||||
|
||||
fn add_id_checked(&mut self, id: &'a Id, valid: fn(Kind) -> bool, expected: &str) {
|
||||
if let Some(kind) = self.kind_of(id) {
|
||||
if valid(kind) {
|
||||
self.add_id(id);
|
||||
if !self.seen_ids.contains(id) {
|
||||
self.todo.insert(id);
|
||||
}
|
||||
} else {
|
||||
self.fail_expecting(id, expected);
|
||||
}
|
||||
@ -402,3 +401,12 @@ fn kind_of(&mut self, id: &Id) -> Option<Kind> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn set_remove<T: Hash + Eq + Clone>(set: &mut HashSet<T>) -> Option<T> {
|
||||
if let Some(id) = set.iter().next() {
|
||||
let id = id.clone();
|
||||
set.take(&id)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user