]>
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 XL |
129 | inputs: inputs.into_iter().map(|a| a.into_tcx(tcx)).collect(), |
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)), | |
fc512014 XL |
143 | } |
144 | } | |
145 | } | |
146 | ||
cdc7bbd5 XL |
147 | impl FromWithTcx<clean::Constant> for Constant { |
148 | fn from_tcx(constant: clean::Constant, tcx: TyCtxt<'_>) -> Self { | |
149 | let expr = constant.expr(tcx); | |
150 | let value = constant.value(tcx); | |
151 | let is_literal = constant.is_literal(tcx); | |
152 | Constant { type_: constant.type_.into_tcx(tcx), expr, value, is_literal } | |
fc512014 XL |
153 | } |
154 | } | |
155 | ||
cdc7bbd5 XL |
156 | impl FromWithTcx<clean::TypeBinding> for TypeBinding { |
157 | fn from_tcx(binding: clean::TypeBinding, tcx: TyCtxt<'_>) -> Self { | |
158 | TypeBinding { name: binding.name.to_string(), binding: binding.kind.into_tcx(tcx) } | |
fc512014 XL |
159 | } |
160 | } | |
161 | ||
cdc7bbd5 XL |
162 | impl FromWithTcx<clean::TypeBindingKind> for TypeBindingKind { |
163 | fn from_tcx(kind: clean::TypeBindingKind, tcx: TyCtxt<'_>) -> Self { | |
fc512014 XL |
164 | use clean::TypeBindingKind::*; |
165 | match kind { | |
cdc7bbd5 | 166 | Equality { ty } => TypeBindingKind::Equality(ty.into_tcx(tcx)), |
fc512014 | 167 | Constraint { bounds } => { |
cdc7bbd5 | 168 | TypeBindingKind::Constraint(bounds.into_iter().map(|a| a.into_tcx(tcx)).collect()) |
fc512014 XL |
169 | } |
170 | } | |
171 | } | |
172 | } | |
173 | ||
136023e0 XL |
174 | crate fn from_item_id(did: ItemId) -> Id { |
175 | struct DisplayDefId(DefId); | |
176 | ||
177 | impl fmt::Display for DisplayDefId { | |
178 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
179 | write!(f, "{}:{}", self.0.krate.as_u32(), u32::from(self.0.index)) | |
180 | } | |
181 | } | |
182 | ||
17df50a5 | 183 | match did { |
136023e0 XL |
184 | ItemId::DefId(did) => Id(format!("{}", DisplayDefId(did))), |
185 | ItemId::Blanket { for_, impl_id } => { | |
186 | Id(format!("b:{}-{}", DisplayDefId(impl_id), DisplayDefId(for_))) | |
187 | } | |
188 | ItemId::Auto { for_, trait_ } => { | |
189 | Id(format!("a:{}-{}", DisplayDefId(trait_), DisplayDefId(for_))) | |
190 | } | |
191 | ItemId::Primitive(ty, krate) => Id(format!("p:{}:{}", krate.as_u32(), ty.as_sym())), | |
17df50a5 | 192 | } |
fc512014 XL |
193 | } |
194 | ||
cdc7bbd5 | 195 | fn from_clean_item(item: clean::Item, tcx: TyCtxt<'_>) -> ItemEnum { |
6a06907d | 196 | use clean::ItemKind::*; |
cdc7bbd5 XL |
197 | let name = item.name; |
198 | let is_crate = item.is_crate(); | |
199 | match *item.kind { | |
200 | ModuleItem(m) => ItemEnum::Module(Module { is_crate, items: ids(m.items) }), | |
201 | ImportItem(i) => ItemEnum::Import(i.into_tcx(tcx)), | |
202 | StructItem(s) => ItemEnum::Struct(s.into_tcx(tcx)), | |
203 | UnionItem(u) => ItemEnum::Union(u.into_tcx(tcx)), | |
204 | StructFieldItem(f) => ItemEnum::StructField(f.into_tcx(tcx)), | |
205 | EnumItem(e) => ItemEnum::Enum(e.into_tcx(tcx)), | |
206 | VariantItem(v) => ItemEnum::Variant(v.into_tcx(tcx)), | |
207 | FunctionItem(f) => ItemEnum::Function(f.into_tcx(tcx)), | |
208 | ForeignFunctionItem(f) => ItemEnum::Function(f.into_tcx(tcx)), | |
209 | TraitItem(t) => ItemEnum::Trait(t.into_tcx(tcx)), | |
210 | TraitAliasItem(t) => ItemEnum::TraitAlias(t.into_tcx(tcx)), | |
211 | MethodItem(m, _) => ItemEnum::Method(from_function_method(m, true, tcx)), | |
212 | TyMethodItem(m) => ItemEnum::Method(from_function_method(m, false, tcx)), | |
213 | ImplItem(i) => ItemEnum::Impl(i.into_tcx(tcx)), | |
214 | StaticItem(s) => ItemEnum::Static(s.into_tcx(tcx)), | |
215 | ForeignStaticItem(s) => ItemEnum::Static(s.into_tcx(tcx)), | |
6a06907d | 216 | ForeignTypeItem => ItemEnum::ForeignType, |
cdc7bbd5 XL |
217 | TypedefItem(t, _) => ItemEnum::Typedef(t.into_tcx(tcx)), |
218 | OpaqueTyItem(t) => ItemEnum::OpaqueTy(t.into_tcx(tcx)), | |
219 | ConstantItem(c) => ItemEnum::Constant(c.into_tcx(tcx)), | |
6a06907d | 220 | MacroItem(m) => ItemEnum::Macro(m.source), |
cdc7bbd5 XL |
221 | ProcMacroItem(m) => ItemEnum::ProcMacro(m.into_tcx(tcx)), |
222 | AssocConstItem(t, s) => ItemEnum::AssocConst { type_: t.into_tcx(tcx), default: s }, | |
6a06907d | 223 | AssocTypeItem(g, t) => ItemEnum::AssocType { |
cdc7bbd5 XL |
224 | bounds: g.into_iter().map(|x| x.into_tcx(tcx)).collect(), |
225 | default: t.map(|x| x.into_tcx(tcx)), | |
6a06907d | 226 | }, |
cdc7bbd5 XL |
227 | // `convert_item` early returns `None` for striped items |
228 | StrippedItem(_) => unreachable!(), | |
6a06907d XL |
229 | PrimitiveItem(_) | KeywordItem(_) => { |
230 | panic!("{:?} is not supported for JSON output", item) | |
fc512014 | 231 | } |
6a06907d XL |
232 | ExternCrateItem { ref src } => ItemEnum::ExternCrate { |
233 | name: name.as_ref().unwrap().to_string(), | |
234 | rename: src.map(|x| x.to_string()), | |
235 | }, | |
fc512014 XL |
236 | } |
237 | } | |
238 | ||
cdc7bbd5 XL |
239 | impl FromWithTcx<clean::Struct> for Struct { |
240 | fn from_tcx(struct_: clean::Struct, tcx: TyCtxt<'_>) -> Self { | |
fc512014 XL |
241 | let clean::Struct { struct_type, generics, fields, fields_stripped } = struct_; |
242 | Struct { | |
5869c6ff | 243 | struct_type: from_ctor_kind(struct_type), |
cdc7bbd5 | 244 | generics: generics.into_tcx(tcx), |
fc512014 XL |
245 | fields_stripped, |
246 | fields: ids(fields), | |
247 | impls: Vec::new(), // Added in JsonRenderer::item | |
248 | } | |
249 | } | |
250 | } | |
251 | ||
cdc7bbd5 XL |
252 | impl FromWithTcx<clean::Union> for Union { |
253 | fn from_tcx(struct_: clean::Union, tcx: TyCtxt<'_>) -> Self { | |
5869c6ff XL |
254 | let clean::Union { generics, fields, fields_stripped } = struct_; |
255 | Union { | |
cdc7bbd5 | 256 | generics: generics.into_tcx(tcx), |
fc512014 XL |
257 | fields_stripped, |
258 | fields: ids(fields), | |
259 | impls: Vec::new(), // Added in JsonRenderer::item | |
260 | } | |
261 | } | |
262 | } | |
263 | ||
5869c6ff XL |
264 | crate fn from_ctor_kind(struct_type: CtorKind) -> StructType { |
265 | match struct_type { | |
266 | CtorKind::Fictive => StructType::Plain, | |
267 | CtorKind::Fn => StructType::Tuple, | |
268 | CtorKind::Const => StructType::Unit, | |
fc512014 XL |
269 | } |
270 | } | |
271 | ||
6a06907d XL |
272 | crate fn from_fn_header(header: &rustc_hir::FnHeader) -> HashSet<Qualifiers> { |
273 | let mut v = HashSet::new(); | |
274 | ||
275 | if let rustc_hir::Unsafety::Unsafe = header.unsafety { | |
276 | v.insert(Qualifiers::Unsafe); | |
277 | } | |
278 | ||
279 | if let rustc_hir::IsAsync::Async = header.asyncness { | |
280 | v.insert(Qualifiers::Async); | |
fc512014 | 281 | } |
6a06907d XL |
282 | |
283 | if let rustc_hir::Constness::Const = header.constness { | |
284 | v.insert(Qualifiers::Const); | |
fc512014 | 285 | } |
6a06907d XL |
286 | |
287 | v | |
fc512014 XL |
288 | } |
289 | ||
cdc7bbd5 XL |
290 | impl FromWithTcx<clean::Function> for Function { |
291 | fn from_tcx(function: clean::Function, tcx: TyCtxt<'_>) -> Self { | |
6a06907d | 292 | let clean::Function { decl, generics, header } = function; |
fc512014 | 293 | Function { |
cdc7bbd5 XL |
294 | decl: decl.into_tcx(tcx), |
295 | generics: generics.into_tcx(tcx), | |
6a06907d | 296 | header: from_fn_header(&header), |
fc512014 XL |
297 | abi: header.abi.to_string(), |
298 | } | |
299 | } | |
300 | } | |
301 | ||
cdc7bbd5 XL |
302 | impl FromWithTcx<clean::Generics> for Generics { |
303 | fn from_tcx(generics: clean::Generics, tcx: TyCtxt<'_>) -> Self { | |
fc512014 | 304 | Generics { |
cdc7bbd5 XL |
305 | params: generics.params.into_iter().map(|x| x.into_tcx(tcx)).collect(), |
306 | where_predicates: generics | |
307 | .where_predicates | |
308 | .into_iter() | |
309 | .map(|x| x.into_tcx(tcx)) | |
310 | .collect(), | |
fc512014 XL |
311 | } |
312 | } | |
313 | } | |
314 | ||
cdc7bbd5 XL |
315 | impl FromWithTcx<clean::GenericParamDef> for GenericParamDef { |
316 | fn from_tcx(generic_param: clean::GenericParamDef, tcx: TyCtxt<'_>) -> Self { | |
317 | GenericParamDef { | |
318 | name: generic_param.name.to_string(), | |
319 | kind: generic_param.kind.into_tcx(tcx), | |
320 | } | |
fc512014 XL |
321 | } |
322 | } | |
323 | ||
cdc7bbd5 XL |
324 | impl FromWithTcx<clean::GenericParamDefKind> for GenericParamDefKind { |
325 | fn from_tcx(kind: clean::GenericParamDefKind, tcx: TyCtxt<'_>) -> Self { | |
fc512014 XL |
326 | use clean::GenericParamDefKind::*; |
327 | match kind { | |
328 | Lifetime => GenericParamDefKind::Lifetime, | |
329 | Type { did: _, bounds, default, synthetic: _ } => GenericParamDefKind::Type { | |
cdc7bbd5 XL |
330 | bounds: bounds.into_iter().map(|x| x.into_tcx(tcx)).collect(), |
331 | default: default.map(|x| x.into_tcx(tcx)), | |
fc512014 | 332 | }, |
17df50a5 XL |
333 | Const { did: _, ty, default } => { |
334 | GenericParamDefKind::Const { ty: ty.into_tcx(tcx), default } | |
335 | } | |
fc512014 XL |
336 | } |
337 | } | |
338 | } | |
339 | ||
cdc7bbd5 XL |
340 | impl FromWithTcx<clean::WherePredicate> for WherePredicate { |
341 | fn from_tcx(predicate: clean::WherePredicate, tcx: TyCtxt<'_>) -> Self { | |
fc512014 XL |
342 | use clean::WherePredicate::*; |
343 | match predicate { | |
136023e0 | 344 | BoundPredicate { ty, bounds, .. } => WherePredicate::BoundPredicate { |
cdc7bbd5 XL |
345 | ty: ty.into_tcx(tcx), |
346 | bounds: bounds.into_iter().map(|x| x.into_tcx(tcx)).collect(), | |
136023e0 | 347 | // FIXME: add `bound_params` to rustdoc-json-params? |
fc512014 XL |
348 | }, |
349 | RegionPredicate { lifetime, bounds } => WherePredicate::RegionPredicate { | |
350 | lifetime: lifetime.0.to_string(), | |
cdc7bbd5 | 351 | bounds: bounds.into_iter().map(|x| x.into_tcx(tcx)).collect(), |
fc512014 XL |
352 | }, |
353 | EqPredicate { lhs, rhs } => { | |
cdc7bbd5 | 354 | WherePredicate::EqPredicate { lhs: lhs.into_tcx(tcx), rhs: rhs.into_tcx(tcx) } |
fc512014 XL |
355 | } |
356 | } | |
357 | } | |
358 | } | |
359 | ||
cdc7bbd5 XL |
360 | impl FromWithTcx<clean::GenericBound> for GenericBound { |
361 | fn from_tcx(bound: clean::GenericBound, tcx: TyCtxt<'_>) -> Self { | |
fc512014 XL |
362 | use clean::GenericBound::*; |
363 | match bound { | |
364 | TraitBound(clean::PolyTrait { trait_, generic_params }, modifier) => { | |
365 | GenericBound::TraitBound { | |
cdc7bbd5 XL |
366 | trait_: trait_.into_tcx(tcx), |
367 | generic_params: generic_params.into_iter().map(|x| x.into_tcx(tcx)).collect(), | |
5869c6ff | 368 | modifier: from_trait_bound_modifier(modifier), |
fc512014 XL |
369 | } |
370 | } | |
371 | Outlives(lifetime) => GenericBound::Outlives(lifetime.0.to_string()), | |
372 | } | |
373 | } | |
374 | } | |
375 | ||
5869c6ff XL |
376 | crate fn from_trait_bound_modifier(modifier: rustc_hir::TraitBoundModifier) -> TraitBoundModifier { |
377 | use rustc_hir::TraitBoundModifier::*; | |
378 | match modifier { | |
379 | None => TraitBoundModifier::None, | |
380 | Maybe => TraitBoundModifier::Maybe, | |
381 | MaybeConst => TraitBoundModifier::MaybeConst, | |
fc512014 XL |
382 | } |
383 | } | |
384 | ||
cdc7bbd5 XL |
385 | impl FromWithTcx<clean::Type> for Type { |
386 | fn from_tcx(ty: clean::Type, tcx: TyCtxt<'_>) -> Self { | |
fc512014 XL |
387 | use clean::Type::*; |
388 | match ty { | |
136023e0 | 389 | ResolvedPath { path, did, is_generic: _ } => Type::ResolvedPath { |
fc512014 | 390 | name: path.whole_name(), |
136023e0 | 391 | id: from_item_id(did.into()), |
cdc7bbd5 | 392 | args: path.segments.last().map(|args| Box::new(args.clone().args.into_tcx(tcx))), |
136023e0 | 393 | param_names: Vec::new(), |
fc512014 | 394 | }, |
136023e0 XL |
395 | DynTrait(mut bounds, lt) => { |
396 | let (path, id) = match bounds.remove(0).trait_ { | |
397 | ResolvedPath { path, did, .. } => (path, did), | |
398 | _ => unreachable!(), | |
399 | }; | |
400 | ||
401 | Type::ResolvedPath { | |
402 | name: path.whole_name(), | |
403 | id: from_item_id(id.into()), | |
404 | args: path | |
405 | .segments | |
406 | .last() | |
407 | .map(|args| Box::new(args.clone().args.into_tcx(tcx))), | |
408 | param_names: bounds | |
409 | .into_iter() | |
410 | .map(|t| { | |
411 | clean::GenericBound::TraitBound(t, rustc_hir::TraitBoundModifier::None) | |
412 | }) | |
413 | .chain(lt.into_iter().map(|lt| clean::GenericBound::Outlives(lt))) | |
414 | .map(|bound| bound.into_tcx(tcx)) | |
415 | .collect(), | |
416 | } | |
417 | } | |
fc512014 | 418 | Generic(s) => Type::Generic(s.to_string()), |
17df50a5 | 419 | Primitive(p) => Type::Primitive(p.as_sym().to_string()), |
cdc7bbd5 XL |
420 | BareFunction(f) => Type::FunctionPointer(Box::new((*f).into_tcx(tcx))), |
421 | Tuple(t) => Type::Tuple(t.into_iter().map(|x| x.into_tcx(tcx)).collect()), | |
422 | Slice(t) => Type::Slice(Box::new((*t).into_tcx(tcx))), | |
423 | Array(t, s) => Type::Array { type_: Box::new((*t).into_tcx(tcx)), len: s }, | |
424 | ImplTrait(g) => Type::ImplTrait(g.into_iter().map(|x| x.into_tcx(tcx)).collect()), | |
fc512014 XL |
425 | Never => Type::Never, |
426 | Infer => Type::Infer, | |
427 | RawPointer(mutability, type_) => Type::RawPointer { | |
428 | mutable: mutability == ast::Mutability::Mut, | |
cdc7bbd5 | 429 | type_: Box::new((*type_).into_tcx(tcx)), |
fc512014 XL |
430 | }, |
431 | BorrowedRef { lifetime, mutability, type_ } => Type::BorrowedRef { | |
432 | lifetime: lifetime.map(|l| l.0.to_string()), | |
433 | mutable: mutability == ast::Mutability::Mut, | |
cdc7bbd5 | 434 | type_: Box::new((*type_).into_tcx(tcx)), |
fc512014 | 435 | }, |
17df50a5 | 436 | QPath { name, self_type, trait_, .. } => Type::QualifiedPath { |
fc512014 | 437 | name: name.to_string(), |
cdc7bbd5 XL |
438 | self_type: Box::new((*self_type).into_tcx(tcx)), |
439 | trait_: Box::new((*trait_).into_tcx(tcx)), | |
fc512014 XL |
440 | }, |
441 | } | |
442 | } | |
443 | } | |
444 | ||
cdc7bbd5 XL |
445 | impl FromWithTcx<clean::BareFunctionDecl> for FunctionPointer { |
446 | fn from_tcx(bare_decl: clean::BareFunctionDecl, tcx: TyCtxt<'_>) -> Self { | |
fc512014 XL |
447 | let clean::BareFunctionDecl { unsafety, generic_params, decl, abi } = bare_decl; |
448 | FunctionPointer { | |
6a06907d XL |
449 | header: if let rustc_hir::Unsafety::Unsafe = unsafety { |
450 | let mut hs = HashSet::new(); | |
451 | hs.insert(Qualifiers::Unsafe); | |
452 | hs | |
453 | } else { | |
454 | HashSet::new() | |
455 | }, | |
cdc7bbd5 XL |
456 | generic_params: generic_params.into_iter().map(|x| x.into_tcx(tcx)).collect(), |
457 | decl: decl.into_tcx(tcx), | |
fc512014 XL |
458 | abi: abi.to_string(), |
459 | } | |
460 | } | |
461 | } | |
462 | ||
cdc7bbd5 XL |
463 | impl FromWithTcx<clean::FnDecl> for FnDecl { |
464 | fn from_tcx(decl: clean::FnDecl, tcx: TyCtxt<'_>) -> Self { | |
465 | let clean::FnDecl { inputs, output, c_variadic } = decl; | |
fc512014 XL |
466 | FnDecl { |
467 | inputs: inputs | |
468 | .values | |
469 | .into_iter() | |
cdc7bbd5 | 470 | .map(|arg| (arg.name.to_string(), arg.type_.into_tcx(tcx))) |
fc512014 XL |
471 | .collect(), |
472 | output: match output { | |
cdc7bbd5 | 473 | clean::FnRetTy::Return(t) => Some(t.into_tcx(tcx)), |
fc512014 XL |
474 | clean::FnRetTy::DefaultReturn => None, |
475 | }, | |
476 | c_variadic, | |
477 | } | |
478 | } | |
479 | } | |
480 | ||
cdc7bbd5 XL |
481 | impl FromWithTcx<clean::Trait> for Trait { |
482 | fn from_tcx(trait_: clean::Trait, tcx: TyCtxt<'_>) -> Self { | |
6a06907d | 483 | let clean::Trait { unsafety, items, generics, bounds, is_auto } = trait_; |
fc512014 XL |
484 | Trait { |
485 | is_auto, | |
486 | is_unsafe: unsafety == rustc_hir::Unsafety::Unsafe, | |
487 | items: ids(items), | |
cdc7bbd5 XL |
488 | generics: generics.into_tcx(tcx), |
489 | bounds: bounds.into_iter().map(|x| x.into_tcx(tcx)).collect(), | |
fc512014 XL |
490 | implementors: Vec::new(), // Added in JsonRenderer::item |
491 | } | |
492 | } | |
493 | } | |
494 | ||
cdc7bbd5 XL |
495 | impl FromWithTcx<clean::Impl> for Impl { |
496 | fn from_tcx(impl_: clean::Impl, tcx: TyCtxt<'_>) -> Self { | |
17df50a5 | 497 | let provided_trait_methods = impl_.provided_trait_methods(tcx); |
fc512014 XL |
498 | let clean::Impl { |
499 | unsafety, | |
500 | generics, | |
fc512014 XL |
501 | trait_, |
502 | for_, | |
503 | items, | |
5869c6ff | 504 | negative_polarity, |
fc512014 XL |
505 | synthetic, |
506 | blanket_impl, | |
cdc7bbd5 | 507 | span: _span, |
fc512014 XL |
508 | } = impl_; |
509 | Impl { | |
510 | is_unsafe: unsafety == rustc_hir::Unsafety::Unsafe, | |
cdc7bbd5 | 511 | generics: generics.into_tcx(tcx), |
fc512014 XL |
512 | provided_trait_methods: provided_trait_methods |
513 | .into_iter() | |
514 | .map(|x| x.to_string()) | |
515 | .collect(), | |
cdc7bbd5 XL |
516 | trait_: trait_.map(|x| x.into_tcx(tcx)), |
517 | for_: for_.into_tcx(tcx), | |
fc512014 | 518 | items: ids(items), |
5869c6ff | 519 | negative: negative_polarity, |
fc512014 | 520 | synthetic, |
17df50a5 | 521 | blanket_impl: blanket_impl.map(|x| (*x).into_tcx(tcx)), |
fc512014 XL |
522 | } |
523 | } | |
524 | } | |
525 | ||
cdc7bbd5 XL |
526 | crate fn from_function_method( |
527 | function: clean::Function, | |
528 | has_body: bool, | |
529 | tcx: TyCtxt<'_>, | |
530 | ) -> Method { | |
6a06907d | 531 | let clean::Function { header, decl, generics } = function; |
5869c6ff | 532 | Method { |
cdc7bbd5 XL |
533 | decl: decl.into_tcx(tcx), |
534 | generics: generics.into_tcx(tcx), | |
6a06907d XL |
535 | header: from_fn_header(&header), |
536 | abi: header.abi.to_string(), | |
5869c6ff | 537 | has_body, |
fc512014 XL |
538 | } |
539 | } | |
540 | ||
cdc7bbd5 XL |
541 | impl FromWithTcx<clean::Enum> for Enum { |
542 | fn from_tcx(enum_: clean::Enum, tcx: TyCtxt<'_>) -> Self { | |
fc512014 XL |
543 | let clean::Enum { variants, generics, variants_stripped } = enum_; |
544 | Enum { | |
cdc7bbd5 | 545 | generics: generics.into_tcx(tcx), |
fc512014 XL |
546 | variants_stripped, |
547 | variants: ids(variants), | |
548 | impls: Vec::new(), // Added in JsonRenderer::item | |
549 | } | |
550 | } | |
551 | } | |
552 | ||
cdc7bbd5 XL |
553 | impl FromWithTcx<clean::VariantStruct> for Struct { |
554 | fn from_tcx(struct_: clean::VariantStruct, _tcx: TyCtxt<'_>) -> Self { | |
fc512014 XL |
555 | let clean::VariantStruct { struct_type, fields, fields_stripped } = struct_; |
556 | Struct { | |
5869c6ff | 557 | struct_type: from_ctor_kind(struct_type), |
fc512014 XL |
558 | generics: Default::default(), |
559 | fields_stripped, | |
560 | fields: ids(fields), | |
561 | impls: Vec::new(), | |
562 | } | |
563 | } | |
564 | } | |
565 | ||
cdc7bbd5 XL |
566 | impl FromWithTcx<clean::Variant> for Variant { |
567 | fn from_tcx(variant: clean::Variant, tcx: TyCtxt<'_>) -> Self { | |
5869c6ff XL |
568 | use clean::Variant::*; |
569 | match variant { | |
fc512014 | 570 | CLike => Variant::Plain, |
cdc7bbd5 | 571 | Tuple(t) => Variant::Tuple(t.into_iter().map(|x| x.into_tcx(tcx)).collect()), |
fc512014 XL |
572 | Struct(s) => Variant::Struct(ids(s.fields)), |
573 | } | |
574 | } | |
575 | } | |
576 | ||
cdc7bbd5 XL |
577 | impl FromWithTcx<clean::Import> for Import { |
578 | fn from_tcx(import: clean::Import, _tcx: TyCtxt<'_>) -> Self { | |
fc512014 XL |
579 | use clean::ImportKind::*; |
580 | match import.kind { | |
581 | Simple(s) => Import { | |
cdc7bbd5 | 582 | source: import.source.path.whole_name(), |
fc512014 | 583 | name: s.to_string(), |
136023e0 | 584 | id: import.source.did.map(ItemId::from).map(from_item_id), |
fc512014 XL |
585 | glob: false, |
586 | }, | |
587 | Glob => Import { | |
cdc7bbd5 | 588 | source: import.source.path.whole_name(), |
fc512014 | 589 | name: import.source.path.last_name().to_string(), |
136023e0 | 590 | id: import.source.did.map(ItemId::from).map(from_item_id), |
fc512014 XL |
591 | glob: true, |
592 | }, | |
593 | } | |
594 | } | |
595 | } | |
596 | ||
cdc7bbd5 XL |
597 | impl FromWithTcx<clean::ProcMacro> for ProcMacro { |
598 | fn from_tcx(mac: clean::ProcMacro, _tcx: TyCtxt<'_>) -> Self { | |
fc512014 | 599 | ProcMacro { |
5869c6ff | 600 | kind: from_macro_kind(mac.kind), |
fc512014 XL |
601 | helpers: mac.helpers.iter().map(|x| x.to_string()).collect(), |
602 | } | |
603 | } | |
604 | } | |
605 | ||
5869c6ff XL |
606 | crate fn from_macro_kind(kind: rustc_span::hygiene::MacroKind) -> MacroKind { |
607 | use rustc_span::hygiene::MacroKind::*; | |
608 | match kind { | |
609 | Bang => MacroKind::Bang, | |
610 | Attr => MacroKind::Attr, | |
611 | Derive => MacroKind::Derive, | |
fc512014 XL |
612 | } |
613 | } | |
614 | ||
cdc7bbd5 XL |
615 | impl FromWithTcx<clean::Typedef> for Typedef { |
616 | fn from_tcx(typedef: clean::Typedef, tcx: TyCtxt<'_>) -> Self { | |
fc512014 | 617 | let clean::Typedef { type_, generics, item_type: _ } = typedef; |
cdc7bbd5 | 618 | Typedef { type_: type_.into_tcx(tcx), generics: generics.into_tcx(tcx) } |
fc512014 XL |
619 | } |
620 | } | |
621 | ||
cdc7bbd5 XL |
622 | impl FromWithTcx<clean::OpaqueTy> for OpaqueTy { |
623 | fn from_tcx(opaque: clean::OpaqueTy, tcx: TyCtxt<'_>) -> Self { | |
fc512014 | 624 | OpaqueTy { |
cdc7bbd5 XL |
625 | bounds: opaque.bounds.into_iter().map(|x| x.into_tcx(tcx)).collect(), |
626 | generics: opaque.generics.into_tcx(tcx), | |
fc512014 XL |
627 | } |
628 | } | |
629 | } | |
630 | ||
cdc7bbd5 XL |
631 | impl FromWithTcx<clean::Static> for Static { |
632 | fn from_tcx(stat: clean::Static, tcx: TyCtxt<'_>) -> Self { | |
633 | Static { | |
634 | type_: stat.type_.into_tcx(tcx), | |
635 | mutable: stat.mutability == ast::Mutability::Mut, | |
636 | expr: stat.expr.map(|e| print_const_expr(tcx, e)).unwrap_or_default(), | |
637 | } | |
fc512014 XL |
638 | } |
639 | } | |
640 | ||
cdc7bbd5 XL |
641 | impl FromWithTcx<clean::TraitAlias> for TraitAlias { |
642 | fn from_tcx(alias: clean::TraitAlias, tcx: TyCtxt<'_>) -> Self { | |
fc512014 | 643 | TraitAlias { |
cdc7bbd5 XL |
644 | generics: alias.generics.into_tcx(tcx), |
645 | params: alias.bounds.into_iter().map(|x| x.into_tcx(tcx)).collect(), | |
fc512014 XL |
646 | } |
647 | } | |
648 | } | |
649 | ||
cdc7bbd5 XL |
650 | impl FromWithTcx<ItemType> for ItemKind { |
651 | fn from_tcx(kind: ItemType, _tcx: TyCtxt<'_>) -> Self { | |
fc512014 XL |
652 | use ItemType::*; |
653 | match kind { | |
654 | Module => ItemKind::Module, | |
655 | ExternCrate => ItemKind::ExternCrate, | |
656 | Import => ItemKind::Import, | |
657 | Struct => ItemKind::Struct, | |
658 | Union => ItemKind::Union, | |
659 | Enum => ItemKind::Enum, | |
660 | Function => ItemKind::Function, | |
661 | Typedef => ItemKind::Typedef, | |
662 | OpaqueTy => ItemKind::OpaqueTy, | |
663 | Static => ItemKind::Static, | |
664 | Constant => ItemKind::Constant, | |
665 | Trait => ItemKind::Trait, | |
666 | Impl => ItemKind::Impl, | |
667 | TyMethod | Method => ItemKind::Method, | |
668 | StructField => ItemKind::StructField, | |
669 | Variant => ItemKind::Variant, | |
670 | Macro => ItemKind::Macro, | |
671 | Primitive => ItemKind::Primitive, | |
672 | AssocConst => ItemKind::AssocConst, | |
673 | AssocType => ItemKind::AssocType, | |
674 | ForeignType => ItemKind::ForeignType, | |
675 | Keyword => ItemKind::Keyword, | |
676 | TraitAlias => ItemKind::TraitAlias, | |
677 | ProcAttribute => ItemKind::ProcAttribute, | |
678 | ProcDerive => ItemKind::ProcDerive, | |
679 | } | |
680 | } | |
681 | } | |
682 | ||
683 | fn ids(items: impl IntoIterator<Item = clean::Item>) -> Vec<Id> { | |
136023e0 | 684 | items.into_iter().filter(|x| !x.is_stripped()).map(|i| from_item_id(i.def_id)).collect() |
fc512014 | 685 | } |