Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove Item::kind, use tagged enum. Rename variants to match #82613

Merged
merged 5 commits into from
Mar 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4568,6 +4568,7 @@ name = "rustdoc-json-types"
version = "0.1.0"
dependencies = [
"serde",
"serde_json",
]

[[package]]
Expand Down
1 change: 1 addition & 0 deletions src/bootstrap/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,7 @@ impl<'a> Builder<'a> {
test::Crate,
test::CrateLibrustc,
test::CrateRustdoc,
test::CrateRustdocJsonTypes,
test::Linkcheck,
test::TierCheck,
test::Cargotest,
Expand Down
71 changes: 71 additions & 0 deletions src/bootstrap/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1922,6 +1922,77 @@ impl Step for CrateRustdoc {
}
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct CrateRustdocJsonTypes {
host: TargetSelection,
test_kind: TestKind,
}

impl Step for CrateRustdocJsonTypes {
type Output = ();
const DEFAULT: bool = true;
const ONLY_HOSTS: bool = true;

fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
run.path("src/rustdoc-json-types")
}

fn make_run(run: RunConfig<'_>) {
let builder = run.builder;

let test_kind = builder.kind.into();

builder.ensure(CrateRustdocJsonTypes { host: run.target, test_kind });
}

fn run(self, builder: &Builder<'_>) {
let test_kind = self.test_kind;
let target = self.host;

// Use the previous stage compiler to reuse the artifacts that are
// created when running compiletest for src/test/rustdoc. If this used
// `compiler`, then it would cause rustdoc to be built *again*, which
// isn't really necessary.
let compiler = builder.compiler_for(builder.top_stage, target, target);
builder.ensure(compile::Rustc { compiler, target });

let mut cargo = tool::prepare_tool_cargo(
builder,
compiler,
Mode::ToolRustc,
target,
test_kind.subcommand(),
"src/rustdoc-json-types",
SourceType::InTree,
&[],
);
if test_kind.subcommand() == "test" && !builder.fail_fast {
cargo.arg("--no-fail-fast");
}

cargo.arg("-p").arg("rustdoc-json-types");

cargo.arg("--");
cargo.args(&builder.config.cmd.test_args());

if self.host.contains("musl") {
cargo.arg("'-Ctarget-feature=-crt-static'");
}

if !builder.config.verbose_tests {
cargo.arg("--quiet");
}

builder.info(&format!(
"{} rustdoc-json-types stage{} ({} -> {})",
test_kind, compiler.stage, &compiler.host, target
));
let _time = util::timeit(&builder);

try_run(builder, &mut cargo.into());
}
}

/// Some test suites are run inside emulators or on remote devices, and most
/// of our test binaries are linked dynamically which means we need to ship
/// the standard library and such to the emulator ahead of time. This step
Expand Down
52 changes: 25 additions & 27 deletions src/librustdoc/json/conversions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ use std::collections::HashSet;

