jsondoclint: Document validator

This commit is contained in:
Nixon Enraght-Moony 2022-09-14 14:47:25 +01:00
parent c98c7cbfa5
commit 5956b56ab2
3 changed files with 30 additions and 23 deletions

View File

@ -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,

View File

@ -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[..] {

View File

@ -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
}
}