Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
2506aa0
jsondoclint: New Tool
aDotInTheVoid Aug 23, 2022
404b60b
Constify impl Fn* &(mut) Fn*
onestacked Sep 13, 2022
478c471
Added Tracking Issue number.
onestacked Sep 14, 2022
c5b9cb4
errors: add `emit_note`/`create_note`
davidtwco Sep 1, 2022
8a2f9c3
errors: implement `IntoDiagnosticArg` for `&T`
davidtwco Aug 30, 2022
ae51741
session: impl `IntoDiagnosticArg` for `CrateType`
davidtwco Aug 30, 2022
7d7cd17
errors: impl `IntoDiagnosticArg` for `TargetTriple`
davidtwco Aug 30, 2022
677d4d0
session: diagnostic migration lint on more fns
davidtwco Aug 19, 2022
b058e41
incremental: migrate diagnostics
davidtwco Aug 19, 2022
d7b9221
change AccessLevels representation
Bryanskiy Sep 12, 2022
a7a4fe9
jsondoclint: Tree Walk Validator
aDotInTheVoid Aug 24, 2022
bb1911d
jsondoclint: Add `Kind` abstraction
aDotInTheVoid Aug 24, 2022
5f1bc6f
jsondocck: Better errors
aDotInTheVoid Aug 24, 2022
41d35a9
jsondocck: Find path to Id's not in index
aDotInTheVoid Aug 24, 2022
c98c7cb
Primitives can appear in modules.
aDotInTheVoid Aug 30, 2022
5956b56
jsondoclint: Document validator
aDotInTheVoid Sep 14, 2022
393792d
Remove check_missing_items.py
aDotInTheVoid Sep 14, 2022
24c751b
Rustdoc-Json: Add test for extern_types
aDotInTheVoid Sep 14, 2022
6e21a28
jsondoclint: More precise `Path` checks
aDotInTheVoid Sep 14, 2022
f69a6c2
jsondoclint: Fix TODO's
aDotInTheVoid Sep 14, 2022
8df181d
Improve handing of env vars during bootstrap process
chriswailes Sep 13, 2022
4cdf264
cache collect_trait_impl_trait_tys
compiler-errors Sep 9, 2022
11e35f0
Rollup merge of #100754 - davidtwco:translation-incremental, r=compil…
Dylan-DPC Sep 15, 2022
8b283b9
Rollup merge of #101713 - Bryanskiy:AccessLevels, r=petrochenkov
Dylan-DPC Sep 15, 2022
3e7f24d
Rollup merge of #101783 - chriswailes:env-vars, r=jyn514
Dylan-DPC Sep 15, 2022
0ab8474
Rollup merge of #101787 - compiler-errors:cache-rpitit, r=petrochenkov
Dylan-DPC Sep 15, 2022
6e23b26
Rollup merge of #101802 - chriss0612:const_fn_trait_ref_impls, r=fee1…
Dylan-DPC Sep 15, 2022
a581bb7
Rollup merge of #101809 - aDotInTheVoid:jsondoclint, r=GuillaumeGomez
Dylan-DPC Sep 15, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
jsondoclint: Add Kind abstraction
  • Loading branch information
aDotInTheVoid committed Sep 14, 2022
commit bb1911db393047382ae040c23598e25984244644
205 changes: 178 additions & 27 deletions src/tools/jsondoclint/src/item_kind.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,180 @@
use rustdoc_json_types::ItemEnum;

