]>
Commit | Line | Data |
---|---|---|
fc512014 XL |
1 | //! These from impls are used to create the JSON types which get serialized. They're very close to |
2 | //! the `clean` types but with some fields removed or stringified to simplify the output and not | |
3 | //! expose unstable compiler internals. | |
4 | ||
6a06907d XL |
5 | #![allow(rustc::default_hash_types)] |
6 | ||
fc512014 | 7 | use std::convert::From; |
136023e0 | 8 | use std::fmt; |
fc512014 XL |
9 | |
10 | use rustc_ast::ast; | |
136023e0 | 11 | use rustc_hir::{def::CtorKind, def_id::DefId}; |
6a06907d | 12 | use rustc_middle::ty::TyCtxt; |
17df50a5 | 13 | use rustc_span::def_id::CRATE_DEF_INDEX; |
fc512014 XL |
14 | use rustc_span::Pos; |
15 | ||
5869c6ff XL |
16 | use rustdoc_json_types::*; |
17 | ||
6a06907d | 18 | use crate::clean::utils::print_const_expr; |
136023e0 | 19 | use crate::clean::{self, ItemId}; |
fc512014 | 20 | use crate::formats::item_type::ItemType; |
fc512014 | 21 | use crate::json::JsonRenderer; |
6a06907d | 22 | use std::collections::HashSet; |
fc512014 XL |
23 | |
24 | impl JsonRenderer<'_> { | |
25 | pub(super) fn convert_item(&self, item: clean::Item) -> Option<Item> { | |
fc512014 | 26 | let deprecation = item.deprecation(self.tcx); |
cdc7bbd5 XL |
27 | let links = self |
28 | .cache | |
29 | .intra_doc_links | |
30 | .get(&item.def_id) | |
31 | .into_iter() | |
32 | .flatten() | |
33 | .filter_map(|clean::ItemLink { link, did, .. }| { | |
136023e0 | 34 | did.map(|did| (link.clone(), from_item_id(did.into()))) |
cdc7bbd5 XL |
35 | }) |
36 | .collect(); | |
37 | let docs = item.attrs.collapsed_doc_value(); | |
38 | let attrs = item | |
39 | .attrs | |
40 | .other_attrs | |
41 | .iter() | |
42 | .map(rustc_ast_pretty::pprust::attribute_to_string) | |
43 | .collect(); | |
44 | let span = item.span(self.tcx); | |
45 | let clean::Item { name, attrs: _, kind: _, visibility, def_id, cfg: _ } = item; | |
46 | let inner = match *item.kind { | |
6a06907d | 47 | clean::StrippedItem(_) => return None, |
cdc7bbd5 | 48 | _ => from_clean_item(item, self.tcx), |
6a06907d XL |
49 | }; |
50 | Some(Item { | |
136023e0 | 51 | id: from_item_id(def_id), |
17df50a5 | 52 | crate_id: def_id.krate().as_u32(), |
6a06907d | 53 | name: name.map(|sym| sym.to_string()), |
cdc7bbd5 | 54 | span: self.convert_span(span), |
6a06907d | 55 | visibility: self.convert_visibility(visibility), |
cdc7bbd5 XL |
56 | docs, |
57 | attrs, | |
6a06907d XL |
58 | deprecation: deprecation.map(from_deprecation), |
59 | inner, | |
cdc7bbd5 | 60 | links, |
6a06907d | 61 | }) |
fc512014 XL |
62 | } |
63 | ||
64 | fn convert_span(&self, span: clean::Span) -> Option<Span> { | |
65 | match span.filename(self.sess()) { | |
66 | rustc_span::FileName::Real(name) => { | |
17df50a5 XL |
67 | if let Some(local_path) = name.into_local_path() { |
68 | let hi = span.hi(self.sess()); | |
69 | let lo = span.lo(self.sess()); | |
70 | Some(Span { | |
71 | filename: local_path, | |
72 | begin: (lo.line, lo.col.to_usize()), | |
73 | end: (hi.line, hi.col.to_usize()), | |
74 | }) | |
75 | } else { | |
76 | None | |
77 | } | |
fc512014 XL |
78 | } |
79 | _ => None, | |
80 | } | |
81 | } | |
82 | ||
83 | fn convert_visibility(&self, v: clean::Visibility) -> Visibility { | |
84 | use clean::Visibility::*; | |
85 | match v { | |
86 | Public => Visibility::Public, | |
87 | Inherited => Visibility::Default, | |
88 | Restricted(did) if did.index == CRATE_DEF_INDEX => Visibility::Crate, | |
89 | Restricted(did) => Visibility::Restricted { | |
136023e0 | 90 | parent: from_item_id(did.into()), |
fc512014 XL |
91 | path: self.tcx.def_path(did).to_string_no_crate_verbose(), |
92 | }, | |
93 | } | |
94 | } | |
95 | } | |
96 | ||
cdc7bbd5 XL |
97 | crate trait FromWithTcx<T> { |
98 | fn from_tcx(f: T, tcx: TyCtxt<'_>) -> Self; | |
99 | } | |
100 | ||
101 | crate trait IntoWithTcx<T> { | |
102 | fn into_tcx(self, tcx: TyCtxt<'_>) -> T; | |
103 | } | |
104 | ||
105 | impl<T, U> IntoWithTcx<U> for T | |
106 | where | |
107 | U: FromWithTcx<T>, | |
108 | { | |
109 | fn into_tcx(self, tcx: TyCtxt<'_>) -> U { | |
110 | U::from_tcx(self, tcx) | |
111 | } | |
112 | } | |
113 | ||
5869c6ff XL |
114 | crate fn from_deprecation(deprecation: rustc_attr::Deprecation) -> Deprecation { |
115 | #[rustfmt::skip] | |
116 | let rustc_attr::Deprecation { since, note, is_since_rustc_version: _, suggestion: _ } = deprecation; | |
117 | Deprecation { since: since.map(|s| s.to_string()), note: note.map(|s| s.to_string()) } | |
fc512014 XL |
118 | } |
119 | ||
cdc7bbd5 XL |
120 | impl FromWithTcx<clean::GenericArgs> for GenericArgs { |
121 | fn from_tcx(args: clean::GenericArgs, tcx: TyCtxt<'_>) -> Self { | |
fc512014 XL |
122 | use clean::GenericArgs::*; |
123 | match args { | |
124 | AngleBracketed { args, bindings } => GenericArgs::AngleBracketed { | |
cdc7bbd5 XL |
125 | args: args.into_iter().map(|a| a.into_tcx(tcx)).collect(), |
126 | bindings: bindings.into_iter().map(|a| a.into_tcx(tcx)).collect(), | |
fc512014 XL |
127 | }, |
128 | Parenthesized { inputs, output } => GenericArgs::Parenthesized { | |
cdc7bbd5 | 129 | inputs: inputs.into_iter().map(|a| a.into_tcx(tcx)).collect(), |
94222f64 | 130 | output: output.map(|a| (*a).into_tcx(tcx)), |
fc512014 XL |
131 | }, |
132 | } | |
133 | } | |
134 | } | |
135 | ||
cdc7bbd5 XL |
136 | impl FromWithTcx<clean::GenericArg> for GenericArg { |
137 | fn from_tcx(arg: clean::GenericArg, tcx: TyCtxt<'_>) -> Self { | |
fc512014 XL |
138 | use clean::GenericArg::*; |
139 | match arg { | |
140 | Lifetime(l) => GenericArg::Lifetime(l.0.to_string()), | |
cdc7bbd5 XL |
141 | Type(t) => GenericArg::Type(t.into_tcx(tcx)), |
142 | Const(c) => GenericArg::Const(c.into_tcx(tcx)), | |
94222f64 | 143 | Infer => GenericArg::Infer, |
fc512014 XL |
144 | } |
145 | } | |
146 | } | |
147 | ||
cdc7bbd5 XL |
148 | impl FromWithTcx<clean::Constant> for Constant { |
149 | fn from_tcx(constant: clean::Constant, tcx: TyCtxt<'_>) -> Self { | |
150 | let expr = constant.expr(tcx); | |
151 | let value = constant.value(tcx); | |
152 | let is_literal = constant.is_literal(tcx); | |
153 | Constant { type_: constant.type_.into_tcx(tcx), expr, value, is_literal } | |
fc512014 XL |
154 | } |
155 | } | |
156 | ||
cdc7bbd5 XL |
157 | impl FromWithTcx<clean::TypeBinding> for TypeBinding { |
158 | fn from_tcx(binding: clean::TypeBinding, tcx: TyCtxt<'_>) -> Self { | |
159 | TypeBinding { name: binding.name.to_string(), binding: binding.kind.into_tcx(tcx) } | |
fc512014 XL |
160 | } |
161 | } | |
162 | ||
cdc7bbd5 XL |
163 | impl FromWithTcx<clean::TypeBindingKind> for TypeBindingKind { |
164 | fn from_tcx(kind: clean::TypeBindingKind, tcx: TyCtxt<'_>) -> Self { | |
fc512014 XL |
165 | use clean::TypeBindingKind::*; |
166 | match kind { | |
cdc7bbd5 | 167 | Equality { ty } => TypeBindingKind::Equality(ty.into_tcx(tcx)), |
fc512014 | 168 | Constraint { bounds } => { |
cdc7bbd5 | 169 | TypeBindingKind::Constraint(bounds.into_iter().map(|a| a.into_tcx(tcx)).collect()) |
fc512014 XL |
170 | } |
171 | } | |
172 | } | |
173 | } | |
174 | ||
136023e0 XL |
175 | crate fn from_item_id(did: ItemId) -> Id { |
176 | struct DisplayDefId(DefId); | |
177 | ||
178 | impl fmt::Display for DisplayDefId { | |
179 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
180 | write!(f, "{}:{}", self.0.krate.as_u32(), u32::from(self.0.index)) | |
181 | } | |
182 | } | |
183 | ||
17df50a5 | 184 | match did { |
136023e0 XL |
185 | ItemId::DefId(did) => Id(format!("{}", DisplayDefId(did))), |
186 | ItemId::Blanket { for_, impl_id } => { | |
187 | Id(format!("b:{}-{}", DisplayDefId(impl_id), DisplayDefId(for_))) | |
188 | } | |
189 | ItemId::Auto { for_, trait_ } => { | |
190 | Id(format!("a:{}-{}", DisplayDefId(trait_), DisplayDefId(for_))) | |
191 | } | |
192 | ItemId::Primitive(ty, krate) => Id(format!("p:{}:{}", krate.as_u32(), ty.as_sym())), | |
17df50a5 | 193 | } |
fc512014 XL |
194 | } |
195 | ||
cdc7bbd5 | 196 | fn from_clean_item(item: clean::Item, tcx: TyCtxt<'_>) -> ItemEnum { |
6a06907d | 197 | use clean::ItemKind::*; |
cdc7bbd5 XL |
198 | let name = item.name; |
199 | let is_crate = item.is_crate(); | |
200 | match *item.kind { | |
201 | ModuleItem(m) => ItemEnum::Module(Module { is_crate, items: ids(m.items) }), | |
202 | ImportItem(i) => ItemEnum::Import(i.into_tcx(tcx)), | |
203 | StructItem(s) => ItemEnum::Struct(s.into_tcx(tcx)), | |
204 | UnionItem(u) => ItemEnum::Union(u.into_tcx(tcx)), | |
205 | StructFieldItem(f) => ItemEnum::StructField(f.into_tcx(tcx)), | |
206 | EnumItem(e) => ItemEnum::Enum(e.into_tcx(tcx)), | |
207 | VariantItem(v) => ItemEnum::Variant(v.into_tcx(tcx)), | |
208 | FunctionItem(f) => ItemEnum::Function(f.into_tcx(tcx)), | |
209 | ForeignFunctionItem(f) => ItemEnum::Function(f.into_tcx(tcx)), | |
210 | TraitItem(t) => ItemEnum::Trait(t.into_tcx(tcx)), | |
211 | TraitAliasItem(t) => ItemEnum::TraitAlias(t.into_tcx(tcx)), | |
212 | MethodItem(m, _) => ItemEnum::Method(from_function_method(m, true, tcx)), | |
213 | TyMethodItem(m) => ItemEnum::Method(from_function_method(m, false, tcx)), | |
214 | ImplItem(i) => ItemEnum::Impl(i.into_tcx(tcx)), | |
215 | StaticItem(s) => ItemEnum::Static(s.into_tcx(tcx)), | |
216 | ForeignStaticItem(s) => ItemEnum::Static(s.into_tcx(tcx)), | |
6a06907d | 217 | ForeignTypeItem => ItemEnum::ForeignType, |
cdc7bbd5 XL |
218 | TypedefItem(t, _) => ItemEnum::Typedef(t.into_tcx(tcx)), |
219 | OpaqueTyItem(t) => ItemEnum::OpaqueTy(t.into_tcx(tcx)), | |
220 | ConstantItem(c) => ItemEnum::Constant(c.into_tcx(tcx)), | |
6a06907d | 221 | MacroItem(m) => ItemEnum::Macro(m.source), |
cdc7bbd5 XL |
222 | ProcMacroItem(m) => ItemEnum::ProcMacro(m.into_tcx(tcx)), |
223 | AssocConstItem(t, s) => ItemEnum::AssocConst { type_: t.into_tcx(tcx), default: s }, | |
6a06907d | 224 | AssocTypeItem(g, t) => ItemEnum::AssocType { |
cdc7bbd5 XL |
225 | bounds: g.into_iter().map(|x| x.into_tcx(tcx)).collect(), |
226 | default: t.map(|x| x.into_tcx(tcx)), | |
6a06907d | 227 | }, |
cdc7bbd5 XL |
228 | // `convert_item` early returns `None` for striped items |
229 | StrippedItem(_) => unreachable!(), | |
6a06907d XL |
230 | PrimitiveItem(_) | KeywordItem(_) => { |
231 | panic!("{:?} is not supported for JSON output", item) | |
fc512014 | 232 | } |
6a06907d XL |
233 | ExternCrateItem { ref src } => ItemEnum::ExternCrate { |
234 | name: name.as_ref().unwrap().to_string(), | |
235 | rename: src.map(|x| x.to_string()), | |
236 | }, | |
fc512014 XL |
237 | } |
238 | } | |
239 | ||
cdc7bbd5 XL |
240 | impl FromWithTcx<clean::Struct> for Struct { |
241 | fn from_tcx(struct_: clean::Struct, tcx: TyCtxt<'_>) -> Self { | |
fc512014 XL |
242 | let clean::Struct { struct_type, generics, fields, fields_stripped } = struct_; |
243 | Struct { | |
5869c6ff | 244 | struct_type: from_ctor_kind(struct_type), |
cdc7bbd5 | 245 | generics: generics.into_tcx(tcx), |
fc512014 XL |
246 | fields_stripped, |
247 | fields: ids(fields), | |
248 | impls: Vec::new(), // Added in JsonRenderer::item | |
249 | } | |
250 | } | |
251 | } | |
252 | ||
cdc7bbd5 XL |
253 | impl FromWithTcx<clean::Union> for Union { |
254 | fn from_tcx(struct_: clean::Union, tcx: TyCtxt<'_>) -> Self { | |
5869c6ff XL |
255 | let clean::Union { generics, fields, fields_stripped } = struct_; |
256 | Union { | |
cdc7bbd5 | 257 | generics: generics.into_tcx(tcx), |
fc512014 XL |
258 | fields_stripped, |
259 | fields: ids(fields), | |
260 | impls: Vec::new(), // Added in JsonRenderer::item | |
261 | } | |
262 | } | |
263 | } | |
264 | ||
5869c6ff XL |
265 | crate fn from_ctor_kind(struct_type: CtorKind) -> StructType { |
266 | match struct_type { | |
267 | CtorKind::Fictive => StructType::Plain, | |
268 | CtorKind::Fn => StructType::Tuple, | |
269 | CtorKind::Const => StructType::Unit, | |
fc512014 XL |
270 | } |
271 | } | |
272 | ||
6a06907d XL |
273 | crate fn from_fn_header(header: &rustc_hir::FnHeader) -> HashSet<Qualifiers> { |
274 | let mut v = HashSet::new(); | |
275 | ||
276 | if let rustc_hir::Unsafety::Unsafe = header.unsafety { | |
277 | v.insert(Qualifiers::Unsafe); | |
278 | } | |
279 | ||
280 | if let rustc_hir::IsAsync::Async = header.asyncness { | |
281 | v.insert(Qualifiers::Async); | |
fc512014 | 282 | } |
6a06907d XL |
283 | |
284 | if let rustc_hir::Constness::Const = header.constness { | |
285 | v.insert(Qualifiers::Const); | |
fc512014 | 286 | } |
6a06907d XL |
287 | |
288 | v | |
fc512014 XL |
289 | } |
290 | ||
cdc7bbd5 XL |
291 | impl FromWithTcx<clean::Function> for Function { |
292 | fn from_tcx(function: clean::Function, tcx: TyCtxt<'_>) -> Self { | |
6a06907d | 293 | let clean::Function { decl, generics, header } = function; |
fc512014 | 294 | Function { |
cdc7bbd5 XL |
295 | decl: decl.into_tcx(tcx), |
296 | generics: generics.into_tcx(tcx), | |
6a06907d | 297 | header: from_fn_header(&header), |
fc512014 XL |
298 | abi: header.abi.to_string(), |
299 | } | |
300 | } | |
301 | } | |
302 | ||
cdc7bbd5 XL |
303 | impl FromWithTcx<clean::Generics> for Generics { |
304 | fn from_tcx(generics: clean::Generics, tcx: TyCtxt<'_>) -> Self { | |
fc512014 | 305 | Generics { |
cdc7bbd5 XL |
306 | params: generics.params.into_iter().map(|x| x.into_tcx(tcx)).collect(), |
307 | where_predicates: generics | |
308 | .where_predicates | |
309 | .into_iter() | |
310 | .map(|x| x.into_tcx(tcx)) | |
311 | .collect(), | |
fc512014 XL |
312 | } |
313 | } | |
314 | } | |
315 | ||
cdc7bbd5 XL |
316 | impl FromWithTcx<clean::GenericParamDef> for GenericParamDef { |
317 | fn from_tcx(generic_param: clean::GenericParamDef, tcx: TyCtxt<'_>) -> Self { | |
318 | GenericParamDef { | |
319 | name: generic_param.name.to_string(), | |
320 | kind: generic_param.kind.into_tcx(tcx), | |
321 | } | |
fc512014 XL |
322 | } |
323 | } | |
324 | ||
cdc7bbd5 XL |
325 | impl FromWithTcx<clean::GenericParamDefKind> for GenericParamDefKind { |
326 | fn from_tcx(kind: clean::GenericParamDefKind, tcx: TyCtxt<'_>) -> Self { | |
fc512014 XL |
327 | use clean::GenericParamDefKind::*; |
328 | match kind { | |
329 | Lifetime => GenericParamDefKind::Lifetime, | |
330 | Type { did: _, bounds, default, synthetic: _ } => GenericParamDefKind::Type { | |
cdc7bbd5 XL |
331 | bounds: bounds.into_iter().map(|x| x.into_tcx(tcx)).collect(), |
332 | default: default.map(|x| x.into_tcx(tcx)), | |
fc512014 | 333 | }, |
17df50a5 XL |
334 | Const { did: _, ty, default } => { |
335 | GenericParamDefKind::Const { ty: ty.into_tcx(tcx), default } | |
336 | } | |
fc512014 XL |
337 | } |
338 | } | |
339 | } | |
340 | ||
cdc7bbd5 XL |
341 | impl FromWithTcx<clean::WherePredicate> for WherePredicate { |
342 | fn from_tcx(predicate: clean::WherePredicate, tcx: TyCtxt<'_>) -> Self { | |
fc512014 XL |
343 | use clean::WherePredicate::*; |
344 | match predicate { | |
136023e0 | 345 | BoundPredicate { ty, bounds, .. } => WherePredicate::BoundPredicate { |
cdc7bbd5 XL |
346 | ty: ty.into_tcx(tcx), |
347 | bounds: bounds.into_iter().map(|x| x.into_tcx(tcx)).collect(), | |
136023e0 | 348 | // FIXME: add `bound_params` to rustdoc-json-params? |
fc512014 XL |
349 | }, |
350 | RegionPredicate { lifetime, bounds } => WherePredicate::RegionPredicate { | |
351 | lifetime: lifetime.0.to_string(), | |
cdc7bbd5 | 352 | bounds: bounds.into_iter().map(|x| x.into_tcx(tcx)).collect(), |
fc512014 XL |
353 | }, |
354 | EqPredicate { lhs, rhs } => { | |
cdc7bbd5 | 355 | WherePredicate::EqPredicate { lhs: lhs.into_tcx(tcx), rhs: rhs.into_tcx(tcx) } |
fc512014 XL |
356 | } |
357 | } | |
358 | } | |
359 | } | |
360 | ||
cdc7bbd5 XL |
361 | impl FromWithTcx<clean::GenericBound> for GenericBound { |
362 | fn from_tcx(bound: clean::GenericBound, tcx: TyCtxt<'_>) -> Self { | |
fc512014 XL |
363 | use clean::GenericBound::*; |
364 | match bound { | |
365 | TraitBound(clean::PolyTrait { trait_, generic_params }, modifier) => { | |
366 | GenericBound::TraitBound { | |
cdc7bbd5 XL |
367 | trait_: trait_.into_tcx(tcx), |
368 | generic_params: generic_params.into_iter().map(|x| x.into_tcx(tcx)).collect(), | |
5869c6ff | 369 | modifier: from_trait_bound_modifier(modifier), |
fc512014 XL |
370 | } |
371 | } | |
372 | Outlives(lifetime) => GenericBound::Outlives(lifetime.0.to_string()), | |
373 | } | |
374 | } | |
375 | } | |
376 | ||
5869c6ff XL |
377 | crate fn from_trait_bound_modifier(modifier: rustc_hir::TraitBoundModifier) -> TraitBoundModifier { |
378 | use rustc_hir::TraitBoundModifier::*; | |
379 | match modifier { | |
380 | None => TraitBoundModifier::None, | |
381 | Maybe => TraitBoundModifier::Maybe, | |
382 | MaybeConst => TraitBoundModifier::MaybeConst, | |
fc512014 XL |
383 | } |
384 | } | |
385 | ||
cdc7bbd5 XL |
386 | impl FromWithTcx<clean::Type> for Type { |
387 | fn from_tcx(ty: clean::Type, tcx: TyCtxt<'_>) -> Self { | |
fc512014 XL |
388 | use clean::Type::*; |
389 | match ty { | |
136023e0 | 390 | ResolvedPath { path, did, is_generic: _ } => Type::ResolvedPath { |
fc512014 | 391 | name: path.whole_name(), |
136023e0 | 392 | id: from_item_id(did.into()), |
cdc7bbd5 | 393 | args: path.segments.last().map(|args| Box::new(args.clone().args.into_tcx(tcx))), |
136023e0 | 394 | param_names: Vec::new(), |
fc512014 | 395 | }, |
136023e0 XL |
396 | DynTrait(mut bounds, lt) => { |
397 | let (path, id) = match bounds.remove(0).trait_ { | |
398 | ResolvedPath { path, did, .. } => (path, did), | |
399 | _ => unreachable!(), | |
400 | }; | |
401 | ||
402 | Type::ResolvedPath { | |
403 | name: path.whole_name(), | |
404 | id: from_item_id(id.into()), | |
405 | args: path | |
406 | .segments | |
407 | .last() | |
408 | .map(|args| Box::new(args.clone().args.into_tcx(tcx))), | |
409 | param_names: bounds | |
410 | .into_iter() | |
411 | .map(|t| { | |
412 | clean::GenericBound::TraitBound(t, rustc_hir::TraitBoundModifier::None) | |
413 | }) | |
414 | .chain(lt.into_iter().map(|lt| clean::GenericBound::Outlives(lt))) | |
415 | .map(|bound| bound.into_tcx(tcx)) | |
416 | .collect(), | |
417 | } | |
418 | } | |
fc512014 | 419 | Generic(s) => Type::Generic(s.to_string()), |
17df50a5 | 420 | Primitive(p) => Type::Primitive(p.as_sym().to_string()), |
cdc7bbd5 XL |
421 | BareFunction(f) => Type::FunctionPointer(Box::new((*f).into_tcx(tcx))), |
422 | Tuple(t) => Type::Tuple(t.into_iter().map(|x| x.into_tcx(tcx)).collect()), | |
423 | Slice(t) => Type::Slice(Box::new((*t).into_tcx(tcx))), | |
424 | Array(t, s) => Type::Array { type_: Box::new((*t).into_tcx(tcx)), len: s }, | |
425 | ImplTrait(g) => Type::ImplTrait(g.into_iter().map(|x| x.into_tcx(tcx)).collect()), | |
fc512014 XL |
426 | Never => Type::Never, |
427 | Infer => Type::Infer, | |
428 | RawPointer(mutability, type_) => Type::RawPointer { | |
429 | mutable: mutability == ast::Mutability::Mut, | |
cdc7bbd5 | 430 | type_: Box::new((*type_).into_tcx(tcx)), |
fc512014 XL |
431 | }, |
432 | BorrowedRef { lifetime, mutability, type_ } => Type::BorrowedRef { | |
433 | lifetime: lifetime.map(|l| l.0.to_string()), | |
434 | mutable: mutability == ast::Mutability::Mut, | |
cdc7bbd5 | 435 | type_: Box::new((*type_).into_tcx(tcx)), |
fc512014 | 436 | }, |
17df50a5 | 437 | QPath { name, self_type, trait_, .. } => Type::QualifiedPath { |
fc512014 | 438 | name: name.to_string(), |
cdc7bbd5 XL |
439 | self_type: Box::new((*self_type).into_tcx(tcx)), |
440 | trait_: Box::new((*trait_).into_tcx(tcx)), | |
fc512014 XL |
441 | }, |
442 | } | |
443 | } | |
444 | } | |
445 | ||
cdc7bbd5 XL |
446 | impl FromWithTcx<clean::BareFunctionDecl> for FunctionPointer { |
447 | fn from_tcx(bare_decl: clean::BareFunctionDecl, tcx: TyCtxt<'_>) -> Self { | |
fc512014 XL |
448 | let clean::BareFunctionDecl { unsafety, generic_params, decl, abi } = bare_decl; |
449 | FunctionPointer { | |
6a06907d XL |
450 | header: if let rustc_hir::Unsafety::Unsafe = unsafety { |
451 | let mut hs = HashSet::new(); | |
452 | hs.insert(Qualifiers::Unsafe); | |
453 | hs | |
454 | } else { | |
455 | HashSet::new() | |
456 | }, | |
cdc7bbd5 XL |
457 | generic_params: generic_params.into_iter().map(|x| x.into_tcx(tcx)).collect(), |
458 | decl: decl.into_tcx(tcx), | |
fc512014 XL |
459 | abi: abi.to_string(), |
460 | } | |
461 | } | |
462 | } | |
463 | ||
cdc7bbd5 XL |
464 | impl FromWithTcx<clean::FnDecl> for FnDecl { |
465 | fn from_tcx(decl: clean::FnDecl, tcx: TyCtxt<'_>) -> Self { | |
466 | let clean::FnDecl { inputs, output, c_variadic } = decl; | |
fc512014 XL |
467 | FnDecl { |
468 | inputs: inputs | |
469 | .values | |
470 | .into_iter() | |
cdc7bbd5 | 471 | .map(|arg| (arg.name.to_string(), arg.type_.into_tcx(tcx))) |
fc512014 XL |
472 | .collect(), |
473 | output: match output { | |
cdc7bbd5 | 474 | clean::FnRetTy::Return(t) => Some(t.into_tcx(tcx)), |
fc512014 XL |
475 | clean::FnRetTy::DefaultReturn => None, |
476 | }, | |
477 | c_variadic, | |
478 | } | |
479 | } | |
480 | } | |
481 | ||
cdc7bbd5 XL |
482 | impl FromWithTcx<clean::Trait> for Trait { |
483 | fn from_tcx(trait_: clean::Trait, tcx: TyCtxt<'_>) -> Self { | |
6a06907d | 484 | let clean::Trait { unsafety, items, generics, bounds, is_auto } = trait_; |
fc512014 XL |
485 | Trait { |
486 | is_auto, | |
487 | is_unsafe: unsafety == rustc_hir::Unsafety::Unsafe, | |
488 | items: ids(items), | |
cdc7bbd5 XL |
489 | generics: generics.into_tcx(tcx), |
490 | bounds: bounds.into_iter().map(|x| x.into_tcx(tcx)).collect(), | |
fc512014 XL |
491 | implementors: Vec::new(), // Added in JsonRenderer::item |
492 | } | |
493 | } | |
494 | } | |
495 | ||
cdc7bbd5 XL |
496 | impl FromWithTcx<clean::Impl> for Impl { |
497 | fn from_tcx(impl_: clean::Impl, tcx: TyCtxt<'_>) -> Self { | |
17df50a5 | 498 | let provided_trait_methods = impl_.provided_trait_methods(tcx); |
fc512014 XL |
499 | let clean::Impl { |
500 | unsafety, | |
501 | generics, | |
fc512014 XL |
502 | trait_, |
503 | for_, | |
504 | items, | |
5869c6ff | 505 | negative_polarity, |
fc512014 XL |
506 | synthetic, |
507 | blanket_impl, | |
cdc7bbd5 | 508 | span: _span, |
fc512014 XL |
509 | } = impl_; |
510 | Impl { | |
511 | is_unsafe: unsafety == rustc_hir::Unsafety::Unsafe, | |
cdc7bbd5 | 512 | generics: generics.into_tcx(tcx), |
fc512014 XL |
513 | provided_trait_methods: provided_trait_methods |
514 | .into_iter() | |
515 | .map(|x| x.to_string()) | |
516 | .collect(), | |
cdc7bbd5 XL |
517 | trait_: trait_.map(|x| x.into_tcx(tcx)), |
518 | for_: for_.into_tcx(tcx), | |
fc512014 | 519 | items: ids(items), |
5869c6ff | 520 | negative: negative_polarity, |
fc512014 | 521 | synthetic, |
17df50a5 | 522 | blanket_impl: blanket_impl.map(|x| (*x).into_tcx(tcx)), |
fc512014 XL |
523 | } |
524 | } | |
525 | } | |
526 | ||
cdc7bbd5 XL |
527 | crate fn from_function_method( |
528 | function: clean::Function, | |
529 | has_body: bool, | |
530 | tcx: TyCtxt<'_>, | |
531 | ) -> Method { | |
6a06907d | 532 | let clean::Function { header, decl, generics } = function; |
5869c6ff | 533 | Method { |
cdc7bbd5 XL |
534 | decl: decl.into_tcx(tcx), |
535 | generics: generics.into_tcx(tcx), | |
6a06907d XL |
536 | header: from_fn_header(&header), |
537 | abi: header.abi.to_string(), | |
5869c6ff | 538 | has_body, |
fc512014 XL |
539 | } |
540 | } | |
541 | ||
cdc7bbd5 XL |
542 | impl FromWithTcx<clean::Enum> for Enum { |
543 | fn from_tcx(enum_: clean::Enum, tcx: TyCtxt<'_>) -> Self { | |
fc512014 XL |
544 | let clean::Enum { variants, generics, variants_stripped } = enum_; |
545 | Enum { | |
cdc7bbd5 | 546 | generics: generics.into_tcx(tcx), |
fc512014 XL |
547 | variants_stripped, |
548 | variants: ids(variants), | |
549 | impls: Vec::new(), // Added in JsonRenderer::item | |
550 | } | |
551 | } | |
552 | } | |
553 | ||
cdc7bbd5 XL |
554 | impl FromWithTcx<clean::VariantStruct> for Struct { |
555 | fn from_tcx(struct_: clean::VariantStruct, _tcx: TyCtxt<'_>) -> Self { | |
fc512014 XL |
556 | let clean::VariantStruct { struct_type, fields, fields_stripped } = struct_; |
557 | Struct { | |
5869c6ff | 558 | struct_type: from_ctor_kind(struct_type), |
fc512014 XL |
559 | generics: Default::default(), |
560 | fields_stripped, | |
561 | fields: ids(fields), | |
562 | impls: Vec::new(), | |
563 | } | |
564 | } | |
565 | } | |
566 | ||
cdc7bbd5 XL |
567 | impl FromWithTcx<clean::Variant> for Variant { |
568 | fn from_tcx(variant: clean::Variant, tcx: TyCtxt<'_>) -> Self { | |
5869c6ff XL |
569 | use clean::Variant::*; |
570 | match variant { | |
fc512014 | 571 | CLike => Variant::Plain, |
94222f64 XL |
572 | Tuple(fields) => Variant::Tuple( |
573 | fields | |
574 | .into_iter() | |
575 | .map(|f| { | |
576 | if let clean::StructFieldItem(ty) = *f.kind { | |
577 | ty.into_tcx(tcx) | |
578 | } else { | |
579 | unreachable!() | |
580 | } | |
581 | }) | |
582 | .collect(), | |
583 | ), | |
fc512014 XL |
584 | Struct(s) => Variant::Struct(ids(s.fields)), |
585 | } | |
586 | } | |
587 | } | |
588 | ||
cdc7bbd5 XL |
589 | impl FromWithTcx<clean::Import> for Import { |
590 | fn from_tcx(import: clean::Import, _tcx: TyCtxt<'_>) -> Self { | |
fc512014 XL |
591 | use clean::ImportKind::*; |
592 | match import.kind { | |
593 | Simple(s) => Import { | |
cdc7bbd5 | 594 | source: import.source.path.whole_name(), |
fc512014 | 595 | name: s.to_string(), |
136023e0 | 596 | id: import.source.did.map(ItemId::from).map(from_item_id), |
fc512014 XL |
597 | glob: false, |
598 | }, | |
599 | Glob => Import { | |
cdc7bbd5 | 600 | source: import.source.path.whole_name(), |
fc512014 | 601 | name: import.source.path.last_name().to_string(), |
136023e0 | 602 | id: import.source.did.map(ItemId::from).map(from_item_id), |
fc512014 XL |
603 | glob: true, |
604 | }, | |
605 | } | |
606 | } | |
607 | } | |
608 | ||
cdc7bbd5 XL |
609 | impl FromWithTcx<clean::ProcMacro> for ProcMacro { |
610 | fn from_tcx(mac: clean::ProcMacro, _tcx: TyCtxt<'_>) -> Self { | |
fc512014 | 611 | ProcMacro { |
5869c6ff | 612 | kind: from_macro_kind(mac.kind), |
fc512014 XL |
613 | helpers: mac.helpers.iter().map(|x| x.to_string()).collect(), |
614 | } | |
615 | } | |
616 | } | |
617 | ||
5869c6ff XL |
618 | crate fn from_macro_kind(kind: rustc_span::hygiene::MacroKind) -> MacroKind { |
619 | use rustc_span::hygiene::MacroKind::*; | |
620 | match kind { | |
621 | Bang => MacroKind::Bang, | |
622 | Attr => MacroKind::Attr, | |
623 | Derive => MacroKind::Derive, | |
fc512014 XL |
624 | } |
625 | } | |
626 | ||
cdc7bbd5 XL |
627 | impl FromWithTcx<clean::Typedef> for Typedef { |
628 | fn from_tcx(typedef: clean::Typedef, tcx: TyCtxt<'_>) -> Self { | |
fc512014 | 629 | let clean::Typedef { type_, generics, item_type: _ } = typedef; |
cdc7bbd5 | 630 | Typedef { type_: type_.into_tcx(tcx), generics: generics.into_tcx(tcx) } |
fc512014 XL |
631 | } |
632 | } | |
633 | ||
cdc7bbd5 XL |
634 | impl FromWithTcx<clean::OpaqueTy> for OpaqueTy { |
635 | fn from_tcx(opaque: clean::OpaqueTy, tcx: TyCtxt<'_>) -> Self { | |
fc512014 | 636 | OpaqueTy { |
cdc7bbd5 XL |
637 | bounds: opaque.bounds.into_iter().map(|x| x.into_tcx(tcx)).collect(), |
638 | generics: opaque.generics.into_tcx(tcx), | |
fc512014 XL |
639 | } |
640 | } | |
641 | } | |
642 | ||
cdc7bbd5 XL |
643 | impl FromWithTcx<clean::Static> for Static { |
644 | fn from_tcx(stat: clean::Static, tcx: TyCtxt<'_>) -> Self { | |
645 | Static { | |
646 | type_: stat.type_.into_tcx(tcx), | |
647 | mutable: stat.mutability == ast::Mutability::Mut, | |
648 | expr: stat.expr.map(|e| print_const_expr(tcx, e)).unwrap_or_default(), | |
649 | } | |
fc512014 XL |
650 | } |
651 | } | |
652 | ||
cdc7bbd5 XL |
653 | impl FromWithTcx<clean::TraitAlias> for TraitAlias { |
654 | fn from_tcx(alias: clean::TraitAlias, tcx: TyCtxt<'_>) -> Self { | |
fc512014 | 655 | TraitAlias { |
cdc7bbd5 XL |
656 | generics: alias.generics.into_tcx(tcx), |
657 | params: alias.bounds.into_iter().map(|x| x.into_tcx(tcx)).collect(), | |
fc512014 XL |
658 | } |
659 | } | |
660 | } | |
661 | ||
cdc7bbd5 XL |
662 | impl FromWithTcx<ItemType> for ItemKind { |
663 | fn from_tcx(kind: ItemType, _tcx: TyCtxt<'_>) -> Self { | |
fc512014 XL |
664 | use ItemType::*; |
665 | match kind { | |
666 | Module => ItemKind::Module, | |
667 | ExternCrate => ItemKind::ExternCrate, | |
668 | Import => ItemKind::Import, | |
669 | Struct => ItemKind::Struct, | |
670 | Union => ItemKind::Union, | |
671 | Enum => ItemKind::Enum, | |
672 | Function => ItemKind::Function, | |
673 | Typedef => ItemKind::Typedef, | |
674 | OpaqueTy => ItemKind::OpaqueTy, | |
675 | Static => ItemKind::Static, | |
676 | Constant => ItemKind::Constant, | |
677 | Trait => ItemKind::Trait, | |
678 | Impl => ItemKind::Impl, | |
679 | TyMethod | Method => ItemKind::Method, | |
680 | StructField => ItemKind::StructField, | |
681 | Variant => ItemKind::Variant, | |
682 | Macro => ItemKind::Macro, | |
683 | Primitive => ItemKind::Primitive, | |
684 | AssocConst => ItemKind::AssocConst, | |
685 | AssocType => ItemKind::AssocType, | |
686 | ForeignType => ItemKind::ForeignType, | |
687 | Keyword => ItemKind::Keyword, | |
688 | TraitAlias => ItemKind::TraitAlias, | |
689 | ProcAttribute => ItemKind::ProcAttribute, | |
690 | ProcDerive => ItemKind::ProcDerive, | |
691 | } | |
692 | } | |
693 | } | |
694 | ||
695 | fn ids(items: impl IntoIterator<Item = clean::Item>) -> Vec<Id> { | |
136023e0 | 696 | items.into_iter().filter(|x| !x.is_stripped()).map(|i| from_item_id(i.def_id)).collect() |
fc512014 | 697 | } |