mirror of
https://github.com/rust-lang/rust
synced 2024-10-14 12:33:57 +00:00
Auto merge of #38529 - nrc:save-sig, r=nikomatsakis
save-analysis: add signature info These 'signatures' for definitions contain enough info for the RLS to create Rustdoc-style info on the fly.
This commit is contained in:
commit
00b4019f28
|
@ -135,6 +135,7 @@ pub struct EnumData {
|
|||
pub variants: Vec<NodeId>,
|
||||
pub visibility: Visibility,
|
||||
pub docs: String,
|
||||
pub sig: Signature,
|
||||
}
|
||||
|
||||
/// Data for extern crates.
|
||||
|
@ -169,6 +170,7 @@ pub struct FunctionData {
|
|||
pub visibility: Visibility,
|
||||
pub parent: Option<DefId>,
|
||||
pub docs: String,
|
||||
pub sig: Signature,
|
||||
}
|
||||
|
||||
/// Data about a function call.
|
||||
|
@ -253,6 +255,7 @@ pub struct MethodData {
|
|||
pub parent: Option<DefId>,
|
||||
pub visibility: Visibility,
|
||||
pub docs: String,
|
||||
pub sig: Signature,
|
||||
}
|
||||
|
||||
/// Data for modules.
|
||||
|
@ -267,6 +270,7 @@ pub struct ModData {
|
|||
pub items: Vec<NodeId>,
|
||||
pub visibility: Visibility,
|
||||
pub docs: String,
|
||||
pub sig: Signature,
|
||||
}
|
||||
|
||||
/// Data for a reference to a module.
|
||||
|
@ -290,6 +294,7 @@ pub struct StructData {
|
|||
pub fields: Vec<NodeId>,
|
||||
pub visibility: Visibility,
|
||||
pub docs: String,
|
||||
pub sig: Signature,
|
||||
}
|
||||
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
|
@ -303,6 +308,7 @@ pub struct StructVariantData {
|
|||
pub scope: NodeId,
|
||||
pub parent: Option<DefId>,
|
||||
pub docs: String,
|
||||
pub sig: Signature,
|
||||
}
|
||||
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
|
@ -316,6 +322,7 @@ pub struct TraitData {
|
|||
pub items: Vec<NodeId>,
|
||||
pub visibility: Visibility,
|
||||
pub docs: String,
|
||||
pub sig: Signature,
|
||||
}
|
||||
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
|
@ -329,6 +336,7 @@ pub struct TupleVariantData {
|
|||
pub scope: NodeId,
|
||||
pub parent: Option<DefId>,
|
||||
pub docs: String,
|
||||
pub sig: Signature,
|
||||
}
|
||||
|
||||
/// Data for a typedef.
|
||||
|
@ -342,6 +350,7 @@ pub struct TypeDefData {
|
|||
pub visibility: Visibility,
|
||||
pub parent: Option<DefId>,
|
||||
pub docs: String,
|
||||
pub sig: Option<Signature>,
|
||||
}
|
||||
|
||||
/// Data for a reference to a type or trait.
|
||||
|
@ -386,6 +395,7 @@ pub struct VariableData {
|
|||
pub type_value: String,
|
||||
pub visibility: Visibility,
|
||||
pub docs: String,
|
||||
pub sig: Option<Signature>,
|
||||
}
|
||||
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
|
@ -405,3 +415,28 @@ pub struct VariableRefData {
|
|||
pub scope: NodeId,
|
||||
pub ref_id: DefId,
|
||||
}
|
||||
|
||||
|
||||
/// Encodes information about the signature of a definition. This should have
|
||||
/// enough information to create a nice display about a definition without
|
||||
/// access to the source code.
|
||||
#[derive(Clone, Debug, RustcEncodable)]
|
||||
pub struct Signature {
|
||||
pub span: Span,
|
||||
pub text: String,
|
||||
// These identify the main identifier for the defintion as byte offsets into
|
||||
// `text`. E.g., of `foo` in `pub fn foo(...)`
|
||||
pub ident_start: usize,
|
||||
pub ident_end: usize,
|
||||
pub defs: Vec<SigElement>,
|
||||
pub refs: Vec<SigElement>,
|
||||
}
|
||||
|
||||
/// An element of a signature. `start` and `end` are byte offsets into the `text`
|
||||
/// of the parent `Signature`.
|
||||
#[derive(Clone, Debug, RustcEncodable)]
|
||||
pub struct SigElement {
|
||||
pub id: DefId,
|
||||
pub start: usize,
|
||||
pub end: usize,
|
||||
}
|
||||
|
|
|
@ -357,6 +357,7 @@ fn process_formals(&mut self, formals: &'l [ast::Arg], qualname: &str) {
|
|||
parent: None,
|
||||
visibility: Visibility::Inherited,
|
||||
docs: String::new(),
|
||||
sig: None,
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
}
|
||||
|
@ -429,6 +430,7 @@ fn process_method(&mut self,
|
|||
parent: trait_id,
|
||||
visibility: vis,
|
||||
docs: docs_for_attrs(attrs),
|
||||
sig: method_data.sig,
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
|
||||
|
@ -500,6 +502,7 @@ fn process_generic_params(&mut self,
|
|||
visibility: Visibility::Inherited,
|
||||
parent: None,
|
||||
docs: String::new(),
|
||||
sig: None,
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
}
|
||||
|
@ -572,6 +575,7 @@ fn process_assoc_const(&mut self,
|
|||
parent: Some(parent_id),
|
||||
visibility: vis,
|
||||
docs: docs_for_attrs(attrs),
|
||||
sig: None,
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
|
||||
|
@ -615,11 +619,10 @@ fn process_struct(&mut self,
|
|||
fields: fields,
|
||||
visibility: From::from(&item.vis),
|
||||
docs: docs_for_attrs(&item.attrs),
|
||||
sig: self.save_ctxt.sig_base(item),
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
|
||||
|
||||
// fields
|
||||
for field in def.fields() {
|
||||
self.process_struct_field_def(field, item.id);
|
||||
self.visit_ty(&field.ty);
|
||||
|
@ -648,6 +651,18 @@ fn process_enum(&mut self,
|
|||
qualname.push_str("::");
|
||||
qualname.push_str(&name);
|
||||
|
||||
let text = self.span.signature_string_for_span(variant.span);
|
||||
let ident_start = text.find(&name).unwrap();
|
||||
let ident_end = ident_start + name.len();
|
||||
let sig = Signature {
|
||||
span: variant.span,
|
||||
text: text,
|
||||
ident_start: ident_start,
|
||||
ident_end: ident_end,
|
||||
defs: vec![],
|
||||
refs: vec![],
|
||||
};
|
||||
|
||||
match variant.node.data {
|
||||
ast::VariantData::Struct(ref fields, _) => {
|
||||
let sub_span = self.span.span_for_first_ident(variant.span);
|
||||
|
@ -669,6 +684,7 @@ fn process_enum(&mut self,
|
|||
scope: enum_data.scope,
|
||||
parent: Some(make_def_id(item.id, &self.tcx.map)),
|
||||
docs: docs_for_attrs(&variant.node.attrs),
|
||||
sig: sig,
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
}
|
||||
|
@ -694,6 +710,7 @@ fn process_enum(&mut self,
|
|||
scope: enum_data.scope,
|
||||
parent: Some(make_def_id(item.id, &self.tcx.map)),
|
||||
docs: docs_for_attrs(&variant.node.attrs),
|
||||
sig: sig,
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
}
|
||||
|
@ -778,6 +795,7 @@ fn process_trait(&mut self,
|
|||
items: methods.iter().map(|i| i.id).collect(),
|
||||
visibility: From::from(&item.vis),
|
||||
docs: docs_for_attrs(&item.attrs),
|
||||
sig: self.save_ctxt.sig_base(item),
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
|
||||
|
@ -1043,6 +1061,7 @@ fn process_var_decl(&mut self, p: &'l ast::Pat, value: String) {
|
|||
parent: None,
|
||||
visibility: Visibility::Inherited,
|
||||
docs: String::new(),
|
||||
sig: None,
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
}
|
||||
|
@ -1257,10 +1276,10 @@ fn visit_item(&mut self, item: &'l ast::Item) {
|
|||
Struct(ref def, ref ty_params) => self.process_struct(item, def, ty_params),
|
||||
Enum(ref def, ref ty_params) => self.process_enum(item, def, ty_params),
|
||||
Impl(..,
|
||||
ref ty_params,
|
||||
ref trait_ref,
|
||||
ref typ,
|
||||
ref impl_items) => {
|
||||
ref ty_params,
|
||||
ref trait_ref,
|
||||
ref typ,
|
||||
ref impl_items) => {
|
||||
self.process_impl(item, ty_params, trait_ref, &typ, impl_items)
|
||||
}
|
||||
Trait(_, ref generics, ref trait_refs, ref methods) =>
|
||||
|
@ -1283,6 +1302,7 @@ fn visit_item(&mut self, item: &'l ast::Item) {
|
|||
visibility: From::from(&item.vis),
|
||||
parent: None,
|
||||
docs: docs_for_attrs(&item.attrs),
|
||||
sig: Some(self.save_ctxt.sig_base(item)),
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
|
||||
|
@ -1492,6 +1512,7 @@ fn visit_arm(&mut self, arm: &'l ast::Arm) {
|
|||
parent: None,
|
||||
visibility: Visibility::Inherited,
|
||||
docs: String::new(),
|
||||
sig: None,
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
use syntax::codemap::CodeMap;
|
||||
use syntax_pos::Span;
|
||||
|
||||
use data::{self, Visibility};
|
||||
use data::{self, Visibility, SigElement};
|
||||
|
||||
// FIXME: this should be pub(crate), but the current snapshot doesn't allow it yet
|
||||
pub trait Lower {
|
||||
|
@ -97,6 +97,7 @@ pub struct EnumData {
|
|||
pub variants: Vec<DefId>,
|
||||
pub visibility: Visibility,
|
||||
pub docs: String,
|
||||
pub sig: Signature,
|
||||
}
|
||||
|
||||
impl Lower for data::EnumData {
|
||||
|
@ -113,6 +114,7 @@ fn lower(self, tcx: TyCtxt) -> EnumData {
|
|||
variants: self.variants.into_iter().map(|id| make_def_id(id, &tcx.map)).collect(),
|
||||
visibility: self.visibility,
|
||||
docs: self.docs,
|
||||
sig: self.sig.lower(tcx),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -176,6 +178,7 @@ pub struct FunctionData {
|
|||
pub visibility: Visibility,
|
||||
pub parent: Option<DefId>,
|
||||
pub docs: String,
|
||||
pub sig: Signature,
|
||||
}
|
||||
|
||||
impl Lower for data::FunctionData {
|
||||
|
@ -193,6 +196,7 @@ fn lower(self, tcx: TyCtxt) -> FunctionData {
|
|||
visibility: self.visibility,
|
||||
parent: self.parent,
|
||||
docs: self.docs,
|
||||
sig: self.sig.lower(tcx),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -341,6 +345,7 @@ pub struct MethodData {
|
|||
pub visibility: Visibility,
|
||||
pub parent: Option<DefId>,
|
||||
pub docs: String,
|
||||
pub sig: Signature,
|
||||
}
|
||||
|
||||
impl Lower for data::MethodData {
|
||||
|
@ -358,6 +363,7 @@ fn lower(self, tcx: TyCtxt) -> MethodData {
|
|||
visibility: self.visibility,
|
||||
parent: self.parent,
|
||||
docs: self.docs,
|
||||
sig: self.sig.lower(tcx),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -374,6 +380,7 @@ pub struct ModData {
|
|||
pub items: Vec<DefId>,
|
||||
pub visibility: Visibility,
|
||||
pub docs: String,
|
||||
pub sig: Signature,
|
||||
}
|
||||
|
||||
impl Lower for data::ModData {
|
||||
|
@ -390,6 +397,7 @@ fn lower(self, tcx: TyCtxt) -> ModData {
|
|||
items: self.items.into_iter().map(|id| make_def_id(id, &tcx.map)).collect(),
|
||||
visibility: self.visibility,
|
||||
docs: self.docs,
|
||||
sig: self.sig.lower(tcx),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -428,6 +436,7 @@ pub struct StructData {
|
|||
pub fields: Vec<DefId>,
|
||||
pub visibility: Visibility,
|
||||
pub docs: String,
|
||||
pub sig: Signature,
|
||||
}
|
||||
|
||||
impl Lower for data::StructData {
|
||||
|
@ -445,6 +454,7 @@ fn lower(self, tcx: TyCtxt) -> StructData {
|
|||
fields: self.fields.into_iter().map(|id| make_def_id(id, &tcx.map)).collect(),
|
||||
visibility: self.visibility,
|
||||
docs: self.docs,
|
||||
sig: self.sig.lower(tcx),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -460,6 +470,7 @@ pub struct StructVariantData {
|
|||
pub scope: DefId,
|
||||
pub parent: Option<DefId>,
|
||||
pub docs: String,
|
||||
pub sig: Signature,
|
||||
}
|
||||
|
||||
impl Lower for data::StructVariantData {
|
||||
|
@ -476,6 +487,7 @@ fn lower(self, tcx: TyCtxt) -> StructVariantData {
|
|||
scope: make_def_id(self.scope, &tcx.map),
|
||||
parent: self.parent,
|
||||
docs: self.docs,
|
||||
sig: self.sig.lower(tcx),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -491,6 +503,7 @@ pub struct TraitData {
|
|||
pub items: Vec<DefId>,
|
||||
pub visibility: Visibility,
|
||||
pub docs: String,
|
||||
pub sig: Signature,
|
||||
}
|
||||
|
||||
impl Lower for data::TraitData {
|
||||
|
@ -507,6 +520,7 @@ fn lower(self, tcx: TyCtxt) -> TraitData {
|
|||
items: self.items.into_iter().map(|id| make_def_id(id, &tcx.map)).collect(),
|
||||
visibility: self.visibility,
|
||||
docs: self.docs,
|
||||
sig: self.sig.lower(tcx),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -522,6 +536,7 @@ pub struct TupleVariantData {
|
|||
pub scope: DefId,
|
||||
pub parent: Option<DefId>,
|
||||
pub docs: String,
|
||||
pub sig: Signature,
|
||||
}
|
||||
|
||||
impl Lower for data::TupleVariantData {
|
||||
|
@ -538,6 +553,7 @@ fn lower(self, tcx: TyCtxt) -> TupleVariantData {
|
|||
scope: make_def_id(self.scope, &tcx.map),
|
||||
parent: self.parent,
|
||||
docs: self.docs,
|
||||
sig: self.sig.lower(tcx),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -553,6 +569,7 @@ pub struct TypeDefData {
|
|||
pub visibility: Visibility,
|
||||
pub parent: Option<DefId>,
|
||||
pub docs: String,
|
||||
pub sig: Option<Signature>,
|
||||
}
|
||||
|
||||
impl Lower for data::TypeDefData {
|
||||
|
@ -568,6 +585,7 @@ fn lower(self, tcx: TyCtxt) -> TypeDefData {
|
|||
visibility: self.visibility,
|
||||
parent: self.parent,
|
||||
docs: self.docs,
|
||||
sig: self.sig.map(|s| s.lower(tcx)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -656,6 +674,7 @@ pub struct VariableData {
|
|||
pub parent: Option<DefId>,
|
||||
pub visibility: Visibility,
|
||||
pub docs: String,
|
||||
pub sig: Option<Signature>,
|
||||
}
|
||||
|
||||
impl Lower for data::VariableData {
|
||||
|
@ -674,6 +693,7 @@ fn lower(self, tcx: TyCtxt) -> VariableData {
|
|||
parent: self.parent,
|
||||
visibility: self.visibility,
|
||||
docs: self.docs,
|
||||
sig: self.sig.map(|s| s.lower(tcx)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -700,3 +720,30 @@ fn lower(self, tcx: TyCtxt) -> VariableRefData {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, RustcEncodable)]
|
||||
pub struct Signature {
|
||||
pub span: SpanData,
|
||||
pub text: String,
|
||||
// These identify the main identifier for the defintion as byte offsets into
|
||||
// `text`. E.g., of `foo` in `pub fn foo(...)`
|
||||
pub ident_start: usize,
|
||||
pub ident_end: usize,
|
||||
pub defs: Vec<SigElement>,
|
||||
pub refs: Vec<SigElement>,
|
||||
}
|
||||
|
||||
impl Lower for data::Signature {
|
||||
type Target = Signature;
|
||||
|
||||
fn lower(self, tcx: TyCtxt) -> Signature {
|
||||
Signature {
|
||||
span: SpanData::from_span(self.span, tcx.sess.codemap()),
|
||||
text: self.text,
|
||||
ident_start: self.ident_start,
|
||||
ident_end: self.ident_end,
|
||||
defs: self.defs,
|
||||
refs: self.refs,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
use rustc_serialize::json::as_json;
|
||||
|
||||
use external_data::*;
|
||||
use data::{VariableKind, Visibility};
|
||||
use data::{VariableKind, Visibility, SigElement};
|
||||
use dump::Dump;
|
||||
use super::Format;
|
||||
|
||||
|
@ -179,6 +179,7 @@ struct Def {
|
|||
children: Vec<Id>,
|
||||
decl_id: Option<Id>,
|
||||
docs: String,
|
||||
sig: Option<JsonSignature>,
|
||||
}
|
||||
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
|
@ -221,6 +222,7 @@ fn from(data: EnumData) -> Option<Def> {
|
|||
children: data.variants.into_iter().map(|id| From::from(id)).collect(),
|
||||
decl_id: None,
|
||||
docs: data.docs,
|
||||
sig: Some(From::from(data.sig)),
|
||||
}),
|
||||
_ => None,
|
||||
}
|
||||
|
@ -240,6 +242,7 @@ fn from(data: TupleVariantData) -> Option<Def> {
|
|||
children: vec![],
|
||||
decl_id: None,
|
||||
docs: data.docs,
|
||||
sig: Some(From::from(data.sig)),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -256,6 +259,7 @@ fn from(data: StructVariantData) -> Option<Def> {
|
|||
children: vec![],
|
||||
decl_id: None,
|
||||
docs: data.docs,
|
||||
sig: Some(From::from(data.sig)),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -273,6 +277,7 @@ fn from(data: StructData) -> Option<Def> {
|
|||
children: data.fields.into_iter().map(|id| From::from(id)).collect(),
|
||||
decl_id: None,
|
||||
docs: data.docs,
|
||||
sig: Some(From::from(data.sig)),
|
||||
}),
|
||||
_ => None,
|
||||
}
|
||||
|
@ -292,6 +297,7 @@ fn from(data: TraitData) -> Option<Def> {
|
|||
parent: None,
|
||||
decl_id: None,
|
||||
docs: data.docs,
|
||||
sig: Some(From::from(data.sig)),
|
||||
}),
|
||||
_ => None,
|
||||
}
|
||||
|
@ -311,6 +317,7 @@ fn from(data: FunctionData) -> Option<Def> {
|
|||
parent: data.parent.map(|id| From::from(id)),
|
||||
decl_id: None,
|
||||
docs: data.docs,
|
||||
sig: Some(From::from(data.sig)),
|
||||
}),
|
||||
_ => None,
|
||||
}
|
||||
|
@ -330,6 +337,7 @@ fn from(data: MethodData) -> Option<Def> {
|
|||
parent: data.parent.map(|id| From::from(id)),
|
||||
decl_id: data.decl_id.map(|id| From::from(id)),
|
||||
docs: data.docs,
|
||||
sig: Some(From::from(data.sig)),
|
||||
}),
|
||||
_ => None,
|
||||
}
|
||||
|
@ -348,6 +356,7 @@ fn from(data: MacroData) -> Option<Def> {
|
|||
parent: None,
|
||||
decl_id: None,
|
||||
docs: data.docs,
|
||||
sig: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -365,6 +374,7 @@ fn from(data:ModData) -> Option<Def> {
|
|||
parent: None,
|
||||
decl_id: None,
|
||||
docs: data.docs,
|
||||
sig: Some(From::from(data.sig)),
|
||||
}),
|
||||
_ => None,
|
||||
}
|
||||
|
@ -384,11 +394,13 @@ fn from(data: TypeDefData) -> Option<Def> {
|
|||
parent: data.parent.map(|id| From::from(id)),
|
||||
decl_id: None,
|
||||
docs: String::new(),
|
||||
sig: data.sig.map(|s| From::from(s)),
|
||||
}),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<VariableData> for Option<Def> {
|
||||
fn from(data: VariableData) -> Option<Def> {
|
||||
match data.visibility {
|
||||
|
@ -408,8 +420,49 @@ fn from(data: VariableData) -> Option<Def> {
|
|||
parent: data.parent.map(|id| From::from(id)),
|
||||
decl_id: None,
|
||||
docs: data.docs,
|
||||
sig: data.sig.map(|s| From::from(s)),
|
||||
}),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
pub struct JsonSignature {
|
||||
span: SpanData,
|
||||
text: String,
|
||||
ident_start: usize,
|
||||
ident_end: usize,
|
||||
defs: Vec<JsonSigElement>,
|
||||
refs: Vec<JsonSigElement>,
|
||||
}
|
||||
|
||||
impl From<Signature> for JsonSignature {
|
||||
fn from(data: Signature) -> JsonSignature {
|
||||
JsonSignature {
|
||||
span: data.span,
|
||||
text: data.text,
|
||||
ident_start: data.ident_start,
|
||||
ident_end: data.ident_end,
|
||||
defs: data.defs.into_iter().map(|s| From::from(s)).collect(),
|
||||
refs: data.refs.into_iter().map(|s| From::from(s)).collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
pub struct JsonSigElement {
|
||||
id: Id,
|
||||
start: usize,
|
||||
end: usize,
|
||||
}
|
||||
|
||||
impl From<SigElement> for JsonSigElement {
|
||||
fn from(data: SigElement) -> JsonSigElement {
|
||||
JsonSigElement {
|
||||
id: From::from(data.id),
|
||||
start: data.start,
|
||||
end: data.end,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
use rustc_serialize::json::as_json;
|
||||
|
||||
use external_data::*;
|
||||
use data::VariableKind;
|
||||
use data::{VariableKind, SigElement};
|
||||
use dump::Dump;
|
||||
use super::Format;
|
||||
|
||||
|
@ -86,6 +86,7 @@ fn mod_data(&mut self, data: ModData) {
|
|||
children: data.items.into_iter().map(|id| From::from(id)).collect(),
|
||||
decl_id: None,
|
||||
docs: data.docs,
|
||||
sig: Some(From::from(data.sig)),
|
||||
};
|
||||
if def.span.file_name != def.value {
|
||||
// If the module is an out-of-line defintion, then we'll make the
|
||||
|
@ -223,6 +224,7 @@ struct Def {
|
|||
children: Vec<Id>,
|
||||
decl_id: Option<Id>,
|
||||
docs: String,
|
||||
sig: Option<JsonSignature>,
|
||||
}
|
||||
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
|
@ -264,6 +266,7 @@ fn from(data: EnumData) -> Def {
|
|||
children: data.variants.into_iter().map(|id| From::from(id)).collect(),
|
||||
decl_id: None,
|
||||
docs: data.docs,
|
||||
sig: Some(From::from(data.sig)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -280,6 +283,7 @@ fn from(data: TupleVariantData) -> Def {
|
|||
children: vec![],
|
||||
decl_id: None,
|
||||
docs: data.docs,
|
||||
sig: Some(From::from(data.sig)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -295,6 +299,7 @@ fn from(data: StructVariantData) -> Def {
|
|||
children: vec![],
|
||||
decl_id: None,
|
||||
docs: data.docs,
|
||||
sig: Some(From::from(data.sig)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -310,6 +315,7 @@ fn from(data: StructData) -> Def {
|
|||
children: data.fields.into_iter().map(|id| From::from(id)).collect(),
|
||||
decl_id: None,
|
||||
docs: data.docs,
|
||||
sig: Some(From::from(data.sig)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -325,6 +331,7 @@ fn from(data: TraitData) -> Def {
|
|||
children: data.items.into_iter().map(|id| From::from(id)).collect(),
|
||||
decl_id: None,
|
||||
docs: data.docs,
|
||||
sig: Some(From::from(data.sig)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -340,6 +347,7 @@ fn from(data: FunctionData) -> Def {
|
|||
children: vec![],
|
||||
decl_id: None,
|
||||
docs: data.docs,
|
||||
sig: Some(From::from(data.sig)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -355,6 +363,7 @@ fn from(data: MethodData) -> Def {
|
|||
children: vec![],
|
||||
decl_id: data.decl_id.map(|id| From::from(id)),
|
||||
docs: data.docs,
|
||||
sig: Some(From::from(data.sig)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -370,10 +379,10 @@ fn from(data: MacroData) -> Def {
|
|||
children: vec![],
|
||||
decl_id: None,
|
||||
docs: data.docs,
|
||||
sig: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TypeDefData> for Def {
|
||||
fn from(data: TypeDefData) -> Def {
|
||||
Def {
|
||||
|
@ -386,6 +395,7 @@ fn from(data: TypeDefData) -> Def {
|
|||
children: vec![],
|
||||
decl_id: None,
|
||||
docs: String::new(),
|
||||
sig: data.sig.map(|s| From::from(s)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -406,6 +416,7 @@ fn from(data: VariableData) -> Def {
|
|||
children: vec![],
|
||||
decl_id: None,
|
||||
docs: data.docs,
|
||||
sig: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -496,3 +507,43 @@ fn from(data: MacroUseData) -> MacroRef {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
pub struct JsonSignature {
|
||||
span: SpanData,
|
||||
text: String,
|
||||
ident_start: usize,
|
||||
ident_end: usize,
|
||||
defs: Vec<JsonSigElement>,
|
||||
refs: Vec<JsonSigElement>,
|
||||
}
|
||||
|
||||
impl From<Signature> for JsonSignature {
|
||||
fn from(data: Signature) -> JsonSignature {
|
||||
JsonSignature {
|
||||
span: data.span,
|
||||
text: data.text,
|
||||
ident_start: data.ident_start,
|
||||
ident_end: data.ident_end,
|
||||
defs: data.defs.into_iter().map(|s| From::from(s)).collect(),
|
||||
refs: data.refs.into_iter().map(|s| From::from(s)).collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, RustcEncodable)]
|
||||
pub struct JsonSigElement {
|
||||
id: Id,
|
||||
start: usize,
|
||||
end: usize,
|
||||
}
|
||||
|
||||
impl From<SigElement> for JsonSigElement {
|
||||
fn from(data: SigElement) -> JsonSigElement {
|
||||
JsonSigElement {
|
||||
id: From::from(data.id),
|
||||
start: data.start,
|
||||
end: data.end,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -152,6 +152,7 @@ pub fn get_item_data(&self, item: &ast::Item) -> Option<Data> {
|
|||
visibility: From::from(&item.vis),
|
||||
parent: None,
|
||||
docs: docs_for_attrs(&item.attrs),
|
||||
sig: self.sig_base(item),
|
||||
}))
|
||||
}
|
||||
ast::ItemKind::Static(ref typ, mt, ref expr) => {
|
||||
|
@ -179,6 +180,7 @@ pub fn get_item_data(&self, item: &ast::Item) -> Option<Data> {
|
|||
type_value: ty_to_string(&typ),
|
||||
visibility: From::from(&item.vis),
|
||||
docs: docs_for_attrs(&item.attrs),
|
||||
sig: Some(self.sig_base(item)),
|
||||
}))
|
||||
}
|
||||
ast::ItemKind::Const(ref typ, ref expr) => {
|
||||
|
@ -197,6 +199,7 @@ pub fn get_item_data(&self, item: &ast::Item) -> Option<Data> {
|
|||
type_value: ty_to_string(&typ),
|
||||
visibility: From::from(&item.vis),
|
||||
docs: docs_for_attrs(&item.attrs),
|
||||
sig: Some(self.sig_base(item)),
|
||||
}))
|
||||
}
|
||||
ast::ItemKind::Mod(ref m) => {
|
||||
|
@ -207,6 +210,7 @@ pub fn get_item_data(&self, item: &ast::Item) -> Option<Data> {
|
|||
|
||||
let sub_span = self.span_utils.sub_span_after_keyword(item.span, keywords::Mod);
|
||||
filter!(self.span_utils, sub_span, item.span, None);
|
||||
|
||||
Some(Data::ModData(ModData {
|
||||
id: item.id,
|
||||
name: item.ident.to_string(),
|
||||
|
@ -217,6 +221,7 @@ pub fn get_item_data(&self, item: &ast::Item) -> Option<Data> {
|
|||
items: m.items.iter().map(|i| i.id).collect(),
|
||||
visibility: From::from(&item.vis),
|
||||
docs: docs_for_attrs(&item.attrs),
|
||||
sig: self.sig_base(item),
|
||||
}))
|
||||
}
|
||||
ast::ItemKind::Enum(ref def, _) => {
|
||||
|
@ -239,6 +244,7 @@ pub fn get_item_data(&self, item: &ast::Item) -> Option<Data> {
|
|||
variants: def.variants.iter().map(|v| v.node.data.id()).collect(),
|
||||
visibility: From::from(&item.vis),
|
||||
docs: docs_for_attrs(&item.attrs),
|
||||
sig: self.sig_base(item),
|
||||
}))
|
||||
}
|
||||
ast::ItemKind::Impl(.., ref trait_ref, ref typ, _) => {
|
||||
|
@ -287,18 +293,34 @@ pub fn get_item_data(&self, item: &ast::Item) -> Option<Data> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_field_data(&self, field: &ast::StructField,
|
||||
scope: NodeId) -> Option<VariableData> {
|
||||
pub fn get_field_data(&self,
|
||||
field: &ast::StructField,
|
||||
scope: NodeId)
|
||||
-> Option<VariableData> {
|
||||
if let Some(ident) = field.ident {
|
||||
let name = ident.to_string();
|
||||
let qualname = format!("::{}::{}", self.tcx.node_path_str(scope), ident);
|
||||
let def_id = self.tcx.map.local_def_id(field.id);
|
||||
let typ = self.tcx.item_type(def_id).to_string();
|
||||
let sub_span = self.span_utils.sub_span_before_token(field.span, token::Colon);
|
||||
filter!(self.span_utils, sub_span, field.span, None);
|
||||
let def_id = self.tcx.map.local_def_id(field.id);
|
||||
let typ = self.tcx.item_type(def_id).to_string();
|
||||
|
||||
let span = field.span;
|
||||
let text = self.span_utils.snippet(field.span);
|
||||
let ident_start = text.find(&name).unwrap();
|
||||
let ident_end = ident_start + name.len();
|
||||
let sig = Signature {
|
||||
span: span,
|
||||
text: text,
|
||||
ident_start: ident_start,
|
||||
ident_end: ident_end,
|
||||
defs: vec![],
|
||||
refs: vec![],
|
||||
};
|
||||
Some(VariableData {
|
||||
id: field.id,
|
||||
kind: VariableKind::Field,
|
||||
name: ident.to_string(),
|
||||
name: name,
|
||||
qualname: qualname,
|
||||
span: sub_span.unwrap(),
|
||||
scope: scope,
|
||||
|
@ -307,6 +329,7 @@ pub fn get_field_data(&self, field: &ast::StructField,
|
|||
type_value: typ,
|
||||
visibility: From::from(&field.vis),
|
||||
docs: docs_for_attrs(&field.attrs),
|
||||
sig: Some(sig),
|
||||
})
|
||||
} else {
|
||||
None
|
||||
|
@ -388,9 +411,23 @@ pub fn get_method_data(&self, id: ast::NodeId,
|
|||
|
||||
let sub_span = self.span_utils.sub_span_after_keyword(span, keywords::Fn);
|
||||
filter!(self.span_utils, sub_span, span, None);
|
||||
|
||||
let name = name.to_string();
|
||||
let text = self.span_utils.signature_string_for_span(span);
|
||||
let ident_start = text.find(&name).unwrap();
|
||||
let ident_end = ident_start + name.len();
|
||||
let sig = Signature {
|
||||
span: span,
|
||||
text: text,
|
||||
ident_start: ident_start,
|
||||
ident_end: ident_end,
|
||||
defs: vec![],
|
||||
refs: vec![],
|
||||
};
|
||||
|
||||
Some(FunctionData {
|
||||
id: id,
|
||||
name: name.to_string(),
|
||||
name: name,
|
||||
qualname: qualname,
|
||||
declaration: decl_id,
|
||||
span: sub_span.unwrap(),
|
||||
|
@ -400,6 +437,7 @@ pub fn get_method_data(&self, id: ast::NodeId,
|
|||
visibility: vis,
|
||||
parent: parent_scope,
|
||||
docs: docs,
|
||||
sig: sig,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -695,6 +733,21 @@ fn lookup_ref_id(&self, ref_id: NodeId) -> Option<DefId> {
|
|||
}
|
||||
}
|
||||
|
||||
fn sig_base(&self, item: &ast::Item) -> Signature {
|
||||
let text = self.span_utils.signature_string_for_span(item.span);
|
||||
let name = item.ident.to_string();
|
||||
let ident_start = text.find(&name).expect("Name not in signature?");
|
||||
let ident_end = ident_start + name.len();
|
||||
Signature {
|
||||
span: mk_sp(item.span.lo, item.span.lo + BytePos(text.len() as u32)),
|
||||
text: text,
|
||||
ident_start: ident_start,
|
||||
ident_end: ident_end,
|
||||
defs: vec![],
|
||||
refs: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn enclosing_scope(&self, id: NodeId) -> NodeId {
|
||||
self.tcx.map.get_enclosing_scope(id).unwrap_or(CRATE_NODE_ID)
|
||||
|
|
|
@ -19,7 +19,9 @@
|
|||
use syntax::ast;
|
||||
use syntax::parse::lexer::{self, Reader, StringReader};
|
||||
use syntax::parse::token::{self, Token};
|
||||
use syntax::parse::parser::Parser;
|
||||
use syntax::symbol::keywords;
|
||||
use syntax::tokenstream::TokenTree;
|
||||
use syntax_pos::*;
|
||||
|
||||
#[derive(Clone)]
|
||||
|
@ -87,6 +89,12 @@ pub fn retokenise_span(&self, span: Span) -> StringReader<'a> {
|
|||
lexer::StringReader::new(s.diagnostic(), filemap)
|
||||
}
|
||||
|
||||
fn span_to_tts(&self, span: Span) -> Vec<TokenTree> {
|
||||
let srdr = self.retokenise_span(span);
|
||||
let mut p = Parser::new(&self.sess.parse_sess, Box::new(srdr), None, false);
|
||||
p.parse_all_token_trees().expect("Couldn't re-parse span")
|
||||
}
|
||||
|
||||
// Re-parses a path and returns the span for the last identifier in the path
|
||||
pub fn span_for_last_ident(&self, span: Span) -> Option<Span> {
|
||||
let mut result = None;
|
||||
|
@ -308,6 +316,42 @@ pub fn spans_with_brackets(&self, span: Span, nesting: isize, limit: isize) -> V
|
|||
}
|
||||
}
|
||||
|
||||
/// `span` must be the span for an item such as a function or struct. This
|
||||
/// function returns the program text from the start of the span until the
|
||||
/// end of the 'signature' part, that is up to, but not including an opening
|
||||
/// brace or semicolon.
|
||||
pub fn signature_string_for_span(&self, span: Span) -> String {
|
||||
let mut toks = self.span_to_tts(span).into_iter();
|
||||
let mut prev = toks.next().unwrap();
|
||||
let first_span = prev.get_span();
|
||||
let mut angle_count = 0;
|
||||
for tok in toks {
|
||||
if let TokenTree::Token(_, ref tok) = prev {
|
||||
angle_count += match *tok {
|
||||
token::Eof => { break; }
|
||||
token::Lt => 1,
|
||||
token::Gt => -1,
|
||||
token::BinOp(token::Shl) => 2,
|
||||
token::BinOp(token::Shr) => -2,
|
||||
_ => 0,
|
||||
};
|
||||
}
|
||||
if angle_count > 0 {
|
||||
prev = tok;
|
||||
continue;
|
||||
}
|
||||
if let TokenTree::Token(_, token::Semi) = tok {
|
||||
return self.snippet(mk_sp(first_span.lo, prev.get_span().hi));
|
||||
} else if let TokenTree::Delimited(_, ref d) = tok {
|
||||
if d.delim == token::Brace {
|
||||
return self.snippet(mk_sp(first_span.lo, prev.get_span().hi));
|
||||
}
|
||||
}
|
||||
prev = tok;
|
||||
}
|
||||
self.snippet(span)
|
||||
}
|
||||
|
||||
pub fn sub_span_before_token(&self, span: Span, tok: Token) -> Option<Span> {
|
||||
let mut toks = self.retokenise_span(span);
|
||||
let mut prev = toks.real_token();
|
||||
|
|
Loading…
Reference in a new issue