pub(crate) fn can_appear_in_mod(kind: &ItemEnum) -> bool {
match kind {
ItemEnum::Module(_) => true,
ItemEnum::ExternCrate { .. } => true,
ItemEnum::Import(_) => true,
ItemEnum::Union(_) => true,
ItemEnum::Struct(_) => true,
ItemEnum::StructField(_) => false, // Only in structs or variants
ItemEnum::Enum(_) => true,
ItemEnum::Variant(_) => false, // Only in enums
ItemEnum::Function(_) => true,
ItemEnum::Trait(_) => true,
ItemEnum::TraitAlias(_) => true,
ItemEnum::Method(_) => false, // Only in traits
ItemEnum::Impl(_) => true,
ItemEnum::Typedef(_) => true,
ItemEnum::OpaqueTy(_) => todo!("IDK"), // On
ItemEnum::Constant(_) => true,
ItemEnum::Static(_) => true,
ItemEnum::ForeignType => todo!("IDK"),
ItemEnum::Macro(_) => true,
ItemEnum::ProcMacro(_) => true,
ItemEnum::PrimitiveType(_) => todo!("IDK"),
ItemEnum::AssocConst { .. } => false, // Trait Only
ItemEnum::AssocType { .. } => false, // Trait only
use rustdoc_json_types::{Item, ItemEnum, ItemKind, ItemSummary};

// We want a univeral way to represent an `ItemEnum` or `ItemKind`

#[derive(Debug)]
pub(crate) enum Kind {
Module,
ExternCrate,
Import,
Struct,
StructField,
Union,
Enum,
Variant,
Function,
Typedef,
OpaqueTy,
Constant,
Trait,
TraitAlias,
Method,
Impl,
Static,
ForeignType,
Macro,
ProcAttribute,
ProcDerive,
AssocConst,
AssocType,
Primitive,
Keyword,
// Not in ItemKind
ProcMacro,
PrimitiveType,
}

impl Kind {
pub fn can_appear_in_mod(self) -> bool {
use Kind::*;
match self {
Module => true,
ExternCrate => true,
Import => true,
Union => true,
Struct => true,
Enum => true,
Function => true,
Trait => true,
TraitAlias => true,
Impl => true,
Typedef => true,
Constant => true,
Static => true,
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"),

// Only in traits
AssocConst => false,
AssocType => false,
Method => false,

StructField => false, // Only in structs or variants
Variant => false, // Only in enums
}
}

pub fn can_appear_in_trait(self) -> bool {
match self {
Kind::AssocConst => true,
Kind::AssocType => true,
Kind::Method => true,

Kind::Module => false,
Kind::ExternCrate => false,
Kind::Import => false,
Kind::Struct => false,
Kind::StructField => false,
Kind::Union => false,
Kind::Enum => false,
Kind::Variant => false,
Kind::Function => false,
Kind::Typedef => false,
Kind::OpaqueTy => false,
Kind::Constant => false,
Kind::Trait => false,
Kind::TraitAlias => false,
Kind::Impl => false,
Kind::Static => false,
Kind::ForeignType => false,
Kind::Macro => false,
Kind::ProcAttribute => false,
Kind::ProcDerive => false,
Kind::Primitive => false,
Kind::Keyword => false,
Kind::ProcMacro => false,
Kind::PrimitiveType => false,
}
}

pub fn is_struct_field(self) -> bool {
matches!(self, Kind::StructField)
}
pub fn is_module(self) -> bool {
matches!(self, Kind::Module)
}
pub fn is_impl(self) -> bool {
matches!(self, Kind::Impl)
}
pub fn is_variant(self) -> bool {
matches!(self, Kind::Variant)
}

pub fn from_item(i: &Item) -> Self {
use Kind::*;
match i.inner {
ItemEnum::Module(_) => Module,
ItemEnum::Import(_) => Import,
ItemEnum::Union(_) => Union,
ItemEnum::Struct(_) => Struct,
ItemEnum::StructField(_) => StructField,
ItemEnum::Enum(_) => Enum,
ItemEnum::Variant(_) => Variant,
ItemEnum::Function(_) => Function,
ItemEnum::Trait(_) => Trait,
ItemEnum::TraitAlias(_) => TraitAlias,
ItemEnum::Method(_) => Method,
ItemEnum::Impl(_) => Impl,
ItemEnum::Typedef(_) => Typedef,
ItemEnum::OpaqueTy(_) => OpaqueTy,
ItemEnum::Constant(_) => Constant,
ItemEnum::Static(_) => Static,
ItemEnum::Macro(_) => Macro,
ItemEnum::ProcMacro(_) => ProcMacro,
ItemEnum::PrimitiveType(_) => PrimitiveType,
ItemEnum::ForeignType => ForeignType,
ItemEnum::ExternCrate { .. } => ExternCrate,
ItemEnum::AssocConst { .. } => AssocConst,
ItemEnum::AssocType { .. } => AssocType,
}
}

pub fn from_summary(s: &ItemSummary) -> Self {
use Kind::*;
match s.kind {
ItemKind::AssocConst => AssocConst,
ItemKind::AssocType => AssocType,
ItemKind::Constant => Constant,
ItemKind::Enum => Enum,
ItemKind::ExternCrate => ExternCrate,
ItemKind::ForeignType => ForeignType,
ItemKind::Function => Function,
ItemKind::Impl => Impl,
ItemKind::Import => Import,
ItemKind::Keyword => Keyword,
ItemKind::Macro => Macro,
ItemKind::Method => Method,
ItemKind::Module => Module,
ItemKind::OpaqueTy => OpaqueTy,
ItemKind::Primitive => Primitive,
ItemKind::ProcAttribute => ProcAttribute,
ItemKind::ProcDerive => ProcDerive,
ItemKind::Static => Static,
ItemKind::Struct => Struct,
ItemKind::StructField => StructField,
ItemKind::Trait => Trait,
ItemKind::TraitAlias => TraitAlias,
ItemKind::Typedef => Typedef,
ItemKind::Union => Union,
ItemKind::Variant => Variant,
}
}
}
74 changes: 35 additions & 39 deletions src/tools/jsondoclint/src/validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use rustdoc_json_types::{
TypeBindingKind, Typedef, Union, Variant, WherePredicate,
};

use crate::{item_kind::can_appear_in_mod, Error};
use crate::{item_kind::Kind, Error};

#[derive(Debug)]
pub struct Validator<'a> {
Expand Down Expand Up @@ -329,63 +329,59 @@ impl<'a> Validator<'a> {
}
}

fn add_field_id(&mut self, id: &'a Id) {
let item = &self.krate.index[id];
if let ItemEnum::StructField(_) = item.inner {
self.add_id(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);
} else {
self.fail_expecting(id, expected);
}
} else {
self.fail(id, "Expecting field");
self.fail(id, "Not found")
}
}

