-
-// We walk the HIR rather than the AST when reading items from metadata.
-impl<'ast> Visitor<'ast> for DefCollector<'ast> {
- fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'ast> {
- // note however that we override `visit_body` below
- NestedVisitorMap::None
- }
-
- fn visit_body(&mut self, id: hir::ExprId) {
- if let Some(krate) = self.hir_crate {
- self.visit_expr(krate.expr(id));
- }
- }
-
- fn visit_item(&mut self, i: &'ast hir::Item) {
- debug!("visit_item: {:?}", i);
-
- // Pick the def data. This need not be unique, but the more
- // information we encapsulate into
- let def_data = match i.node {
- hir::ItemDefaultImpl(..) | hir::ItemImpl(..) =>
- DefPathData::Impl,
- hir::ItemEnum(..) | hir::ItemStruct(..) | hir::ItemUnion(..) |
- hir::ItemTrait(..) | hir::ItemExternCrate(..) | hir::ItemMod(..) |
- hir::ItemForeignMod(..) | hir::ItemTy(..) =>
- DefPathData::TypeNs(i.name.as_str()),
- hir::ItemStatic(..) | hir::ItemConst(..) | hir::ItemFn(..) =>
- DefPathData::ValueNs(i.name.as_str()),
- hir::ItemUse(..) => DefPathData::Misc,
- };
- let def = self.create_def(i.id, def_data);
-
- self.with_parent(def, |this| {
- match i.node {
- hir::ItemEnum(ref enum_definition, _) => {
- for v in &enum_definition.variants {
- let variant_def_index =
- this.create_def(v.node.data.id(),
- DefPathData::EnumVariant(v.node.name.as_str()));
-
- this.with_parent(variant_def_index, |this| {
- for field in v.node.data.fields() {
- this.create_def(field.id,
- DefPathData::Field(field.name.as_str()));
- }
- if let Some(ref expr) = v.node.disr_expr {
- this.visit_hir_const_integer(expr);
- }
- });
- }
- }
- hir::ItemStruct(ref struct_def, _) |
- hir::ItemUnion(ref struct_def, _) => {
- // If this is a tuple-like struct, register the constructor.
- if !struct_def.is_struct() {
- this.create_def(struct_def.id(),
- DefPathData::StructCtor);
- }
-
- for field in struct_def.fields() {
- this.create_def(field.id, DefPathData::Field(field.name.as_str()));
- }
- }
- _ => {}
- }
- intravisit::walk_item(this, i);
- });
- }
-
- fn visit_foreign_item(&mut self, foreign_item: &'ast hir::ForeignItem) {
- let def = self.create_def(foreign_item.id,
- DefPathData::ValueNs(foreign_item.name.as_str()));
-
- self.with_parent(def, |this| {
- intravisit::walk_foreign_item(this, foreign_item);
- });
- }
-
- fn visit_generics(&mut self, generics: &'ast hir::Generics) {
- for ty_param in generics.ty_params.iter() {
- self.create_def(ty_param.id, DefPathData::TypeParam(ty_param.name.as_str()));
- }
-
- intravisit::walk_generics(self, generics);
- }
-
- fn visit_trait_item(&mut self, ti: &'ast hir::TraitItem) {
- let def_data = match ti.node {
- hir::MethodTraitItem(..) | hir::ConstTraitItem(..) =>
- DefPathData::ValueNs(ti.name.as_str()),
- hir::TypeTraitItem(..) => DefPathData::TypeNs(ti.name.as_str()),
- };
-
- let def = self.create_def(ti.id, def_data);
- self.with_parent(def, |this| {
- if let hir::ConstTraitItem(_, Some(ref expr)) = ti.node {
- this.create_def(expr.id, DefPathData::Initializer);
- }
-
- intravisit::walk_trait_item(this, ti);
- });
- }
-
- fn visit_impl_item(&mut self, ii: &'ast hir::ImplItem) {
- let def_data = match ii.node {
- hir::ImplItemKind::Method(..) | hir::ImplItemKind::Const(..) =>
- DefPathData::ValueNs(ii.name.as_str()),
- hir::ImplItemKind::Type(..) => DefPathData::TypeNs(ii.name.as_str()),
- };
-
- let def = self.create_def(ii.id, def_data);
- self.with_parent(def, |this| {
- if let hir::ImplItemKind::Const(_, ref expr) = ii.node {
- this.create_def(expr.id, DefPathData::Initializer);
- }
-
- intravisit::walk_impl_item(this, ii);
- });
- }
-
- fn visit_pat(&mut self, pat: &'ast hir::Pat) {
- let parent_def = self.parent_def;
-
- if let hir::PatKind::Binding(_, _, name, _) = pat.node {
- let def = self.create_def(pat.id, DefPathData::Binding(name.node.as_str()));
- self.parent_def = Some(def);
- }
-
- intravisit::walk_pat(self, pat);
- self.parent_def = parent_def;
- }
-
- fn visit_expr(&mut self, expr: &'ast hir::Expr) {
- let parent_def = self.parent_def;
-
- if let hir::ExprRepeat(_, ref count) = expr.node {
- self.visit_hir_const_integer(count);
- }
-
- if let hir::ExprClosure(..) = expr.node {
- let def = self.create_def(expr.id, DefPathData::ClosureExpr);
- self.parent_def = Some(def);
- }
-
- intravisit::walk_expr(self, expr);
- self.parent_def = parent_def;
- }
-
- fn visit_ty(&mut self, ty: &'ast hir::Ty) {
- if let hir::TyArray(_, ref length) = ty.node {
- self.visit_hir_const_integer(length);
- }
- if let hir::TyImplTrait(..) = ty.node {
- self.create_def(ty.id, DefPathData::ImplTrait);
- }
- intravisit::walk_ty(self, ty);
- }
-
- fn visit_lifetime_def(&mut self, def: &'ast hir::LifetimeDef) {
- self.create_def(def.lifetime.id, DefPathData::LifetimeDef(def.lifetime.name.as_str()));
- }
-
- fn visit_macro_def(&mut self, macro_def: &'ast hir::MacroDef) {
- self.create_def(macro_def.id, DefPathData::MacroDef(macro_def.name.as_str()));
- }
-}