diff --git a/src/librustc_save_analysis/data.rs b/src/librustc_save_analysis/data.rs index 493f7669337..b8827657888 100644 --- a/src/librustc_save_analysis/data.rs +++ b/src/librustc_save_analysis/data.rs @@ -13,8 +13,9 @@ //! The `Dump` trait can be used together with `DumpVisitor` in order to //! retrieve the data from a crate. +use rustc::hir; use rustc::hir::def_id::DefId; -use syntax::ast::{CrateNum, NodeId}; +use syntax::ast::{self, CrateNum, NodeId}; use syntax_pos::Span; pub struct CrateData { @@ -76,6 +77,35 @@ pub enum Data { VariableRefData(VariableRefData), } +#[derive(Eq, PartialEq, Clone, Copy, Debug, RustcEncodable)] +pub enum Visibility { + Public, + Restricted, + Inherited, +} + +impl<'a> From<&'a ast::Visibility> for Visibility { + fn from(v: &'a ast::Visibility) -> Visibility { + match *v { + ast::Visibility::Public => Visibility::Public, + ast::Visibility::Crate(_) => Visibility::Restricted, + ast::Visibility::Restricted { .. } => Visibility::Restricted, + ast::Visibility::Inherited => Visibility::Inherited, + } + } +} + +impl<'a> From<&'a hir::Visibility> for Visibility { + fn from(v: &'a hir::Visibility) -> Visibility { + match *v { + hir::Visibility::Public => Visibility::Public, + hir::Visibility::Crate => Visibility::Restricted, + hir::Visibility::Restricted { .. } => Visibility::Restricted, + hir::Visibility::Inherited => Visibility::Inherited, + } + } +} + /// Data for the prelude of a crate. #[derive(Debug, RustcEncodable)] pub struct CratePreludeData { @@ -103,7 +133,7 @@ pub struct EnumData { pub span: Span, pub scope: NodeId, pub variants: Vec, - + pub visibility: Visibility, } /// Data for extern crates. @@ -135,6 +165,7 @@ pub struct FunctionData { pub span: Span, pub scope: NodeId, pub value: String, + pub visibility: Visibility, } /// Data about a function call. @@ -215,6 +246,7 @@ pub struct MethodData { pub scope: NodeId, pub value: String, pub decl_id: Option, + pub visibility: Visibility, } /// Data for modules. @@ -227,6 +259,7 @@ pub struct ModData { pub scope: NodeId, pub filename: String, pub items: Vec, + pub visibility: Visibility, } /// Data for a reference to a module. @@ -248,6 +281,7 @@ pub struct StructData { pub scope: NodeId, pub value: String, pub fields: Vec, + pub visibility: Visibility, } #[derive(Debug, RustcEncodable)] @@ -270,6 +304,7 @@ pub struct TraitData { pub scope: NodeId, pub value: String, pub items: Vec, + pub visibility: Visibility, } #[derive(Debug, RustcEncodable)] @@ -291,6 +326,7 @@ pub struct TypeDefData { pub span: Span, pub qualname: String, pub value: String, + pub visibility: Visibility, } /// Data for a reference to a type or trait. @@ -308,7 +344,8 @@ pub struct UseData { pub span: Span, pub name: String, pub mod_id: Option, - pub scope: NodeId + pub scope: NodeId, + pub visibility: Visibility, } #[derive(Debug, RustcEncodable)] @@ -316,7 +353,8 @@ pub struct UseGlobData { pub id: NodeId, pub span: Span, pub names: Vec, - pub scope: NodeId + pub scope: NodeId, + pub visibility: Visibility, } /// Data for local and global variables (consts and statics). @@ -330,6 +368,7 @@ pub struct VariableData { pub scope: NodeId, pub value: String, pub type_value: String, + pub visibility: Visibility, } #[derive(Debug, RustcEncodable)] diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index dbe956f021e..e0475bfed93 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -364,7 +364,8 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { qualname: format!("{}::{}", qualname, path_to_string(p)), type_value: typ, value: String::new(), - scope: 0 + scope: 0, + visibility: Visibility::Inherited, }.lower(self.tcx)); } } @@ -376,6 +377,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { body: Option<&ast::Block>, id: ast::NodeId, name: ast::Name, + vis: Visibility, span: Span) { debug!("process_method: {}:{}", id, name); @@ -416,6 +418,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { qualname: method_data.qualname.clone(), value: sig_str, decl_id: decl_id, + visibility: vis, }.lower(self.tcx)); } @@ -483,7 +486,8 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { name: name, id: param.id, qualname: qualname, - value: String::new() + value: String::new(), + visibility: Visibility::Inherited, }.lower(self.tcx)); } } @@ -532,7 +536,8 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { name: ast::Name, span: Span, typ: &ast::Ty, - expr: &ast::Expr) { + expr: &ast::Expr, + vis: Visibility) { let qualname = format!("::{}", self.tcx.node_path_str(id)); let sub_span = self.span.sub_span_after_keyword(span, keywords::Const); @@ -546,7 +551,8 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { qualname: qualname, value: self.span.snippet(expr.span), type_value: ty_to_string(&typ), - scope: self.cur_scope + scope: self.cur_scope, + visibility: vis, }.lower(self.tcx)); } @@ -588,6 +594,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { scope: self.cur_scope, value: val, fields: fields, + visibility: From::from(&item.vis), }.lower(self.tcx)); } @@ -744,6 +751,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { scope: self.cur_scope, value: val, items: methods.iter().map(|i| i.id).collect(), + visibility: From::from(&item.vis), }.lower(self.tcx)); } @@ -989,7 +997,8 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { qualname: format!("{}${}", path_to_string(p), id), value: value, type_value: typ, - scope: 0 + scope: 0, + visibility: Visibility::Inherited, }.lower(self.tcx)); } } @@ -1072,7 +1081,8 @@ impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor for DumpVisitor<'l, 'tcx, 'll, D> id: item.id, mod_id: mod_id, name: ident.to_string(), - scope: self.cur_scope + scope: self.cur_scope, + visibility: From::from(&item.vis), }.lower(self.tcx)); } self.write_sub_paths_truncated(path, true); @@ -1095,7 +1105,8 @@ impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor for DumpVisitor<'l, 'tcx, 'll, D> span: sub_span.expect("No span found for use glob"), id: item.id, names: names, - scope: self.cur_scope + scope: self.cur_scope, + visibility: From::from(&item.vis), }.lower(self.tcx)); } self.write_sub_paths(path, true); @@ -1167,7 +1178,8 @@ impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor for DumpVisitor<'l, 'tcx, 'll, D> name: item.ident.to_string(), id: item.id, qualname: qualname.clone(), - value: value + value: value, + visibility: From::from(&item.vis), }.lower(self.tcx)); } @@ -1200,13 +1212,15 @@ impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor for DumpVisitor<'l, 'tcx, 'll, D> trait_item.ident.name, trait_item.span, &ty, - &expr); + &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) | @@ -1223,13 +1237,15 @@ impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor for DumpVisitor<'l, 'tcx, 'll, D> impl_item.ident.name, impl_item.span, &ty, - &expr); + &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(_) | @@ -1399,7 +1415,8 @@ impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor for DumpVisitor<'l, 'tcx, 'll, D> qualname: format!("{}${}", path_to_string(p), id), value: value, type_value: String::new(), - scope: 0 + scope: 0, + visibility: Visibility::Inherited, }.lower(self.tcx)); } } diff --git a/src/librustc_save_analysis/external_data.rs b/src/librustc_save_analysis/external_data.rs index 65e4f7e869b..b7dded7b624 100644 --- a/src/librustc_save_analysis/external_data.rs +++ b/src/librustc_save_analysis/external_data.rs @@ -15,7 +15,7 @@ use syntax::ast::{CrateNum, NodeId}; use syntax::codemap::CodeMap; use syntax_pos::Span; -use data; +use data::{self, Visibility}; // FIXME: this should be pub(crate), but the current snapshot doesn't allow it yet pub trait Lower { @@ -91,7 +91,8 @@ pub struct EnumData { pub qualname: String, pub span: SpanData, pub scope: DefId, - pub variants: Vec + pub variants: Vec, + pub visibility: Visibility, } impl Lower for data::EnumData { @@ -106,6 +107,7 @@ impl Lower for data::EnumData { span: SpanData::from_span(self.span, tcx.sess.codemap()), scope: make_def_id(self.scope, &tcx.map), variants: self.variants.into_iter().map(|id| make_def_id(id, &tcx.map)).collect(), + visibility: self.visibility, } } } @@ -166,6 +168,7 @@ pub struct FunctionData { pub span: SpanData, pub scope: DefId, pub value: String, + pub visibility: Visibility, } impl Lower for data::FunctionData { @@ -180,6 +183,7 @@ impl Lower for data::FunctionData { span: SpanData::from_span(self.span, tcx.sess.codemap()), scope: make_def_id(self.scope, &tcx.map), value: self.value, + visibility: self.visibility, } } } @@ -323,6 +327,7 @@ pub struct MethodData { pub scope: DefId, pub value: String, pub decl_id: Option, + pub visibility: Visibility, } impl Lower for data::MethodData { @@ -337,6 +342,7 @@ impl Lower for data::MethodData { qualname: self.qualname, value: self.value, decl_id: self.decl_id, + visibility: self.visibility, } } } @@ -351,6 +357,7 @@ pub struct ModData { pub scope: DefId, pub filename: String, pub items: Vec, + pub visibility: Visibility, } impl Lower for data::ModData { @@ -365,6 +372,7 @@ impl Lower for data::ModData { scope: make_def_id(self.scope, &tcx.map), filename: self.filename, items: self.items.into_iter().map(|id| make_def_id(id, &tcx.map)).collect(), + visibility: self.visibility, } } } @@ -401,6 +409,7 @@ pub struct StructData { pub scope: DefId, pub value: String, pub fields: Vec, + pub visibility: Visibility, } impl Lower for data::StructData { @@ -416,6 +425,7 @@ impl Lower for data::StructData { scope: make_def_id(self.scope, &tcx.map), value: self.value, fields: self.fields.into_iter().map(|id| make_def_id(id, &tcx.map)).collect(), + visibility: self.visibility, } } } @@ -456,6 +466,7 @@ pub struct TraitData { pub scope: DefId, pub value: String, pub items: Vec, + pub visibility: Visibility, } impl Lower for data::TraitData { @@ -470,6 +481,7 @@ impl Lower for data::TraitData { scope: make_def_id(self.scope, &tcx.map), value: self.value, items: self.items.into_iter().map(|id| make_def_id(id, &tcx.map)).collect(), + visibility: self.visibility, } } } @@ -509,6 +521,7 @@ pub struct TypeDefData { pub span: SpanData, pub qualname: String, pub value: String, + pub visibility: Visibility, } impl Lower for data::TypeDefData { @@ -521,6 +534,7 @@ impl Lower for data::TypeDefData { span: SpanData::from_span(self.span, tcx.sess.codemap()), qualname: self.qualname, value: self.value, + visibility: self.visibility, } } } @@ -553,7 +567,8 @@ pub struct UseData { pub span: SpanData, pub name: String, pub mod_id: Option, - pub scope: DefId + pub scope: DefId, + pub visibility: Visibility, } impl Lower for data::UseData { @@ -566,6 +581,7 @@ impl Lower for data::UseData { name: self.name, mod_id: self.mod_id, scope: make_def_id(self.scope, &tcx.map), + visibility: self.visibility, } } } @@ -575,7 +591,8 @@ pub struct UseGlobData { pub id: DefId, pub span: SpanData, pub names: Vec, - pub scope: DefId + pub scope: DefId, + pub visibility: Visibility, } impl Lower for data::UseGlobData { @@ -587,6 +604,7 @@ impl Lower for data::UseGlobData { span: SpanData::from_span(self.span, tcx.sess.codemap()), names: self.names, scope: make_def_id(self.scope, &tcx.map), + visibility: self.visibility, } } } @@ -602,6 +620,7 @@ pub struct VariableData { pub scope: DefId, pub value: String, pub type_value: String, + pub visibility: Visibility, } impl Lower for data::VariableData { @@ -617,6 +636,7 @@ impl Lower for data::VariableData { scope: make_def_id(self.scope, &tcx.map), value: self.value, type_value: self.type_value, + visibility: self.visibility, } } } diff --git a/src/librustc_save_analysis/json_api_dumper.rs b/src/librustc_save_analysis/json_api_dumper.rs index e92c23d7d7c..9cc1badf7cd 100644 --- a/src/librustc_save_analysis/json_api_dumper.rs +++ b/src/librustc_save_analysis/json_api_dumper.rs @@ -14,7 +14,7 @@ use rustc::hir::def_id::DefId; use rustc_serialize::json::as_json; use external_data::*; -use data::VariableKind; +use data::{VariableKind, Visibility}; use dump::Dump; pub struct JsonApiDumper<'b, W: Write + 'b> { @@ -123,24 +123,30 @@ enum ImportKind { impl From for Option { fn from(data: UseData) -> Option { - Some(Import { - kind: ImportKind::Use, - id: From::from(data.id), - span: data.span, - name: data.name, - value: String::new(), - }) + match data.visibility { + Visibility::Public => Some(Import { + kind: ImportKind::Use, + id: From::from(data.id), + span: data.span, + name: data.name, + value: String::new(), + }), + _ => None, + } } } impl From for Option { fn from(data: UseGlobData) -> Option { - Some(Import { - kind: ImportKind::GlobUse, - id: From::from(data.id), - span: data.span, - name: "*".to_owned(), - value: data.names.join(", "), - }) + match data.visibility { + Visibility::Public => Some(Import { + kind: ImportKind::GlobUse, + id: From::from(data.id), + span: data.span, + name: "*".to_owned(), + value: data.names.join(", "), + }), + _ => None, + } } } @@ -185,17 +191,20 @@ enum DefKind { impl From for Option { fn from(data: EnumData) -> Option { - Some(Def { - kind: DefKind::Enum, - id: From::from(data.id), - span: data.span, - name: data.name, - qualname: data.qualname, - value: data.value, - parent: None, - children: data.variants.into_iter().map(|id| From::from(id)).collect(), - decl_id: None, - }) + match data.visibility { + Visibility::Public => Some(Def { + kind: DefKind::Enum, + id: From::from(data.id), + span: data.span, + name: data.name, + qualname: data.qualname, + value: data.value, + parent: None, + children: data.variants.into_iter().map(|id| From::from(id)).collect(), + decl_id: None, + }), + _ => None, + } } } @@ -231,7 +240,8 @@ impl From for Option { } impl From for Option { fn from(data: StructData) -> Option { - Some(Def { + match data.visibility { + Visibility::Public => Some(Def { kind: DefKind::Struct, id: From::from(data.id), span: data.span, @@ -241,52 +251,63 @@ impl From for Option { parent: None, children: data.fields.into_iter().map(|id| From::from(id)).collect(), decl_id: None, - }) + }), + _ => None, + } } } impl From for Option { fn from(data: TraitData) -> Option { - Some(Def { - kind: DefKind::Trait, - id: From::from(data.id), - span: data.span, - name: data.name, - qualname: data.qualname, - value: data.value, - children: data.items.into_iter().map(|id| From::from(id)).collect(), - parent: None, - decl_id: None, - }) + match data.visibility { + Visibility::Public => Some(Def { + kind: DefKind::Trait, + id: From::from(data.id), + span: data.span, + name: data.name, + qualname: data.qualname, + value: data.value, + children: data.items.into_iter().map(|id| From::from(id)).collect(), + parent: None, + decl_id: None, + }), + _ => None, + } } } impl From for Option { fn from(data: FunctionData) -> Option { - Some(Def { - kind: DefKind::Function, - id: From::from(data.id), - span: data.span, - name: data.name, - qualname: data.qualname, - value: data.value, - children: vec![], - parent: None, - decl_id: None, - }) + match data.visibility { + Visibility::Public => Some(Def { + kind: DefKind::Function, + id: From::from(data.id), + span: data.span, + name: data.name, + qualname: data.qualname, + value: data.value, + children: vec![], + parent: None, + decl_id: None, + }), + _ => None, + } } } impl From for Option { fn from(data: MethodData) -> Option { - Some(Def { - kind: DefKind::Method, - id: From::from(data.id), - span: data.span, - name: data.name, - qualname: data.qualname, - value: data.value, - children: vec![], - parent: None, - decl_id: data.decl_id.map(|id| From::from(id)), - }) + match data.visibility { + Visibility::Public => Some(Def { + kind: DefKind::Method, + id: From::from(data.id), + span: data.span, + name: data.name, + qualname: data.qualname, + value: data.value, + children: vec![], + parent: None, + decl_id: data.decl_id.map(|id| From::from(id)), + }), + _ => None, + } } } impl From for Option { @@ -306,51 +327,60 @@ impl From for Option { } impl From for Option { fn from(data:ModData) -> Option { - Some(Def { - kind: DefKind::Mod, - id: From::from(data.id), - span: data.span, - name: data.name, - qualname: data.qualname, - value: data.filename, - children: data.items.into_iter().map(|id| From::from(id)).collect(), - parent: None, - decl_id: None, - }) + match data.visibility { + Visibility::Public => Some(Def { + kind: DefKind::Mod, + id: From::from(data.id), + span: data.span, + name: data.name, + qualname: data.qualname, + value: data.filename, + children: data.items.into_iter().map(|id| From::from(id)).collect(), + parent: None, + decl_id: None, + }), + _ => None, + } } } impl From for Option { fn from(data: TypeDefData) -> Option { - Some(Def { - kind: DefKind::Type, - id: From::from(data.id), - span: data.span, - name: data.name, - qualname: data.qualname, - value: data.value, - children: vec![], - parent: None, - decl_id: None, - }) + match data.visibility { + Visibility::Public => Some(Def { + kind: DefKind::Type, + id: From::from(data.id), + span: data.span, + name: data.name, + qualname: data.qualname, + value: data.value, + children: vec![], + parent: None, + decl_id: None, + }), + _ => None, + } } } impl From for Option { fn from(data: VariableData) -> Option { - Some(Def { - kind: match data.kind { - VariableKind::Static => DefKind::Static, - VariableKind::Const => DefKind::Const, - VariableKind::Local => { return None } - VariableKind::Field => DefKind::Field, - }, - id: From::from(data.id), - span: data.span, - name: data.name, - qualname: data.qualname, - value: data.value, - children: vec![], - parent: None, - decl_id: None, - }) + match data.visibility { + Visibility::Public => Some(Def { + kind: match data.kind { + VariableKind::Static => DefKind::Static, + VariableKind::Const => DefKind::Const, + VariableKind::Local => { return None } + VariableKind::Field => DefKind::Field, + }, + id: From::from(data.id), + span: data.span, + name: data.name, + qualname: data.qualname, + value: data.value, + children: vec![], + parent: None, + decl_id: None, + }), + _ => None, + } } } diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 5aa8bec3d36..3645eb68394 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -140,6 +140,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { span: sub_span.unwrap(), scope: self.enclosing_scope(item.id), value: make_signature(decl, generics), + visibility: From::from(&item.vis), })) } ast::ItemKind::Static(ref typ, mt, ref expr) => { @@ -164,6 +165,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { scope: self.enclosing_scope(item.id), value: value, type_value: ty_to_string(&typ), + visibility: From::from(&item.vis), })) } ast::ItemKind::Const(ref typ, ref expr) => { @@ -179,6 +181,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { scope: self.enclosing_scope(item.id), value: self.span_utils.snippet(expr.span), type_value: ty_to_string(&typ), + visibility: From::from(&item.vis), })) } ast::ItemKind::Mod(ref m) => { @@ -197,6 +200,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { scope: self.enclosing_scope(item.id), filename: filename, items: m.items.iter().map(|i| i.id).collect(), + visibility: From::from(&item.vis), })) } ast::ItemKind::Enum(ref def, _) => { @@ -217,6 +221,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { qualname: qualname, scope: self.enclosing_scope(item.id), variants: def.variants.iter().map(|v| v.node.data.id()).collect(), + visibility: From::from(&item.vis), })) } ast::ItemKind::Impl(_, _, _, ref trait_ref, ref typ, _) => { @@ -281,6 +286,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { scope: scope, value: "".to_owned(), type_value: typ, + visibility: From::from(&field.vis), }) } else { None @@ -293,7 +299,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { name: ast::Name, span: Span) -> Option { // The qualname for a method is the trait name or name of the struct in an impl in // which the method is declared in, followed by the method's name. - let qualname = match self.tcx.impl_of_method(self.tcx.map.local_def_id(id)) { + let (qualname, vis) = match self.tcx.impl_of_method(self.tcx.map.local_def_id(id)) { Some(impl_id) => match self.tcx.map.get_if_local(impl_id) { Some(NodeItem(item)) => { match item.node { @@ -306,7 +312,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { result.push_str(&self.tcx.item_path_str(def_id)); } result.push_str(">"); - result + (result, From::from(&item.vis)) } _ => { span_bug!(span, @@ -327,8 +333,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { None => match self.tcx.trait_of_item(self.tcx.map.local_def_id(id)) { Some(def_id) => { match self.tcx.map.get_if_local(def_id) { - Some(NodeItem(_)) => { - format!("::{}", self.tcx.item_path_str(def_id)) + Some(NodeItem(item)) => { + (format!("::{}", self.tcx.item_path_str(def_id)), From::from(&item.vis)) } r => { span_bug!(span, @@ -369,6 +375,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { scope: self.enclosing_scope(id), // FIXME you get better data here by using the visitor. value: String::new(), + visibility: vis, }) }