fn add_mod_id(&mut self, id: &'a Id) {
let item = &self.krate.index[id];
if let ItemEnum::Module(_) = item.inner {
self.add_id(id);
} else {
self.fail(id, "Expecting module");
}
fn add_field_id(&mut self, id: &'a Id) {
self.add_id_checked(id, Kind::is_struct_field, "StructField");
}

fn add_mod_id(&mut self, id: &'a Id) {
self.add_id_checked(id, Kind::is_module, "Module");
}
fn add_impl_id(&mut self, id: &'a Id) {
let item = &self.krate.index[id];
if let ItemEnum::StructField(_) = item.inner {
self.add_id(id);
} else {
self.fail(id, "Expecting impl");
}
self.add_id_checked(id, Kind::is_impl, "Impl");
}

fn add_variant_id(&mut self, id: &'a Id) {
let item = &self.krate.index[id];
if let ItemEnum::StructField(_) = item.inner {
self.add_id(id);
} else {
self.fail(id, "Expecting variant");
}
self.add_id_checked(id, Kind::is_variant, "Variant");
}

/// Add an Id that appeared in a trait
fn add_trait_item_id(&mut self, id: &'a Id) {
let item = &self.krate.index[id];
if !can_appear_in_mod(&item.inner) {
self.fail(id, "Expecting item that can appear in trait");
} else {
self.add_id(id);
}
self.add_id_checked(id, Kind::can_appear_in_trait, "Trait inner item");
}

/// Add an Id that appeared in a mod
fn add_mod_item_id(&mut self, id: &'a Id) {
let item = &self.krate.index[id];
if can_appear_in_mod(&item.inner) {
self.add_id(id);
} else {
self.fail(id, "Expecting item that can appear in trait");
}
self.add_id_checked(id, Kind::can_appear_in_mod, "Module inner item")
}

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:?}"));
}

fn fail(&mut self, id: &Id, msg: &str) {
self.errs.push(Error { id: id.clone(), message: msg.to_string() });
fn fail(&mut self, id: &Id, message: impl Into<String>) {
self.errs.push(Error { id: id.clone(), message: message.into() });
}

fn kind_of(&mut self, id: &Id) -> Option<Kind> {
if let Some(item) = self.krate.index.get(id) {
Some(Kind::from_item(item))
} else if let Some(summary) = self.krate.paths.get(id) {
Some(Kind::from_summary(summary))
} else {
None
}
}
}