fn keep_ast(sess: &Session) -> bool {
sess.opts.debugging_opts.keep_ast ||
sess.opts.debugging_opts.save_analysis ||
- sess.opts.debugging_opts.save_analysis_csv
+ sess.opts.debugging_opts.save_analysis_csv ||
+ sess.opts.debugging_opts.save_analysis_api
}
/// The name used for source code that doesn't originate in a file
pub scope: NodeId,
pub value: String,
pub visibility: Visibility,
+ pub parent: Option<NodeId>,
}
/// Data about a function call.
pub qualname: String,
pub type_value: String,
pub value: String,
- pub scope: NodeId
+ pub scope: NodeId,
+ pub parent: Option<NodeId>,
}
#[derive(Debug, RustcEncodable)]
pub qualname: String,
pub type_value: String,
pub value: String,
- pub scope: NodeId
+ pub scope: NodeId,
+ pub parent: Option<NodeId>,
}
/// Data for a typedef.
pub qualname: String,
pub value: String,
pub visibility: Visibility,
+ pub parent: Option<NodeId>,
}
/// Data for a reference to a type or trait.
pub qualname: String,
pub span: Span,
pub scope: NodeId,
+ pub parent: Option<NodeId>,
pub value: String,
pub type_value: String,
pub visibility: Visibility,
type_value: typ,
value: String::new(),
scope: 0,
+ parent: None,
visibility: Visibility::Inherited,
}.lower(self.tcx));
}
qualname: qualname,
value: String::new(),
visibility: Visibility::Inherited,
+ parent: None,
}.lower(self.tcx));
}
}
self.visit_expr(expr);
}
- fn process_const(&mut self,
- id: ast::NodeId,
- name: ast::Name,
- span: Span,
- typ: &ast::Ty,
- expr: &ast::Expr,
- vis: Visibility) {
+ fn process_assoc_const(&mut self,
+ id: ast::NodeId,
+ name: ast::Name,
+ span: Span,
+ typ: &ast::Ty,
+ expr: &ast::Expr,
+ parent_id: NodeId,
+ vis: Visibility) {
let qualname = format!("::{}", self.tcx.node_path_str(id));
let sub_span = self.span.sub_span_after_keyword(span, keywords::Const);
value: self.span.snippet(expr.span),
type_value: ty_to_string(&typ),
scope: self.cur_scope,
+ parent: Some(parent_id),
visibility: vis,
}.lower(self.tcx));
}
qualname: qualname,
type_value: enum_data.qualname.clone(),
value: val,
- scope: enum_data.scope
+ scope: enum_data.scope,
+ parent: Some(item.id),
}.lower(self.tcx));
}
}
qualname: qualname,
type_value: enum_data.qualname.clone(),
value: val,
- scope: enum_data.scope
+ scope: enum_data.scope,
+ parent: Some(item.id),
}.lower(self.tcx));
}
}
}
self.process_generic_params(type_parameters, item.span, "", item.id);
for impl_item in impl_items {
- self.visit_impl_item(impl_item);
+ self.process_impl_item(impl_item, item.id);
}
}
// walk generics and methods
self.process_generic_params(generics, item.span, &qualname, item.id);
for method in methods {
- self.visit_trait_item(method)
+ self.process_trait_item(method, item.id)
}
}
value: value,
type_value: typ,
scope: 0,
+ parent: None,
visibility: Visibility::Inherited,
}.lower(self.tcx));
}
}
}
}
+
+ fn process_trait_item(&mut self, trait_item: &ast::TraitItem, trait_id: NodeId) {
+ self.process_macro_use(trait_item.span, trait_item.id);
+ match trait_item.node {
+ ast::TraitItemKind::Const(ref ty, Some(ref expr)) => {
+ self.process_assoc_const(trait_item.id,
+ trait_item.ident.name,
+ trait_item.span,
+ &ty,
+ &expr,
+ trait_id,
+ Visibility::Public);
+ }
+ ast::TraitItemKind::Method(ref sig, ref body) => {
+ self.process_method(sig,
+ body.as_ref().map(|x| &**x),
+ trait_item.id,
+ trait_item.ident.name,
+ Visibility::Public,
+ trait_item.span);
+ }
+ ast::TraitItemKind::Const(_, None) |
+ ast::TraitItemKind::Type(..) |
+ ast::TraitItemKind::Macro(_) => {}
+ }
+ }
+
+ fn process_impl_item(&mut self, impl_item: &ast::ImplItem, impl_id: NodeId) {
+ self.process_macro_use(impl_item.span, impl_item.id);
+ match impl_item.node {
+ ast::ImplItemKind::Const(ref ty, ref expr) => {
+ self.process_assoc_const(impl_item.id,
+ impl_item.ident.name,
+ impl_item.span,
+ &ty,
+ &expr,
+ impl_id,
+ From::from(&impl_item.vis));
+ }
+ ast::ImplItemKind::Method(ref sig, ref body) => {
+ self.process_method(sig,
+ Some(body),
+ impl_item.id,
+ impl_item.ident.name,
+ From::from(&impl_item.vis),
+ impl_item.span);
+ }
+ ast::ImplItemKind::Type(_) |
+ ast::ImplItemKind::Macro(_) => {}
+ }
+ }
}
impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor for DumpVisitor<'l, 'tcx, 'll, D> {
qualname: qualname.clone(),
value: value,
visibility: From::from(&item.vis),
+ parent: None,
}.lower(self.tcx));
}
}
}
- fn visit_trait_item(&mut self, trait_item: &ast::TraitItem) {
- self.process_macro_use(trait_item.span, trait_item.id);
- match trait_item.node {
- ast::TraitItemKind::Const(ref ty, Some(ref expr)) => {
- self.process_const(trait_item.id,
- trait_item.ident.name,
- trait_item.span,
- &ty,
- &expr,
- Visibility::Public);
- }
- ast::TraitItemKind::Method(ref sig, ref body) => {
- self.process_method(sig,
- body.as_ref().map(|x| &**x),
- trait_item.id,
- trait_item.ident.name,
- Visibility::Public,
- trait_item.span);
- }
- ast::TraitItemKind::Const(_, None) |
- ast::TraitItemKind::Type(..) |
- ast::TraitItemKind::Macro(_) => {}
- }
- }
-
- fn visit_impl_item(&mut self, impl_item: &ast::ImplItem) {
- self.process_macro_use(impl_item.span, impl_item.id);
- match impl_item.node {
- ast::ImplItemKind::Const(ref ty, ref expr) => {
- self.process_const(impl_item.id,
- impl_item.ident.name,
- impl_item.span,
- &ty,
- &expr,
- From::from(&impl_item.vis));
- }
- ast::ImplItemKind::Method(ref sig, ref body) => {
- self.process_method(sig,
- Some(body),
- impl_item.id,
- impl_item.ident.name,
- From::from(&impl_item.vis),
- impl_item.span);
- }
- ast::ImplItemKind::Type(_) |
- ast::ImplItemKind::Macro(_) => {}
- }
- }
-
fn visit_ty(&mut self, t: &ast::Ty) {
self.process_macro_use(t.span, t.id);
match t.node {
value: value,
type_value: String::new(),
scope: 0,
+ parent: None,
visibility: Visibility::Inherited,
}.lower(self.tcx));
}
pub scope: DefId,
pub value: String,
pub visibility: Visibility,
+ pub parent: Option<DefId>,
}
impl Lower for data::FunctionData {
scope: make_def_id(self.scope, &tcx.map),
value: self.value,
visibility: self.visibility,
+ parent: self.parent.map(|id| make_def_id(id, &tcx.map)),
}
}
}
pub value: String,
pub decl_id: Option<DefId>,
pub visibility: Visibility,
+ pub parent: Option<DefId>
}
impl Lower for data::MethodData {
value: self.value,
decl_id: self.decl_id,
visibility: self.visibility,
+ parent: Some(make_def_id(self.scope, &tcx.map)),
}
}
}
pub qualname: String,
pub type_value: String,
pub value: String,
- pub scope: DefId
+ pub scope: DefId,
+ pub parent: Option<DefId>,
}
impl Lower for data::StructVariantData {
type_value: self.type_value,
value: self.value,
scope: make_def_id(self.scope, &tcx.map),
+ parent: self.parent.map(|id| make_def_id(id, &tcx.map)),
}
}
}
pub type_value: String,
pub value: String,
pub scope: DefId,
+ pub parent: Option<DefId>,
}
impl Lower for data::TupleVariantData {
type_value: self.type_value,
value: self.value,
scope: make_def_id(self.scope, &tcx.map),
+ parent: self.parent.map(|id| make_def_id(id, &tcx.map)),
}
}
}
pub qualname: String,
pub value: String,
pub visibility: Visibility,
+ pub parent: Option<DefId>,
}
impl Lower for data::TypeDefData {
qualname: self.qualname,
value: self.value,
visibility: self.visibility,
+ parent: self.parent.map(|id| make_def_id(id, &tcx.map)),
}
}
}
pub scope: DefId,
pub value: String,
pub type_value: String,
+ pub parent: Option<DefId>,
pub visibility: Visibility,
}
scope: make_def_id(self.scope, &tcx.map),
value: self.value,
type_value: self.type_value,
+ parent: self.parent.map(|id| make_def_id(id, &tcx.map)),
visibility: self.visibility,
}
}
use data::{VariableKind, Visibility};
use dump::Dump;
+// A dumper to dump a restricted set of JSON information, designed for use with
+// libraries distributed without their source. Clients are likely to use type
+// information here, and (for example) generate Rustdoc URLs, but don't need
+// information for navigating the source of the crate.
+// Relative to the regular JSON save-analysis info, this form is filtered to
+// remove non-visible items, but includes some extra info for items (e.g., the
+// parent field for finding the struct to which a field belongs).
pub struct JsonApiDumper<'b, W: Write + 'b> {
output: &'b mut W,
result: Analysis,
name: data.name,
qualname: data.qualname,
value: data.value,
- parent: None,
+ parent: data.parent.map(|id| From::from(id)),
children: vec![],
decl_id: None,
})
name: data.name,
qualname: data.qualname,
value: data.value,
- parent: None,
+ parent: data.parent.map(|id| From::from(id)),
children: vec![],
decl_id: None,
})
qualname: data.qualname,
value: data.value,
children: vec![],
- parent: None,
+ parent: data.parent.map(|id| From::from(id)),
decl_id: None,
}),
_ => None,
qualname: data.qualname,
value: data.value,
children: vec![],
- parent: None,
+ parent: data.parent.map(|id| From::from(id)),
decl_id: data.decl_id.map(|id| From::from(id)),
}),
_ => None,
qualname: data.qualname,
value: data.value,
children: vec![],
- parent: None,
+ parent: data.parent.map(|id| From::from(id)),
decl_id: None,
}),
_ => None,
qualname: data.qualname,
value: data.value,
children: vec![],
- parent: None,
+ parent: data.parent.map(|id| From::from(id)),
decl_id: None,
}),
_ => None,
scope: self.enclosing_scope(item.id),
value: make_signature(decl, generics),
visibility: From::from(&item.vis),
+ parent: None,
}))
}
ast::ItemKind::Static(ref typ, mt, ref expr) => {
qualname: qualname,
span: sub_span.unwrap(),
scope: self.enclosing_scope(item.id),
+ parent: None,
value: value,
type_value: ty_to_string(&typ),
visibility: From::from(&item.vis),
qualname: qualname,
span: sub_span.unwrap(),
scope: self.enclosing_scope(item.id),
+ parent: None,
value: self.span_utils.snippet(expr.span),
type_value: ty_to_string(&typ),
visibility: From::from(&item.vis),
qualname: qualname,
span: sub_span.unwrap(),
scope: scope,
+ parent: Some(scope),
value: "".to_owned(),
type_value: typ,
visibility: From::from(&field.vis),
let sub_span = self.span_utils.sub_span_after_keyword(span, keywords::Fn);
filter!(self.span_utils, sub_span, span, None);
+ let parent_scope = self.enclosing_scope(id);
Some(FunctionData {
id: id,
name: name.to_string(),
// FIXME you get better data here by using the visitor.
value: String::new(),
visibility: vis,
+ parent: Some(parent_scope),
})
}
code: foo.rs krate2
$(RUSTC) foo.rs -Zsave-analysis-csv
$(RUSTC) foo.rs -Zsave-analysis
+ $(RUSTC) foo.rs -Zsave-analysis-api