impl JsonRenderer<'_> {
pub(super) fn convert_item(&self, item: clean::Item) -> Option<Item> {
let item_type = ItemType::from(&item);
let deprecation = item.deprecation(self.tcx);
let clean::Item { source, name, attrs, kind, visibility, def_id } = item;
let inner = match *kind {
Expand All @@ -50,7 +49,6 @@ impl JsonRenderer<'_> {
.map(rustc_ast_pretty::pprust::attribute_to_string)
.collect(),
deprecation: deprecation.map(from_deprecation),
kind: item_type.into(),
inner,
})
}
Expand Down Expand Up @@ -154,38 +152,38 @@ crate fn from_def_id(did: DefId) -> Id {
fn from_clean_item_kind(item: clean::ItemKind, tcx: TyCtxt<'_>, name: &Option<Symbol>) -> ItemEnum {
use clean::ItemKind::*;
match item {
ModuleItem(m) => ItemEnum::ModuleItem(m.into()),
ImportItem(i) => ItemEnum::ImportItem(i.into()),
StructItem(s) => ItemEnum::StructItem(s.into()),
UnionItem(u) => ItemEnum::UnionItem(u.into()),
StructFieldItem(f) => ItemEnum::StructFieldItem(f.into()),
EnumItem(e) => ItemEnum::EnumItem(e.into()),
VariantItem(v) => ItemEnum::VariantItem(v.into()),
FunctionItem(f) => ItemEnum::FunctionItem(f.into()),
ForeignFunctionItem(f) => ItemEnum::FunctionItem(f.into()),
TraitItem(t) => ItemEnum::TraitItem(t.into()),
TraitAliasItem(t) => ItemEnum::TraitAliasItem(t.into()),
MethodItem(m, _) => ItemEnum::MethodItem(from_function_method(m, true)),
TyMethodItem(m) => ItemEnum::MethodItem(from_function_method(m, false)),
ImplItem(i) => ItemEnum::ImplItem(i.into()),
StaticItem(s) => ItemEnum::StaticItem(from_clean_static(s, tcx)),
ForeignStaticItem(s) => ItemEnum::StaticItem(from_clean_static(s, tcx)),
ForeignTypeItem => ItemEnum::ForeignTypeItem,
TypedefItem(t, _) => ItemEnum::TypedefItem(t.into()),
OpaqueTyItem(t) => ItemEnum::OpaqueTyItem(t.into()),
ConstantItem(c) => ItemEnum::ConstantItem(c.into()),
MacroItem(m) => ItemEnum::MacroItem(m.source),
ProcMacroItem(m) => ItemEnum::ProcMacroItem(m.into()),
AssocConstItem(t, s) => ItemEnum::AssocConstItem { type_: t.into(), default: s },
AssocTypeItem(g, t) => ItemEnum::AssocTypeItem {
ModuleItem(m) => ItemEnum::Module(m.into()),
ImportItem(i) => ItemEnum::Import(i.into()),
StructItem(s) => ItemEnum::Struct(s.into()),
UnionItem(u) => ItemEnum::Union(u.into()),
StructFieldItem(f) => ItemEnum::StructField(f.into()),
EnumItem(e) => ItemEnum::Enum(e.into()),
VariantItem(v) => ItemEnum::Variant(v.into()),
FunctionItem(f) => ItemEnum::Function(f.into()),
ForeignFunctionItem(f) => ItemEnum::Function(f.into()),
TraitItem(t) => ItemEnum::Trait(t.into()),
TraitAliasItem(t) => ItemEnum::TraitAlias(t.into()),
MethodItem(m, _) => ItemEnum::Method(from_function_method(m, true)),
TyMethodItem(m) => ItemEnum::Method(from_function_method(m, false)),
ImplItem(i) => ItemEnum::Impl(i.into()),
StaticItem(s) => ItemEnum::Static(from_clean_static(s, tcx)),
ForeignStaticItem(s) => ItemEnum::Static(from_clean_static(s, tcx)),
ForeignTypeItem => ItemEnum::ForeignType,
TypedefItem(t, _) => ItemEnum::Typedef(t.into()),
OpaqueTyItem(t) => ItemEnum::OpaqueTy(t.into()),
ConstantItem(c) => ItemEnum::Constant(c.into()),
MacroItem(m) => ItemEnum::Macro(m.source),
ProcMacroItem(m) => ItemEnum::ProcMacro(m.into()),
AssocConstItem(t, s) => ItemEnum::AssocConst { type_: t.into(), default: s },
AssocTypeItem(g, t) => ItemEnum::AssocType {
bounds: g.into_iter().map(Into::into).collect(),
default: t.map(Into::into),
},
StrippedItem(inner) => from_clean_item_kind(*inner, tcx, name),
PrimitiveItem(_) | KeywordItem(_) => {
panic!("{:?} is not supported for JSON output", item)
}
ExternCrateItem { ref src } => ItemEnum::ExternCrateItem {
ExternCrateItem { ref src } => ItemEnum::ExternCrate {
name: name.as_ref().unwrap().to_string(),
rename: src.map(|x| x.to_string()),
},
Expand Down
9 changes: 4 additions & 5 deletions src/librustdoc/json/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,7 @@ impl JsonRenderer<'tcx> {
.last()
.map(Clone::clone),
visibility: types::Visibility::Public,
kind: types::ItemKind::Trait,
inner: types::ItemEnum::TraitItem(trait_item.clone().into()),
inner: types::ItemEnum::Trait(trait_item.clone().into()),
source: None,
docs: Default::default(),
links: Default::default(),
Expand Down Expand Up @@ -158,11 +157,11 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {

let id = item.def_id;
if let Some(mut new_item) = self.convert_item(item) {
if let types::ItemEnum::TraitItem(ref mut t) = new_item.inner {
if let types::ItemEnum::Trait(ref mut t) = new_item.inner {
t.implementors = self.get_trait_implementors(id)
} else if let types::ItemEnum::StructItem(ref mut s) = new_item.inner {
} else if let types::ItemEnum::Struct(ref mut s) = new_item.inner {
s.impls = self.get_impls(id)
} else if let types::ItemEnum::EnumItem(ref mut e) = new_item.inner {
} else if let types::ItemEnum::Enum(ref mut e) = new_item.inner {
e.impls = self.get_impls(id)
}
let removed = self.index.borrow_mut().insert(from_def_id(id), new_item.clone());
Expand Down
3 changes: 3 additions & 0 deletions src/rustdoc-json-types/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,6 @@ path = "lib.rs"

[dependencies]
serde = { version = "1.0", features = ["derive"] }

[dev-dependencies]
serde_json = "1.0"
51 changes: 27 additions & 24 deletions src/rustdoc-json-types/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ pub struct Item {
/// Stringified versions of the attributes on this item (e.g. `"#[inline]"`)
pub attrs: Vec<String>,
pub deprecation: Option<Deprecation>,
pub kind: ItemKind,
#[serde(flatten)]
pub inner: ItemEnum,
}

Expand Down Expand Up @@ -185,48 +185,48 @@ pub enum ItemKind {
}

#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(untagged)]
#[serde(tag = "kind", content = "inner", rename_all = "snake_case")]
pub enum ItemEnum {
ModuleItem(Module),
ExternCrateItem {
Module(Module),
ExternCrate {
name: String,
rename: Option<String>,
},
ImportItem(Import),
Import(Import),

UnionItem(Union),
StructItem(Struct),
StructFieldItem(Type),
EnumItem(Enum),
VariantItem(Variant),
Union(Union),
Struct(Struct),
StructField(Type),
Enum(Enum),
Variant(Variant),

FunctionItem(Function),
Function(Function),

TraitItem(Trait),
TraitAliasItem(TraitAlias),
MethodItem(Method),
ImplItem(Impl),
Trait(Trait),
TraitAlias(TraitAlias),
Method(Method),
Impl(Impl),

TypedefItem(Typedef),
OpaqueTyItem(OpaqueTy),
ConstantItem(Constant),
Typedef(Typedef),
OpaqueTy(OpaqueTy),
Constant(Constant),

StaticItem(Static),
Static(Static),

/// `type`s from an extern block
ForeignTypeItem,
ForeignType,

/// Declarative macro_rules! macro
MacroItem(String),
ProcMacroItem(ProcMacro),
Macro(String),
ProcMacro(ProcMacro),

AssocConstItem {
AssocConst {
#[serde(rename = "type")]
type_: Type,
/// e.g. `const X: usize = 5;`
default: Option<String>,
},
AssocTypeItem {
AssocType {
bounds: Vec<GenericBound>,
/// e.g. `type X = usize;`
default: Option<Type>,
Expand Down Expand Up @@ -508,3 +508,6 @@ pub struct Static {
pub mutable: bool,
pub expr: String,
}

#[cfg(test)]
mod tests;
34 changes: 34 additions & 0 deletions src/rustdoc-json-types/tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
use super::*;

#[test]
fn test_struct_info_roundtrip() {
CraftSpider marked this conversation as resolved.
Show resolved Hide resolved
let s = ItemEnum::Struct(Struct {
struct_type: StructType::Plain,
generics: Generics { params: vec![], where_predicates: vec![] },
fields_stripped: false,
fields: vec![],
impls: vec![],
});

let struct_json = serde_json::to_string(&s).unwrap();

let de_s = serde_json::from_str(&struct_json).unwrap();

assert_eq!(s, de_s);
}

#[test]
fn test_union_info_roundtrip() {
let u = ItemEnum::Union(Union {
generics: Generics { params: vec![], where_predicates: vec![] },
fields_stripped: false,
fields: vec![],
impls: vec![],
});

let union_json = serde_json::to_string(&u).unwrap();

let de_u = serde_json::from_str(&union_json).unwrap();

assert_eq!(u, de_u);
}