]> git.lizzy.rs Git - rust.git/commitdiff
Split JSON into separately versioned crate
authorRune Tynan <runetynan@gmail.com>
Fri, 22 Jan 2021 21:09:24 +0000 (16:09 -0500)
committerRune Tynan <runetynan@gmail.com>
Wed, 27 Jan 2021 23:56:57 +0000 (18:56 -0500)
Cargo.toml
src/librustdoc/Cargo.toml
src/librustdoc/json-types/Cargo.toml [new file with mode: 0644]
src/librustdoc/json-types/lib.rs [new file with mode: 0644]
src/librustdoc/json/conversions.rs
src/librustdoc/json/mod.rs
src/librustdoc/json/types.rs [deleted file]

index 5bd1147cad55425b693b4118e5326cb210e8ab29..5b58ed8f6a05020fc01af1f32b4e45330d97f2ba 100644 (file)
@@ -4,6 +4,7 @@ members = [
   "compiler/rustc",
   "library/std",
   "library/test",
+  "src/librustdoc/json-types",
   "src/tools/cargotest",
   "src/tools/clippy",
   "src/tools/compiletest",
index b0f5bac6abd0fc069d431fef32ddc4733697a1bd..bc6eba74d2d48a1095d98c2f60af92bebfe78257 100644 (file)
@@ -17,6 +17,7 @@ smallvec = "1.0"
 tempfile = "3"
 itertools = "0.9"
 regex = "1"
+json-types = { path = "./json-types" }
 
 [dev-dependencies]
 expect-test = "1.0"
diff --git a/src/librustdoc/json-types/Cargo.toml b/src/librustdoc/json-types/Cargo.toml
new file mode 100644 (file)
index 0000000..b9c97c3
--- /dev/null
@@ -0,0 +1,11 @@
+[package]
+name = "json-types"
+version = "0.1.0"
+authors = ["The Rust Project Developers"]
+edition = "2018"
+
+[lib]
+path = "lib.rs"
+
+[dependencies]
+serde = { version = "1.0", features = ["derive"] }
diff --git a/src/librustdoc/json-types/lib.rs b/src/librustdoc/json-types/lib.rs
new file mode 100644 (file)
index 0000000..3fb2a32
--- /dev/null
@@ -0,0 +1,492 @@
+//! Rustdoc's JSON output interface
+//!
+//! These types are the public API exposed through the `--output-format json` flag. The [`Crate`]
+//! struct is the root of the JSON blob and all other items are contained within.
+
+use std::collections::HashMap;
+use std::path::PathBuf;
+
+use serde::{Deserialize, Serialize};
+
+/// A `Crate` is the root of the emitted JSON blob. It contains all type/documentation information
+/// about the language items in the local crate, as well as info about external items to allow
+/// tools to find or link to them.
+#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
+pub struct Crate {
+    /// The id of the root [`Module`] item of the local crate.
+    pub root: Id,
+    /// The version string given to `--crate-version`, if any.
+    pub crate_version: Option<String>,
+    /// Whether or not the output includes private items.
+    pub includes_private: bool,
+    /// A collection of all items in the local crate as well as some external traits and their
+    /// items that are referenced locally.
+    pub index: HashMap<Id, Item>,
+    /// Maps IDs to fully qualified paths and other info helpful for generating links.
+    pub paths: HashMap<Id, ItemSummary>,
+    /// Maps `crate_id` of items to a crate name and html_root_url if it exists.
+    pub external_crates: HashMap<u32, ExternalCrate>,
+    /// A single version number to be used in the future when making backwards incompatible changes
+    /// to the JSON output.
+    pub format_version: u32,
+}
+
+#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
+pub struct ExternalCrate {
+    pub name: String,
+    pub html_root_url: Option<String>,
+}
+
+/// For external (not defined in the local crate) items, you don't get the same level of
+/// information. This struct should contain enough to generate a link/reference to the item in
+/// question, or can be used by a tool that takes the json output of multiple crates to find
+/// the actual item definition with all the relevant info.
+#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
+pub struct ItemSummary {
+    /// Can be used to look up the name and html_root_url of the crate this item came from in the
+    /// `external_crates` map.
+    pub crate_id: u32,
+    /// The list of path components for the fully qualified path of this item (e.g.
+    /// `["std", "io", "lazy", "Lazy"]` for `std::io::lazy::Lazy`).
+    pub path: Vec<String>,
+    /// Whether this item is a struct, trait, macro, etc.
+    pub kind: ItemKind,
+}
+
+#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
+pub struct Item {
+    /// The unique identifier of this item. Can be used to find this item in various mappings.
+    pub id: Id,
+    /// This can be used as a key to the `external_crates` map of [`Crate`] to see which crate
+    /// this item came from.
+    pub crate_id: u32,
+    /// Some items such as impls don't have names.
+    pub name: Option<String>,
+    /// The source location of this item (absent if it came from a macro expansion or inline
+    /// assembly).
+    pub source: Option<Span>,
+    /// By default all documented items are public, but you can tell rustdoc to output private items
+    /// so this field is needed to differentiate.
+    pub visibility: Visibility,
+    /// The full markdown docstring of this item. Absent if there is no documentation at all,
+    /// Some("") if there is some documentation but it is empty (EG `#[doc = ""]`).
+    pub docs: Option<String>,
+    /// This mapping resolves [intra-doc links](https://github.com/rust-lang/rfcs/blob/master/text/1946-intra-rustdoc-links.md) from the docstring to their IDs
+    pub links: HashMap<String, Id>,
+    /// Stringified versions of the attributes on this item (e.g. `"#[inline]"`)
+    pub attrs: Vec<String>,
+    pub deprecation: Option<Deprecation>,
+    pub kind: ItemKind,
+    pub inner: ItemEnum,
+}
+
+#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
+pub struct Span {
+    /// The path to the source file for this span relative to the path `rustdoc` was invoked with.
+    pub filename: PathBuf,
+    /// Zero indexed Line and Column of the first character of the `Span`
+    pub begin: (usize, usize),
+    /// Zero indexed Line and Column of the last character of the `Span`
+    pub end: (usize, usize),
+}
+
+#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
+pub struct Deprecation {
+    pub since: Option<String>,
+    pub note: Option<String>,
+}
+
+#[serde(rename_all = "snake_case")]
+#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
+pub enum Visibility {
+    Public,
+    /// For the most part items are private by default. The exceptions are associated items of
+    /// public traits and variants of public enums.
+    Default,
+    Crate,
+    /// For `pub(in path)` visibility. `parent` is the module it's restricted to and `path` is how
+    /// that module was referenced (like `"super::super"` or `"crate::foo::bar"`).
+    Restricted {
+        parent: Id,
+        path: String,
+    },
+}
+
+#[serde(rename_all = "snake_case")]
+#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
+pub enum GenericArgs {
+    /// <'a, 32, B: Copy, C = u32>
+    AngleBracketed { args: Vec<GenericArg>, bindings: Vec<TypeBinding> },
+    /// Fn(A, B) -> C
+    Parenthesized { inputs: Vec<Type>, output: Option<Type> },
+}
+
+#[serde(rename_all = "snake_case")]
+#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
+pub enum GenericArg {
+    Lifetime(String),
+    Type(Type),
+    Const(Constant),
+}
+
+#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
+pub struct Constant {
+    #[serde(rename = "type")]
+    pub type_: Type,
+    pub expr: String,
+    pub value: Option<String>,
+    pub is_literal: bool,
+}
+
+#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
+pub struct TypeBinding {
+    pub name: String,
+    pub binding: TypeBindingKind,
+}
+
+#[serde(rename_all = "snake_case")]
+#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
+pub enum TypeBindingKind {
+    Equality(Type),
+    Constraint(Vec<GenericBound>),
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
+pub struct Id(pub String);
+
+#[serde(rename_all = "snake_case")]
+#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
+pub enum ItemKind {
+    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,
+}
+
+#[serde(untagged)]
+#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
+pub enum ItemEnum {
+    ModuleItem(Module),
+    ExternCrateItem {
+        name: String,
+        rename: Option<String>,
+    },
+    ImportItem(Import),
+
+    StructItem(Struct),
+    StructFieldItem(Type),
+    EnumItem(Enum),
+    VariantItem(Variant),
+
+    FunctionItem(Function),
+
+    TraitItem(Trait),
+    TraitAliasItem(TraitAlias),
+    MethodItem(Method),
+    ImplItem(Impl),
+
+    TypedefItem(Typedef),
+    OpaqueTyItem(OpaqueTy),
+    ConstantItem(Constant),
+
+    StaticItem(Static),
+
+    /// `type`s from an extern block
+    ForeignTypeItem,
+
+    /// Declarative macro_rules! macro
+    MacroItem(String),
+    ProcMacroItem(ProcMacro),
+
+    AssocConstItem {
+        #[serde(rename = "type")]
+        type_: Type,
+        /// e.g. `const X: usize = 5;`
+        default: Option<String>,
+    },
+    AssocTypeItem {
+        bounds: Vec<GenericBound>,
+        /// e.g. `type X = usize;`
+        default: Option<Type>,
+    },
+}
+
+#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
+pub struct Module {
+    pub is_crate: bool,
+    pub items: Vec<Id>,
+}
+
+#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
+pub struct Struct {
+    pub struct_type: StructType,
+    pub generics: Generics,
+    pub fields_stripped: bool,
+    pub fields: Vec<Id>,
+    pub impls: Vec<Id>,
+}
+
+#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
+pub struct Enum {
+    pub generics: Generics,
+    pub variants_stripped: bool,
+    pub variants: Vec<Id>,
+    pub impls: Vec<Id>,
+}
+
+#[serde(rename_all = "snake_case")]
+#[serde(tag = "variant_kind", content = "variant_inner")]
+#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
+pub enum Variant {
+    Plain,
+    Tuple(Vec<Type>),
+    Struct(Vec<Id>),
+}
+
+#[serde(rename_all = "snake_case")]
+#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
+pub enum StructType {
+    Plain,
+    Tuple,
+    Unit,
+    Union,
+}
+
+#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
+pub struct Function {
+    pub decl: FnDecl,
+    pub generics: Generics,
+    pub header: String,
+    pub abi: String,
+}
+
+#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
+pub struct Method {
+    pub decl: FnDecl,
+    pub generics: Generics,
+    pub header: String,
+    pub has_body: bool,
+}
+
+#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq)]
+pub struct Generics {
+    pub params: Vec<GenericParamDef>,
+    pub where_predicates: Vec<WherePredicate>,
+}
+
+#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
+pub struct GenericParamDef {
+    pub name: String,
+    pub kind: GenericParamDefKind,
+}
+
+#[serde(rename_all = "snake_case")]
+#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
+pub enum GenericParamDefKind {
+    Lifetime,
+    Type { bounds: Vec<GenericBound>, default: Option<Type> },
+    Const(Type),
+}
+
+#[serde(rename_all = "snake_case")]
+#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
+pub enum WherePredicate {
+    BoundPredicate { ty: Type, bounds: Vec<GenericBound> },
+    RegionPredicate { lifetime: String, bounds: Vec<GenericBound> },
+    EqPredicate { lhs: Type, rhs: Type },
+}
+
+#[serde(rename_all = "snake_case")]
+#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
+pub enum GenericBound {
+    TraitBound {
+        #[serde(rename = "trait")]
+        trait_: Type,
+        /// Used for HRTBs
+        generic_params: Vec<GenericParamDef>,
+        modifier: TraitBoundModifier,
+    },
+    Outlives(String),
+}
+
+#[serde(rename_all = "snake_case")]
+#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
+pub enum TraitBoundModifier {
+    None,
+    Maybe,
+    MaybeConst,
+}
+
+#[serde(rename_all = "snake_case")]
+#[serde(tag = "kind", content = "inner")]
+#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
+pub enum Type {
+    /// Structs, enums, and traits
+    ResolvedPath {
+        name: String,
+        id: Id,
+        args: Option<Box<GenericArgs>>,
+        param_names: Vec<GenericBound>,
+    },
+    /// Parameterized types
+    Generic(String),
+    /// Fixed-size numeric types (plus int/usize/float), char, arrays, slices, and tuples
+    Primitive(String),
+    /// `extern "ABI" fn`
+    FunctionPointer(Box<FunctionPointer>),
+    /// `(String, u32, Box<usize>)`
+    Tuple(Vec<Type>),
+    /// `[u32]`
+    Slice(Box<Type>),
+    /// [u32; 15]
+    Array {
+        #[serde(rename = "type")]
+        type_: Box<Type>,
+        len: String,
+    },
+    /// `impl TraitA + TraitB + ...`
+    ImplTrait(Vec<GenericBound>),
+    /// `!`
+    Never,
+    /// `_`
+    Infer,
+    /// `*mut u32`, `*u8`, etc.
+    RawPointer {
+        mutable: bool,
+        #[serde(rename = "type")]
+        type_: Box<Type>,
+    },
+    /// `&'a mut String`, `&str`, etc.
+    BorrowedRef {
+        lifetime: Option<String>,
+        mutable: bool,
+        #[serde(rename = "type")]
+        type_: Box<Type>,
+    },
+    /// `<Type as Trait>::Name` or associated types like `T::Item` where `T: Iterator`
+    QualifiedPath {
+        name: String,
+        self_type: Box<Type>,
+        #[serde(rename = "trait")]
+        trait_: Box<Type>,
+    },
+}
+
+#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
+pub struct FunctionPointer {
+    pub is_unsafe: bool,
+    pub generic_params: Vec<GenericParamDef>,
+    pub decl: FnDecl,
+    pub abi: String,
+}
+
+#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
+pub struct FnDecl {
+    pub inputs: Vec<(String, Type)>,
+    pub output: Option<Type>,
+    pub c_variadic: bool,
+}
+
+#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
+pub struct Trait {
+    pub is_auto: bool,
+    pub is_unsafe: bool,
+    pub items: Vec<Id>,
+    pub generics: Generics,
+    pub bounds: Vec<GenericBound>,
+    pub implementors: Vec<Id>,
+}
+
+#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
+pub struct TraitAlias {
+    pub generics: Generics,
+    pub params: Vec<GenericBound>,
+}
+
+#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
+pub struct Impl {
+    pub is_unsafe: bool,
+    pub generics: Generics,
+    pub provided_trait_methods: Vec<String>,
+    #[serde(rename = "trait")]
+    pub trait_: Option<Type>,
+    #[serde(rename = "for")]
+    pub for_: Type,
+    pub items: Vec<Id>,
+    pub negative: bool,
+    pub synthetic: bool,
+    pub blanket_impl: Option<Type>,
+}
+
+#[serde(rename_all = "snake_case")]
+#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
+pub struct Import {
+    /// The full path being imported.
+    pub span: String,
+    /// May be different from the last segment of `source` when renaming imports:
+    /// `use source as name;`
+    pub name: String,
+    /// The ID of the item being imported.
+    pub id: Option<Id>, // FIXME is this actually ever None?
+    /// Whether this import uses a glob: `use source::*;`
+    pub glob: bool,
+}
+
+#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
+pub struct ProcMacro {
+    pub kind: MacroKind,
+    pub helpers: Vec<String>,
+}
+
+#[serde(rename_all = "snake_case")]
+#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
+pub enum MacroKind {
+    /// A bang macro `foo!()`.
+    Bang,
+    /// An attribute macro `#[foo]`.
+    Attr,
+    /// A derive macro `#[derive(Foo)]`
+    Derive,
+}
+
+#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
+pub struct Typedef {
+    #[serde(rename = "type")]
+    pub type_: Type,
+    pub generics: Generics,
+}
+
+#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
+pub struct OpaqueTy {
+    pub bounds: Vec<GenericBound>,
+    pub generics: Generics,
+}
+
+#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
+pub struct Static {
+    #[serde(rename = "type")]
+    pub type_: Type,
+    pub mutable: bool,
+    pub expr: String,
+}
index bfd2141d9a1745214d423700b77f5e2176e69ed0..9b0603c4d55ba59d7b6d40d057a5d1090d33d042 100644 (file)
@@ -9,9 +9,10 @@
 use rustc_span::def_id::{DefId, CRATE_DEF_INDEX};
 use rustc_span::Pos;
 
+use json_types::*;
+
 use crate::clean;
 use crate::formats::item_type::ItemType;
-use crate::json::types::*;
 use crate::json::JsonRenderer;
 
 impl JsonRenderer<'_> {
@@ -22,7 +23,7 @@ pub(super) fn convert_item(&self, item: clean::Item) -> Option<Item> {
         match *kind {
             clean::StrippedItem(_) => None,
             kind => Some(Item {
-                id: def_id.into(),
+                id: from_def_id(def_id),
                 crate_id: def_id.krate.as_u32(),
                 name: name.map(|sym| sym.to_string()),
                 source: self.convert_span(source),
@@ -32,7 +33,7 @@ pub(super) fn convert_item(&self, item: clean::Item) -> Option<Item> {
                     .links
                     .into_iter()
                     .filter_map(|clean::ItemLink { link, did, .. }| {
-                        did.map(|did| (link, did.into()))
+                        did.map(|did| (link, from_def_id(did)))
                     })
                     .collect(),
                 attrs: attrs
@@ -40,7 +41,7 @@ pub(super) fn convert_item(&self, item: clean::Item) -> Option<Item> {
                     .iter()
                     .map(rustc_ast_pretty::pprust::attribute_to_string)
                     .collect(),
-                deprecation: deprecation.map(Into::into),
+                deprecation: deprecation.map(from_deprecation),
                 kind: item_type.into(),
                 inner: kind.into(),
             }),
@@ -74,19 +75,17 @@ fn convert_visibility(&self, v: clean::Visibility) -> Visibility {
             Inherited => Visibility::Default,
             Restricted(did) if did.index == CRATE_DEF_INDEX => Visibility::Crate,
             Restricted(did) => Visibility::Restricted {
-                parent: did.into(),
+                parent: from_def_id(did),
                 path: self.tcx.def_path(did).to_string_no_crate_verbose(),
             },
         }
     }
 }
 
-impl From<rustc_attr::Deprecation> for Deprecation {
-    fn from(deprecation: rustc_attr::Deprecation) -> Self {
-        #[rustfmt::skip]
-        let rustc_attr::Deprecation { since, note, is_since_rustc_version: _, suggestion: _ } = deprecation;
-        Deprecation { since: since.map(|s| s.to_string()), note: note.map(|s| s.to_string()) }
-    }
+crate fn from_deprecation(deprecation: rustc_attr::Deprecation) -> Deprecation {
+    #[rustfmt::skip]
+    let rustc_attr::Deprecation { since, note, is_since_rustc_version: _, suggestion: _ } = deprecation;
+    Deprecation { since: since.map(|s| s.to_string()), note: note.map(|s| s.to_string()) }
 }
 
 impl From<clean::GenericArgs> for GenericArgs {
@@ -141,10 +140,8 @@ fn from(kind: clean::TypeBindingKind) -> Self {
     }
 }
 
-impl From<DefId> for Id {
-    fn from(did: DefId) -> Self {
-        Id(format!("{}:{}", did.krate.as_u32(), u32::from(did.index)))
-    }
+crate fn from_def_id(did: DefId) -> Id {
+    Id(format!("{}:{}", did.krate.as_u32(), u32::from(did.index)))
 }
 
 impl From<clean::ItemKind> for ItemEnum {
@@ -199,7 +196,7 @@ impl From<clean::Struct> for Struct {
     fn from(struct_: clean::Struct) -> Self {
         let clean::Struct { struct_type, generics, fields, fields_stripped } = struct_;
         Struct {
-            struct_type: struct_type.into(),
+            struct_type: from_ctor_kind(struct_type),
             generics: generics.into(),
             fields_stripped,
             fields: ids(fields),
@@ -221,13 +218,11 @@ fn from(struct_: clean::Union) -> Self {
     }
 }
 
-impl From<CtorKind> for StructType {
-    fn from(struct_type: CtorKind) -> Self {
-        match struct_type {
-            CtorKind::Fictive => StructType::Plain,
-            CtorKind::Fn => StructType::Tuple,
-            CtorKind::Const => StructType::Unit,
-        }
+crate fn from_ctor_kind(struct_type: CtorKind) -> StructType {
+    match struct_type {
+        CtorKind::Fictive => StructType::Plain,
+        CtorKind::Fn => StructType::Tuple,
+        CtorKind::Const => StructType::Unit,
     }
 }
 
@@ -310,7 +305,7 @@ fn from(bound: clean::GenericBound) -> Self {
                 GenericBound::TraitBound {
                     trait_: trait_.into(),
                     generic_params: generic_params.into_iter().map(Into::into).collect(),
-                    modifier: modifier.into(),
+                    modifier: from_trait_bound_modifier(modifier),
                 }
             }
             Outlives(lifetime) => GenericBound::Outlives(lifetime.0.to_string()),
@@ -318,14 +313,12 @@ fn from(bound: clean::GenericBound) -> Self {
     }
 }
 
-impl From<rustc_hir::TraitBoundModifier> for TraitBoundModifier {
-    fn from(modifier: rustc_hir::TraitBoundModifier) -> Self {
-        use rustc_hir::TraitBoundModifier::*;
-        match modifier {
-            None => TraitBoundModifier::None,
-            Maybe => TraitBoundModifier::Maybe,
-            MaybeConst => TraitBoundModifier::MaybeConst,
-        }
+crate fn from_trait_bound_modifier(modifier: rustc_hir::TraitBoundModifier) -> TraitBoundModifier {
+    use rustc_hir::TraitBoundModifier::*;
+    match modifier {
+        None => TraitBoundModifier::None,
+        Maybe => TraitBoundModifier::Maybe,
+        MaybeConst => TraitBoundModifier::MaybeConst,
     }
 }
 
@@ -335,7 +328,7 @@ fn from(ty: clean::Type) -> Self {
         match ty {
             ResolvedPath { path, param_names, did, is_generic: _ } => Type::ResolvedPath {
                 name: path.whole_name(),
-                id: did.into(),
+                id: from_def_id(did),
                 args: path.segments.last().map(|args| Box::new(args.clone().args.into())),
                 param_names: param_names
                     .map(|v| v.into_iter().map(Into::into).collect())
@@ -470,7 +463,7 @@ impl From<clean::VariantStruct> for Struct {
     fn from(struct_: clean::VariantStruct) -> Self {
         let clean::VariantStruct { struct_type, fields, fields_stripped } = struct_;
         Struct {
-            struct_type: struct_type.into(),
+            struct_type: from_ctor_kind(struct_type),
             generics: Default::default(),
             fields_stripped,
             fields: ids(fields),
@@ -497,13 +490,13 @@ fn from(import: clean::Import) -> Self {
             Simple(s) => Import {
                 span: import.source.path.whole_name(),
                 name: s.to_string(),
-                id: import.source.did.map(Into::into),
+                id: import.source.did.map(from_def_id),
                 glob: false,
             },
             Glob => Import {
                 span: import.source.path.whole_name(),
                 name: import.source.path.last_name().to_string(),
-                id: import.source.did.map(Into::into),
+                id: import.source.did.map(from_def_id),
                 glob: true,
             },
         }
@@ -513,20 +506,18 @@ fn from(import: clean::Import) -> Self {
 impl From<clean::ProcMacro> for ProcMacro {
     fn from(mac: clean::ProcMacro) -> Self {
         ProcMacro {
-            kind: mac.kind.into(),
+            kind: from_macro_kind(mac.kind),
             helpers: mac.helpers.iter().map(|x| x.to_string()).collect(),
         }
     }
 }
 
-impl From<rustc_span::hygiene::MacroKind> for MacroKind {
-    fn from(kind: rustc_span::hygiene::MacroKind) -> Self {
-        use rustc_span::hygiene::MacroKind::*;
-        match kind {
-            Bang => MacroKind::Bang,
-            Attr => MacroKind::Attr,
-            Derive => MacroKind::Derive,
-        }
+crate fn from_macro_kind(kind: rustc_span::hygiene::MacroKind) -> MacroKind {
+    use rustc_span::hygiene::MacroKind::*;
+    match kind {
+        Bang => MacroKind::Bang,
+        Attr => MacroKind::Attr,
+        Derive => MacroKind::Derive,
     }
 }
 
@@ -599,5 +590,5 @@ fn from(kind: ItemType) -> Self {
 }
 
 fn ids(items: impl IntoIterator<Item = clean::Item>) -> Vec<Id> {
-    items.into_iter().filter(|x| !x.is_stripped()).map(|i| i.def_id.into()).collect()
+    items.into_iter().filter(|x| !x.is_stripped()).map(|i| from_def_id(i.def_id)).collect()
 }
index a8a4b74b818b617c9d60de33ce44e931efc3c708..7d4d5598c6b9b0ea5afeb3200312502c9ef9fd6a 100644 (file)
@@ -5,7 +5,6 @@
 //! docs for usage and details.
 
 mod conversions;
-pub mod types;
 
 use std::cell::RefCell;
 use std::fs::File;
 use rustc_session::Session;
 use rustc_span::edition::Edition;
 
+use json_types as types;
+
 use crate::clean;
 use crate::config::{RenderInfo, RenderOptions};
 use crate::error::Error;
 use crate::formats::cache::Cache;
 use crate::formats::FormatRenderer;
 use crate::html::render::cache::ExternalLocation;
+use crate::json::conversions::from_def_id;
 
 #[derive(Clone)]
 crate struct JsonRenderer<'tcx> {
@@ -50,7 +52,7 @@ fn get_trait_implementors(&mut self, id: rustc_span::def_id::DefId) -> Vec<types
                     .map(|i| {
                         let item = &i.impl_item;
                         self.item(item.clone()).unwrap();
-                        item.def_id.into()
+                        from_def_id(item.def_id)
                     })
                     .collect()
             })
@@ -68,7 +70,7 @@ fn get_impls(&mut self, id: rustc_span::def_id::DefId) -> Vec<types::Id> {
                         let item = &i.impl_item;
                         if item.def_id.is_local() {
                             self.item(item.clone()).unwrap();
-                            Some(item.def_id.into())
+                            Some(from_def_id(item.def_id))
                         } else {
                             None
                         }
@@ -87,9 +89,9 @@ fn get_trait_items(&mut self) -> Vec<(types::Id, types::Item)> {
                 if !id.is_local() {
                     trait_item.items.clone().into_iter().for_each(|i| self.item(i).unwrap());
                     Some((
-                        id.into(),
+                        from_def_id(id),
                         types::Item {
-                            id: id.into(),
+                            id: from_def_id(id),
                             crate_id: id.krate.as_u32(),
                             name: self
                                 .cache
@@ -163,7 +165,7 @@ fn item(&mut self, item: clean::Item) -> Result<(), Error> {
             } else if let types::ItemEnum::EnumItem(ref mut e) = new_item.inner {
                 e.impls = self.get_impls(id)
             }
-            let removed = self.index.borrow_mut().insert(id.into(), new_item.clone());
+            let removed = self.index.borrow_mut().insert(from_def_id(id), new_item.clone());
             // FIXME(adotinthevoid): Currently, the index is duplicated. This is a sanity check
             // to make sure the items are unique.
             if let Some(old_item) = removed {
@@ -203,11 +205,18 @@ fn after_krate(
         debug!("Done with crate");
         let mut index = (*self.index).clone().into_inner();
         index.extend(self.get_trait_items());
+        let len = index.len();
         let output = types::Crate {
             root: types::Id(String::from("0:0")),
             crate_version: krate.version.clone(),
             includes_private: self.cache.document_private,
-            index,
+            index: index.into_iter().fold(
+                std::collections::HashMap::with_capacity(len),
+                |mut acc, (key, val)| {
+                    acc.insert(key, val);
+                    acc
+                },
+            ),
             paths: self
                 .cache
                 .paths
@@ -216,7 +225,7 @@ fn after_krate(
                 .chain(self.cache.external_paths.clone().into_iter())
                 .map(|(k, (path, kind))| {
                     (
-                        k.into(),
+                        from_def_id(k),
                         types::ItemSummary { crate_id: k.krate.as_u32(), path, kind: kind.into() },
                     )
                 })
diff --git a/src/librustdoc/json/types.rs b/src/librustdoc/json/types.rs
deleted file mode 100644 (file)
index 66cf129..0000000
+++ /dev/null
@@ -1,492 +0,0 @@
-//! Rustdoc's JSON output interface
-//!
-//! These types are the public API exposed through the `--output-format json` flag. The [`Crate`]
-//! struct is the root of the JSON blob and all other items are contained within.
-
-use std::path::PathBuf;
-
-use rustc_data_structures::fx::FxHashMap;
-use serde::{Deserialize, Serialize};
-
-/// A `Crate` is the root of the emitted JSON blob. It contains all type/documentation information
-/// about the language items in the local crate, as well as info about external items to allow
-/// tools to find or link to them.
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
-pub struct Crate {
-    /// The id of the root [`Module`] item of the local crate.
-    pub root: Id,
-    /// The version string given to `--crate-version`, if any.
-    pub crate_version: Option<String>,
-    /// Whether or not the output includes private items.
-    pub includes_private: bool,
-    /// A collection of all items in the local crate as well as some external traits and their
-    /// items that are referenced locally.
-    pub index: FxHashMap<Id, Item>,
-    /// Maps IDs to fully qualified paths and other info helpful for generating links.
-    pub paths: FxHashMap<Id, ItemSummary>,
-    /// Maps `crate_id` of items to a crate name and html_root_url if it exists.
-    pub external_crates: FxHashMap<u32, ExternalCrate>,
-    /// A single version number to be used in the future when making backwards incompatible changes
-    /// to the JSON output.
-    pub format_version: u32,
-}
-
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
-pub struct ExternalCrate {
-    pub name: String,
-    pub html_root_url: Option<String>,
-}
-
-/// For external (not defined in the local crate) items, you don't get the same level of
-/// information. This struct should contain enough to generate a link/reference to the item in
-/// question, or can be used by a tool that takes the json output of multiple crates to find
-/// the actual item definition with all the relevant info.
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
-pub struct ItemSummary {
-    /// Can be used to look up the name and html_root_url of the crate this item came from in the
-    /// `external_crates` map.
-    pub crate_id: u32,
-    /// The list of path components for the fully qualified path of this item (e.g.
-    /// `["std", "io", "lazy", "Lazy"]` for `std::io::lazy::Lazy`).
-    pub path: Vec<String>,
-    /// Whether this item is a struct, trait, macro, etc.
-    pub kind: ItemKind,
-}
-
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
-pub struct Item {
-    /// The unique identifier of this item. Can be used to find this item in various mappings.
-    pub id: Id,
-    /// This can be used as a key to the `external_crates` map of [`Crate`] to see which crate
-    /// this item came from.
-    pub crate_id: u32,
-    /// Some items such as impls don't have names.
-    pub name: Option<String>,
-    /// The source location of this item (absent if it came from a macro expansion or inline
-    /// assembly).
-    pub source: Option<Span>,
-    /// By default all documented items are public, but you can tell rustdoc to output private items
-    /// so this field is needed to differentiate.
-    pub visibility: Visibility,
-    /// The full markdown docstring of this item. Absent if there is no documentation at all,
-    /// Some("") if there is some documentation but it is empty (EG `#[doc = ""]`).
-    pub docs: Option<String>,
-    /// This mapping resolves [intra-doc links](https://github.com/rust-lang/rfcs/blob/master/text/1946-intra-rustdoc-links.md) from the docstring to their IDs
-    pub links: FxHashMap<String, Id>,
-    /// Stringified versions of the attributes on this item (e.g. `"#[inline]"`)
-    pub attrs: Vec<String>,
-    pub deprecation: Option<Deprecation>,
-    pub kind: ItemKind,
-    pub inner: ItemEnum,
-}
-
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
-pub struct Span {
-    /// The path to the source file for this span relative to the path `rustdoc` was invoked with.
-    pub filename: PathBuf,
-    /// Zero indexed Line and Column of the first character of the `Span`
-    pub begin: (usize, usize),
-    /// Zero indexed Line and Column of the last character of the `Span`
-    pub end: (usize, usize),
-}
-
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
-pub struct Deprecation {
-    pub since: Option<String>,
-    pub note: Option<String>,
-}
-
-#[serde(rename_all = "snake_case")]
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
-pub enum Visibility {
-    Public,
-    /// For the most part items are private by default. The exceptions are associated items of
-    /// public traits and variants of public enums.
-    Default,
-    Crate,
-    /// For `pub(in path)` visibility. `parent` is the module it's restricted to and `path` is how
-    /// that module was referenced (like `"super::super"` or `"crate::foo::bar"`).
-    Restricted {
-        parent: Id,
-        path: String,
-    },
-}
-
-#[serde(rename_all = "snake_case")]
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
-pub enum GenericArgs {
-    /// <'a, 32, B: Copy, C = u32>
-    AngleBracketed { args: Vec<GenericArg>, bindings: Vec<TypeBinding> },
-    /// Fn(A, B) -> C
-    Parenthesized { inputs: Vec<Type>, output: Option<Type> },
-}
-
-#[serde(rename_all = "snake_case")]
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
-pub enum GenericArg {
-    Lifetime(String),
-    Type(Type),
-    Const(Constant),
-}
-
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
-pub struct Constant {
-    #[serde(rename = "type")]
-    pub type_: Type,
-    pub expr: String,
-    pub value: Option<String>,
-    pub is_literal: bool,
-}
-
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
-pub struct TypeBinding {
-    pub name: String,
-    pub binding: TypeBindingKind,
-}
-
-#[serde(rename_all = "snake_case")]
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
-pub enum TypeBindingKind {
-    Equality(Type),
-    Constraint(Vec<GenericBound>),
-}
-
-#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
-pub struct Id(pub String);
-
-#[serde(rename_all = "snake_case")]
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
-pub enum ItemKind {
-    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,
-}
-
-#[serde(untagged)]
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
-pub enum ItemEnum {
-    ModuleItem(Module),
-    ExternCrateItem {
-        name: String,
-        rename: Option<String>,
-    },
-    ImportItem(Import),
-
-    StructItem(Struct),
-    StructFieldItem(Type),
-    EnumItem(Enum),
-    VariantItem(Variant),
-
-    FunctionItem(Function),
-
-    TraitItem(Trait),
-    TraitAliasItem(TraitAlias),
-    MethodItem(Method),
-    ImplItem(Impl),
-
-    TypedefItem(Typedef),
-    OpaqueTyItem(OpaqueTy),
-    ConstantItem(Constant),
-
-    StaticItem(Static),
-
-    /// `type`s from an extern block
-    ForeignTypeItem,
-
-    /// Declarative macro_rules! macro
-    MacroItem(String),
-    ProcMacroItem(ProcMacro),
-
-    AssocConstItem {
-        #[serde(rename = "type")]
-        type_: Type,
-        /// e.g. `const X: usize = 5;`
-        default: Option<String>,
-    },
-    AssocTypeItem {
-        bounds: Vec<GenericBound>,
-        /// e.g. `type X = usize;`
-        default: Option<Type>,
-    },
-}
-
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
-pub struct Module {
-    pub is_crate: bool,
-    pub items: Vec<Id>,
-}
-
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
-pub struct Struct {
-    pub struct_type: StructType,
-    pub generics: Generics,
-    pub fields_stripped: bool,
-    pub fields: Vec<Id>,
-    pub impls: Vec<Id>,
-}
-
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
-pub struct Enum {
-    pub generics: Generics,
-    pub variants_stripped: bool,
-    pub variants: Vec<Id>,
-    pub impls: Vec<Id>,
-}
-
-#[serde(rename_all = "snake_case")]
-#[serde(tag = "variant_kind", content = "variant_inner")]
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
-pub enum Variant {
-    Plain,
-    Tuple(Vec<Type>),
-    Struct(Vec<Id>),
-}
-
-#[serde(rename_all = "snake_case")]
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
-pub enum StructType {
-    Plain,
-    Tuple,
-    Unit,
-    Union,
-}
-
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
-pub struct Function {
-    pub decl: FnDecl,
-    pub generics: Generics,
-    pub header: String,
-    pub abi: String,
-}
-
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
-pub struct Method {
-    pub decl: FnDecl,
-    pub generics: Generics,
-    pub header: String,
-    pub has_body: bool,
-}
-
-#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq)]
-pub struct Generics {
-    pub params: Vec<GenericParamDef>,
-    pub where_predicates: Vec<WherePredicate>,
-}
-
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
-pub struct GenericParamDef {
-    pub name: String,
-    pub kind: GenericParamDefKind,
-}
-
-#[serde(rename_all = "snake_case")]
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
-pub enum GenericParamDefKind {
-    Lifetime,
-    Type { bounds: Vec<GenericBound>, default: Option<Type> },
-    Const(Type),
-}
-
-#[serde(rename_all = "snake_case")]
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
-pub enum WherePredicate {
-    BoundPredicate { ty: Type, bounds: Vec<GenericBound> },
-    RegionPredicate { lifetime: String, bounds: Vec<GenericBound> },
-    EqPredicate { lhs: Type, rhs: Type },
-}
-
-#[serde(rename_all = "snake_case")]
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
-pub enum GenericBound {
-    TraitBound {
-        #[serde(rename = "trait")]
-        trait_: Type,
-        /// Used for HRTBs
-        generic_params: Vec<GenericParamDef>,
-        modifier: TraitBoundModifier,
-    },
-    Outlives(String),
-}
-
-#[serde(rename_all = "snake_case")]
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
-pub enum TraitBoundModifier {
-    None,
-    Maybe,
-    MaybeConst,
-}
-
-#[serde(rename_all = "snake_case")]
-#[serde(tag = "kind", content = "inner")]
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
-pub enum Type {
-    /// Structs, enums, and traits
-    ResolvedPath {
-        name: String,
-        id: Id,
-        args: Option<Box<GenericArgs>>,
-        param_names: Vec<GenericBound>,
-    },
-    /// Parameterized types
-    Generic(String),
-    /// Fixed-size numeric types (plus int/usize/float), char, arrays, slices, and tuples
-    Primitive(String),
-    /// `extern "ABI" fn`
-    FunctionPointer(Box<FunctionPointer>),
-    /// `(String, u32, Box<usize>)`
-    Tuple(Vec<Type>),
-    /// `[u32]`
-    Slice(Box<Type>),
-    /// [u32; 15]
-    Array {
-        #[serde(rename = "type")]
-        type_: Box<Type>,
-        len: String,
-    },
-    /// `impl TraitA + TraitB + ...`
-    ImplTrait(Vec<GenericBound>),
-    /// `!`
-    Never,
-    /// `_`
-    Infer,
-    /// `*mut u32`, `*u8`, etc.
-    RawPointer {
-        mutable: bool,
-        #[serde(rename = "type")]
-        type_: Box<Type>,
-    },
-    /// `&'a mut String`, `&str`, etc.
-    BorrowedRef {
-        lifetime: Option<String>,
-        mutable: bool,
-        #[serde(rename = "type")]
-        type_: Box<Type>,
-    },
-    /// `<Type as Trait>::Name` or associated types like `T::Item` where `T: Iterator`
-    QualifiedPath {
-        name: String,
-        self_type: Box<Type>,
-        #[serde(rename = "trait")]
-        trait_: Box<Type>,
-    },
-}
-
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
-pub struct FunctionPointer {
-    pub is_unsafe: bool,
-    pub generic_params: Vec<GenericParamDef>,
-    pub decl: FnDecl,
-    pub abi: String,
-}
-
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
-pub struct FnDecl {
-    pub inputs: Vec<(String, Type)>,
-    pub output: Option<Type>,
-    pub c_variadic: bool,
-}
-
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
-pub struct Trait {
-    pub is_auto: bool,
-    pub is_unsafe: bool,
-    pub items: Vec<Id>,
-    pub generics: Generics,
-    pub bounds: Vec<GenericBound>,
-    pub implementors: Vec<Id>,
-}
-
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
-pub struct TraitAlias {
-    pub generics: Generics,
-    pub params: Vec<GenericBound>,
-}
-
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
-pub struct Impl {
-    pub is_unsafe: bool,
-    pub generics: Generics,
-    pub provided_trait_methods: Vec<String>,
-    #[serde(rename = "trait")]
-    pub trait_: Option<Type>,
-    #[serde(rename = "for")]
-    pub for_: Type,
-    pub items: Vec<Id>,
-    pub negative: bool,
-    pub synthetic: bool,
-    pub blanket_impl: Option<Type>,
-}
-
-#[serde(rename_all = "snake_case")]
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
-pub struct Import {
-    /// The full path being imported.
-    pub span: String,
-    /// May be different from the last segment of `source` when renaming imports:
-    /// `use source as name;`
-    pub name: String,
-    /// The ID of the item being imported.
-    pub id: Option<Id>, // FIXME is this actually ever None?
-    /// Whether this import uses a glob: `use source::*;`
-    pub glob: bool,
-}
-
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
-pub struct ProcMacro {
-    pub kind: MacroKind,
-    pub helpers: Vec<String>,
-}
-
-#[serde(rename_all = "snake_case")]
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
-pub enum MacroKind {
-    /// A bang macro `foo!()`.
-    Bang,
-    /// An attribute macro `#[foo]`.
-    Attr,
-    /// A derive macro `#[derive(Foo)]`
-    Derive,
-}
-
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
-pub struct Typedef {
-    #[serde(rename = "type")]
-    pub type_: Type,
-    pub generics: Generics,
-}
-
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
-pub struct OpaqueTy {
-    pub bounds: Vec<GenericBound>,
-    pub generics: Generics,
-}
-
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
-pub struct Static {
-    #[serde(rename = "type")]
-    pub type_: Type,
-    pub mutable: bool,
-    pub expr: String,
-}