1
Fork 0

jsondoclint: More precise Path checks

This commit is contained in:
Nixon Enraght-Moony 2022-09-14 15:31:45 +01:00
parent 24c751b2ba
commit 6e21a28dda
2 changed files with 29 additions and 14 deletions

View file

@ -114,6 +114,12 @@ impl Kind {
pub fn is_variant(self) -> bool { pub fn is_variant(self) -> bool {
matches!(self, Kind::Variant) matches!(self, Kind::Variant)
} }
pub fn is_trait(self) -> bool {
matches!(self, Kind::Trait)
}
pub fn is_struct_enum_union(self) -> bool {
matches!(self, Kind::Struct | Kind::Enum | Kind::Union)
}
pub fn from_item(i: &Item) -> Self { pub fn from_item(i: &Item) -> Self {
use Kind::*; use Kind::*;

View file

@ -30,6 +30,11 @@ pub struct Validator<'a> {
missing_ids: HashSet<&'a Id>, missing_ids: HashSet<&'a Id>,
} }
enum PathKind {
Trait,
StructEnumUnion,
}
impl<'a> Validator<'a> { impl<'a> Validator<'a> {
pub fn new(krate: &'a Crate) -> Self { pub fn new(krate: &'a Crate) -> Self {
Self { Self {
@ -165,7 +170,7 @@ impl<'a> Validator<'a> {
fn check_impl(&mut self, x: &'a Impl) { fn check_impl(&mut self, x: &'a Impl) {
self.check_generics(&x.generics); self.check_generics(&x.generics);
if let Some(path) = &x.trait_ { if let Some(path) = &x.trait_ {
self.check_path(path); // TODO: Check is trait. self.check_path(path, PathKind::Trait);
} }
self.check_type(&x.for_); self.check_type(&x.for_);
x.items.iter().for_each(|i| self.add_trait_item_id(i)); x.items.iter().for_each(|i| self.add_trait_item_id(i));
@ -211,7 +216,7 @@ impl<'a> Validator<'a> {
fn check_type(&mut self, x: &'a Type) { fn check_type(&mut self, x: &'a Type) {
match x { match x {
Type::ResolvedPath(path) => self.check_path(path), Type::ResolvedPath(path) => self.check_path(path, PathKind::StructEnumUnion),
Type::DynTrait(dyn_trait) => self.check_dyn_trait(dyn_trait), Type::DynTrait(dyn_trait) => self.check_dyn_trait(dyn_trait),
Type::Generic(_) => {} Type::Generic(_) => {}
Type::Primitive(_) => {} Type::Primitive(_) => {}
@ -226,7 +231,7 @@ impl<'a> Validator<'a> {
Type::QualifiedPath { name: _, args, self_type, trait_ } => { Type::QualifiedPath { name: _, args, self_type, trait_ } => {
self.check_generic_args(&**args); self.check_generic_args(&**args);
self.check_type(&**self_type); self.check_type(&**self_type);
self.check_path(trait_); self.check_path(trait_, PathKind::Trait);
} }
} }
} }
@ -241,15 +246,18 @@ impl<'a> Validator<'a> {
fn check_generic_bound(&mut self, x: &'a GenericBound) { fn check_generic_bound(&mut self, x: &'a GenericBound) {
match x { match x {
GenericBound::TraitBound { trait_, generic_params, modifier: _ } => { GenericBound::TraitBound { trait_, generic_params, modifier: _ } => {
self.check_path(trait_); self.check_path(trait_, PathKind::Trait);
generic_params.iter().for_each(|gpd| self.check_generic_param_def(gpd)); generic_params.iter().for_each(|gpd| self.check_generic_param_def(gpd));
} }
GenericBound::Outlives(_) => {} GenericBound::Outlives(_) => {}
} }
} }
fn check_path(&mut self, x: &'a Path) { fn check_path(&mut self, x: &'a Path, kind: PathKind) {
self.add_id(&x.id); // TODO: What kinds are allowed here. match kind {
PathKind::Trait => self.add_trait_id(&x.id),
PathKind::StructEnumUnion => self.add_struct_enum_union_id(&x.id),
}
if let Some(args) = &x.args { if let Some(args) = &x.args {
self.check_generic_args(&**args); self.check_generic_args(&**args);
} }
@ -330,7 +338,7 @@ impl<'a> Validator<'a> {
fn check_dyn_trait(&mut self, dyn_trait: &'a DynTrait) { fn check_dyn_trait(&mut self, dyn_trait: &'a DynTrait) {
for pt in &dyn_trait.traits { for pt in &dyn_trait.traits {
self.check_path(&pt.trait_); self.check_path(&pt.trait_, PathKind::Trait);
pt.generic_params.iter().for_each(|gpd| self.check_generic_param_def(gpd)); pt.generic_params.iter().for_each(|gpd| self.check_generic_param_def(gpd));
} }
} }
@ -340,13 +348,6 @@ impl<'a> Validator<'a> {
fp.generic_params.iter().for_each(|gpd| self.check_generic_param_def(gpd)); fp.generic_params.iter().for_each(|gpd| self.check_generic_param_def(gpd));
} }
// TODO: Remove
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) { fn add_id_checked(&mut self, id: &'a Id, valid: fn(Kind) -> bool, expected: &str) {
if let Some(kind) = self.kind_of(id) { if let Some(kind) = self.kind_of(id) {
if valid(kind) { if valid(kind) {
@ -379,6 +380,14 @@ impl<'a> Validator<'a> {
self.add_id_checked(id, Kind::is_variant, "Variant"); self.add_id_checked(id, Kind::is_variant, "Variant");
} }
fn add_trait_id(&mut self, id: &'a Id) {
self.add_id_checked(id, Kind::is_trait, "Trait");
}
fn add_struct_enum_union_id(&mut self, id: &'a Id) {
self.add_id_checked(id, Kind::is_struct_enum_union, "Struct or Enum or Union");
}
/// Add an Id that appeared in a trait /// Add an Id that appeared in a trait
fn add_trait_item_id(&mut self, id: &'a Id) { fn add_trait_item_id(&mut self, id: &'a Id) {
self.add_id_checked(id, Kind::can_appear_in_trait, "Trait inner item"); self.add_id_checked(id, Kind::can_appear_in_trait, "Trait inner item");