Move the API json dumper to use rls-data too
This commit is contained in:
parent
bf07f1c6bb
commit
979a9881ea
@ -10,15 +10,14 @@
|
|||||||
|
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
|
||||||
use rustc::hir::def_id::DefId;
|
|
||||||
use rustc_serialize::json::as_json;
|
use rustc_serialize::json::as_json;
|
||||||
|
|
||||||
use external_data::*;
|
use external_data::*;
|
||||||
use data::{VariableKind, Visibility, SigElement};
|
use data::{VariableKind, Visibility};
|
||||||
use dump::Dump;
|
use dump::Dump;
|
||||||
use super::Format;
|
use json_dumper::id_from_def_id;
|
||||||
|
|
||||||
use rls_data::{SpanData, CratePreludeData};
|
use rls_data::{Analysis, Import, ImportKind, Def, DefKind, CratePreludeData};
|
||||||
|
|
||||||
|
|
||||||
// A dumper to dump a restricted set of JSON information, designed for use with
|
// A dumper to dump a restricted set of JSON information, designed for use with
|
||||||
@ -26,8 +25,7 @@
|
|||||||
// information here, and (for example) generate Rustdoc URLs, but don't need
|
// information here, and (for example) generate Rustdoc URLs, but don't need
|
||||||
// information for navigating the source of the crate.
|
// information for navigating the source of the crate.
|
||||||
// Relative to the regular JSON save-analysis info, this form is filtered to
|
// 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
|
// remove non-visible items.
|
||||||
// parent field for finding the struct to which a field belongs).
|
|
||||||
pub struct JsonApiDumper<'b, W: Write + 'b> {
|
pub struct JsonApiDumper<'b, W: Write + 'b> {
|
||||||
output: &'b mut W,
|
output: &'b mut W,
|
||||||
result: Analysis,
|
result: Analysis,
|
||||||
@ -50,7 +48,7 @@ fn drop(&mut self) {
|
|||||||
macro_rules! impl_fn {
|
macro_rules! impl_fn {
|
||||||
($fn_name: ident, $data_type: ident, $bucket: ident) => {
|
($fn_name: ident, $data_type: ident, $bucket: ident) => {
|
||||||
fn $fn_name(&mut self, data: $data_type) {
|
fn $fn_name(&mut self, data: $data_type) {
|
||||||
if let Some(datum) = From::from(data) {
|
if let Some(datum) = data.into() {
|
||||||
self.result.$bucket.push(datum);
|
self.result.$bucket.push(datum);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -79,11 +77,11 @@ fn crate_prelude(&mut self, data: CratePreludeData) {
|
|||||||
|
|
||||||
fn impl_data(&mut self, data: ImplData) {
|
fn impl_data(&mut self, data: ImplData) {
|
||||||
if data.self_ref.is_some() {
|
if data.self_ref.is_some() {
|
||||||
self.result.relations.push(From::from(data));
|
self.result.relations.push(data.into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn inheritance(&mut self, data: InheritanceData) {
|
fn inheritance(&mut self, data: InheritanceData) {
|
||||||
self.result.relations.push(From::from(data));
|
self.result.relations.push(data.into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,426 +90,261 @@ fn inheritance(&mut self, data: InheritanceData) {
|
|||||||
// method, but not the supplied method). In both cases, we are currently
|
// method, but not the supplied method). In both cases, we are currently
|
||||||
// ignoring it.
|
// ignoring it.
|
||||||
|
|
||||||
#[derive(Debug, RustcEncodable)]
|
impl Into<Option<Import>> for UseData {
|
||||||
struct Analysis {
|
fn into(self) -> Option<Import> {
|
||||||
kind: Format,
|
match self.visibility {
|
||||||
prelude: Option<CratePreludeData>,
|
|
||||||
imports: Vec<Import>,
|
|
||||||
defs: Vec<Def>,
|
|
||||||
relations: Vec<Relation>,
|
|
||||||
// These two fields are dummies so that clients can parse the two kinds of
|
|
||||||
// JSON data in the same way.
|
|
||||||
refs: Vec<()>,
|
|
||||||
macro_refs: Vec<()>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Analysis {
|
|
||||||
fn new() -> Analysis {
|
|
||||||
Analysis {
|
|
||||||
kind: Format::JsonApi,
|
|
||||||
prelude: None,
|
|
||||||
imports: vec![],
|
|
||||||
defs: vec![],
|
|
||||||
relations: vec![],
|
|
||||||
refs: vec![],
|
|
||||||
macro_refs: vec![],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// DefId::index is a newtype and so the JSON serialisation is ugly. Therefore
|
|
||||||
// we use our own Id which is the same, but without the newtype.
|
|
||||||
#[derive(Debug, RustcEncodable)]
|
|
||||||
struct Id {
|
|
||||||
krate: u32,
|
|
||||||
index: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<DefId> for Id {
|
|
||||||
fn from(id: DefId) -> Id {
|
|
||||||
Id {
|
|
||||||
krate: id.krate.as_u32(),
|
|
||||||
index: id.index.as_u32(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, RustcEncodable)]
|
|
||||||
struct Import {
|
|
||||||
kind: ImportKind,
|
|
||||||
id: Id,
|
|
||||||
span: SpanData,
|
|
||||||
name: String,
|
|
||||||
value: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, RustcEncodable)]
|
|
||||||
enum ImportKind {
|
|
||||||
Use,
|
|
||||||
GlobUse,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<UseData> for Option<Import> {
|
|
||||||
fn from(data: UseData) -> Option<Import> {
|
|
||||||
match data.visibility {
|
|
||||||
Visibility::Public => Some(Import {
|
Visibility::Public => Some(Import {
|
||||||
kind: ImportKind::Use,
|
kind: ImportKind::Use,
|
||||||
id: From::from(data.id),
|
ref_id: self.mod_id.map(|id| id_from_def_id(id)),
|
||||||
span: data.span,
|
span: self.span,
|
||||||
name: data.name,
|
name: self.name,
|
||||||
value: String::new(),
|
value: String::new(),
|
||||||
}),
|
}),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl From<UseGlobData> for Option<Import> {
|
impl Into<Option<Import>> for UseGlobData {
|
||||||
fn from(data: UseGlobData) -> Option<Import> {
|
fn into(self) -> Option<Import> {
|
||||||
match data.visibility {
|
match self.visibility {
|
||||||
Visibility::Public => Some(Import {
|
Visibility::Public => Some(Import {
|
||||||
kind: ImportKind::GlobUse,
|
kind: ImportKind::GlobUse,
|
||||||
id: From::from(data.id),
|
ref_id: None,
|
||||||
span: data.span,
|
span: self.span,
|
||||||
name: "*".to_owned(),
|
name: "*".to_owned(),
|
||||||
value: data.names.join(", "),
|
value: self.names.join(", "),
|
||||||
}),
|
}),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, RustcEncodable)]
|
impl Into<Option<Def>> for EnumData {
|
||||||
struct Def {
|
fn into(self) -> Option<Def> {
|
||||||
kind: DefKind,
|
match self.visibility {
|
||||||
id: Id,
|
|
||||||
span: SpanData,
|
|
||||||
name: String,
|
|
||||||
qualname: String,
|
|
||||||
value: String,
|
|
||||||
parent: Option<Id>,
|
|
||||||
children: Vec<Id>,
|
|
||||||
decl_id: Option<Id>,
|
|
||||||
docs: String,
|
|
||||||
sig: Option<JsonSignature>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, RustcEncodable)]
|
|
||||||
enum DefKind {
|
|
||||||
// value = variant names
|
|
||||||
Enum,
|
|
||||||
// value = enum name + variant name + types
|
|
||||||
Tuple,
|
|
||||||
// value = [enum name +] name + fields
|
|
||||||
Struct,
|
|
||||||
// value = signature
|
|
||||||
Trait,
|
|
||||||
// value = type + generics
|
|
||||||
Function,
|
|
||||||
// value = type + generics
|
|
||||||
Method,
|
|
||||||
// No id, no value.
|
|
||||||
Macro,
|
|
||||||
// value = file_name
|
|
||||||
Mod,
|
|
||||||
// value = aliased type
|
|
||||||
Type,
|
|
||||||
// value = type and init expression (for all variable kinds).
|
|
||||||
Static,
|
|
||||||
Const,
|
|
||||||
Field,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<EnumData> for Option<Def> {
|
|
||||||
fn from(data: EnumData) -> Option<Def> {
|
|
||||||
match data.visibility {
|
|
||||||
Visibility::Public => Some(Def {
|
Visibility::Public => Some(Def {
|
||||||
kind: DefKind::Enum,
|
kind: DefKind::Enum,
|
||||||
id: From::from(data.id),
|
id: id_from_def_id(self.id),
|
||||||
span: data.span,
|
span: self.span,
|
||||||
name: data.name,
|
name: self.name,
|
||||||
qualname: data.qualname,
|
qualname: self.qualname,
|
||||||
value: data.value,
|
value: self.value,
|
||||||
parent: None,
|
parent: None,
|
||||||
children: data.variants.into_iter().map(|id| From::from(id)).collect(),
|
children: self.variants.into_iter().map(|id| id_from_def_id(id)).collect(),
|
||||||
decl_id: None,
|
decl_id: None,
|
||||||
docs: data.docs,
|
docs: self.docs,
|
||||||
sig: Some(From::from(data.sig)),
|
sig: Some(self.sig.into()),
|
||||||
|
attributes: vec![],
|
||||||
}),
|
}),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<TupleVariantData> for Option<Def> {
|
impl Into<Option<Def>> for TupleVariantData {
|
||||||
fn from(data: TupleVariantData) -> Option<Def> {
|
fn into(self) -> Option<Def> {
|
||||||
Some(Def {
|
Some(Def {
|
||||||
kind: DefKind::Tuple,
|
kind: DefKind::Tuple,
|
||||||
id: From::from(data.id),
|
id: id_from_def_id(self.id),
|
||||||
span: data.span,
|
span: self.span,
|
||||||
name: data.name,
|
name: self.name,
|
||||||
qualname: data.qualname,
|
qualname: self.qualname,
|
||||||
value: data.value,
|
value: self.value,
|
||||||
parent: data.parent.map(|id| From::from(id)),
|
parent: self.parent.map(|id| id_from_def_id(id)),
|
||||||
children: vec![],
|
children: vec![],
|
||||||
decl_id: None,
|
decl_id: None,
|
||||||
docs: data.docs,
|
docs: self.docs,
|
||||||
sig: Some(From::from(data.sig)),
|
sig: Some(self.sig.into()),
|
||||||
|
attributes: vec![],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl From<StructVariantData> for Option<Def> {
|
impl Into<Option<Def>> for StructVariantData {
|
||||||
fn from(data: StructVariantData) -> Option<Def> {
|
fn into(self) -> Option<Def> {
|
||||||
Some(Def {
|
Some(Def {
|
||||||
kind: DefKind::Struct,
|
kind: DefKind::Struct,
|
||||||
id: From::from(data.id),
|
id: id_from_def_id(self.id),
|
||||||
span: data.span,
|
span: self.span,
|
||||||
name: data.name,
|
name: self.name,
|
||||||
qualname: data.qualname,
|
qualname: self.qualname,
|
||||||
value: data.value,
|
value: self.value,
|
||||||
parent: data.parent.map(|id| From::from(id)),
|
parent: self.parent.map(|id| id_from_def_id(id)),
|
||||||
children: vec![],
|
children: vec![],
|
||||||
decl_id: None,
|
decl_id: None,
|
||||||
docs: data.docs,
|
docs: self.docs,
|
||||||
sig: Some(From::from(data.sig)),
|
sig: Some(self.sig.into()),
|
||||||
|
attributes: vec![],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl From<StructData> for Option<Def> {
|
impl Into<Option<Def>> for StructData {
|
||||||
fn from(data: StructData) -> Option<Def> {
|
fn into(self) -> Option<Def> {
|
||||||
match data.visibility {
|
match self.visibility {
|
||||||
Visibility::Public => Some(Def {
|
Visibility::Public => Some(Def {
|
||||||
kind: DefKind::Struct,
|
kind: DefKind::Struct,
|
||||||
id: From::from(data.id),
|
id: id_from_def_id(self.id),
|
||||||
span: data.span,
|
span: self.span,
|
||||||
name: data.name,
|
name: self.name,
|
||||||
qualname: data.qualname,
|
qualname: self.qualname,
|
||||||
value: data.value,
|
value: self.value,
|
||||||
parent: None,
|
parent: None,
|
||||||
children: data.fields.into_iter().map(|id| From::from(id)).collect(),
|
children: self.fields.into_iter().map(|id| id_from_def_id(id)).collect(),
|
||||||
decl_id: None,
|
decl_id: None,
|
||||||
docs: data.docs,
|
docs: self.docs,
|
||||||
sig: Some(From::from(data.sig)),
|
sig: Some(self.sig.into()),
|
||||||
|
attributes: vec![],
|
||||||
}),
|
}),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl From<TraitData> for Option<Def> {
|
impl Into<Option<Def>> for TraitData {
|
||||||
fn from(data: TraitData) -> Option<Def> {
|
fn into(self) -> Option<Def> {
|
||||||
match data.visibility {
|
match self.visibility {
|
||||||
Visibility::Public => Some(Def {
|
Visibility::Public => Some(Def {
|
||||||
kind: DefKind::Trait,
|
kind: DefKind::Trait,
|
||||||
id: From::from(data.id),
|
id: id_from_def_id(self.id),
|
||||||
span: data.span,
|
span: self.span,
|
||||||
name: data.name,
|
name: self.name,
|
||||||
qualname: data.qualname,
|
qualname: self.qualname,
|
||||||
value: data.value,
|
value: self.value,
|
||||||
children: data.items.into_iter().map(|id| From::from(id)).collect(),
|
children: self.items.into_iter().map(|id| id_from_def_id(id)).collect(),
|
||||||
parent: None,
|
parent: None,
|
||||||
decl_id: None,
|
decl_id: None,
|
||||||
docs: data.docs,
|
docs: self.docs,
|
||||||
sig: Some(From::from(data.sig)),
|
sig: Some(self.sig.into()),
|
||||||
|
attributes: vec![],
|
||||||
}),
|
}),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl From<FunctionData> for Option<Def> {
|
impl Into<Option<Def>> for FunctionData {
|
||||||
fn from(data: FunctionData) -> Option<Def> {
|
fn into(self) -> Option<Def> {
|
||||||
match data.visibility {
|
match self.visibility {
|
||||||
Visibility::Public => Some(Def {
|
Visibility::Public => Some(Def {
|
||||||
kind: DefKind::Function,
|
kind: DefKind::Function,
|
||||||
id: From::from(data.id),
|
id: id_from_def_id(self.id),
|
||||||
span: data.span,
|
span: self.span,
|
||||||
name: data.name,
|
name: self.name,
|
||||||
qualname: data.qualname,
|
qualname: self.qualname,
|
||||||
value: data.value,
|
value: self.value,
|
||||||
children: vec![],
|
children: vec![],
|
||||||
parent: data.parent.map(|id| From::from(id)),
|
parent: self.parent.map(|id| id_from_def_id(id)),
|
||||||
decl_id: None,
|
decl_id: None,
|
||||||
docs: data.docs,
|
docs: self.docs,
|
||||||
sig: Some(From::from(data.sig)),
|
sig: Some(self.sig.into()),
|
||||||
|
attributes: vec![],
|
||||||
}),
|
}),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl From<MethodData> for Option<Def> {
|
impl Into<Option<Def>> for MethodData {
|
||||||
fn from(data: MethodData) -> Option<Def> {
|
fn into(self) -> Option<Def> {
|
||||||
match data.visibility {
|
match self.visibility {
|
||||||
Visibility::Public => Some(Def {
|
Visibility::Public => Some(Def {
|
||||||
kind: DefKind::Method,
|
kind: DefKind::Method,
|
||||||
id: From::from(data.id),
|
id: id_from_def_id(self.id),
|
||||||
span: data.span,
|
span: self.span,
|
||||||
name: data.name,
|
name: self.name,
|
||||||
qualname: data.qualname,
|
qualname: self.qualname,
|
||||||
value: data.value,
|
value: self.value,
|
||||||
children: vec![],
|
children: vec![],
|
||||||
parent: data.parent.map(|id| From::from(id)),
|
parent: self.parent.map(|id| id_from_def_id(id)),
|
||||||
decl_id: data.decl_id.map(|id| From::from(id)),
|
decl_id: self.decl_id.map(|id| id_from_def_id(id)),
|
||||||
docs: data.docs,
|
docs: self.docs,
|
||||||
sig: Some(From::from(data.sig)),
|
sig: Some(self.sig.into()),
|
||||||
|
attributes: vec![],
|
||||||
}),
|
}),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl From<MacroData> for Option<Def> {
|
impl Into<Option<Def>> for MacroData {
|
||||||
fn from(data: MacroData) -> Option<Def> {
|
fn into(self) -> Option<Def> {
|
||||||
Some(Def {
|
Some(Def {
|
||||||
kind: DefKind::Macro,
|
kind: DefKind::Macro,
|
||||||
id: From::from(null_def_id()),
|
id: id_from_def_id(null_def_id()),
|
||||||
span: data.span,
|
span: self.span,
|
||||||
name: data.name,
|
name: self.name,
|
||||||
qualname: data.qualname,
|
qualname: self.qualname,
|
||||||
value: String::new(),
|
value: String::new(),
|
||||||
children: vec![],
|
children: vec![],
|
||||||
parent: None,
|
parent: None,
|
||||||
decl_id: None,
|
decl_id: None,
|
||||||
docs: data.docs,
|
docs: self.docs,
|
||||||
sig: None,
|
sig: None,
|
||||||
|
attributes: vec![],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl From<ModData> for Option<Def> {
|
impl Into<Option<Def>> for ModData {
|
||||||
fn from(data:ModData) -> Option<Def> {
|
fn into(self) -> Option<Def> {
|
||||||
match data.visibility {
|
match self.visibility {
|
||||||
Visibility::Public => Some(Def {
|
Visibility::Public => Some(Def {
|
||||||
kind: DefKind::Mod,
|
kind: DefKind::Mod,
|
||||||
id: From::from(data.id),
|
id: id_from_def_id(self.id),
|
||||||
span: data.span,
|
span: self.span,
|
||||||
name: data.name,
|
name: self.name,
|
||||||
qualname: data.qualname,
|
qualname: self.qualname,
|
||||||
value: data.filename,
|
value: self.filename,
|
||||||
children: data.items.into_iter().map(|id| From::from(id)).collect(),
|
children: self.items.into_iter().map(|id| id_from_def_id(id)).collect(),
|
||||||
parent: None,
|
parent: None,
|
||||||
decl_id: None,
|
decl_id: None,
|
||||||
docs: data.docs,
|
docs: self.docs,
|
||||||
sig: Some(From::from(data.sig)),
|
sig: Some(self.sig.into()),
|
||||||
|
attributes: vec![],
|
||||||
}),
|
}),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl From<TypeDefData> for Option<Def> {
|
impl Into<Option<Def>> for TypeDefData {
|
||||||
fn from(data: TypeDefData) -> Option<Def> {
|
fn into(self) -> Option<Def> {
|
||||||
match data.visibility {
|
match self.visibility {
|
||||||
Visibility::Public => Some(Def {
|
Visibility::Public => Some(Def {
|
||||||
kind: DefKind::Type,
|
kind: DefKind::Type,
|
||||||
id: From::from(data.id),
|
id: id_from_def_id(self.id),
|
||||||
span: data.span,
|
span: self.span,
|
||||||
name: data.name,
|
name: self.name,
|
||||||
qualname: data.qualname,
|
qualname: self.qualname,
|
||||||
value: data.value,
|
value: self.value,
|
||||||
children: vec![],
|
children: vec![],
|
||||||
parent: data.parent.map(|id| From::from(id)),
|
parent: self.parent.map(|id| id_from_def_id(id)),
|
||||||
decl_id: None,
|
decl_id: None,
|
||||||
docs: String::new(),
|
docs: String::new(),
|
||||||
sig: data.sig.map(|s| From::from(s)),
|
sig: self.sig.map(|s| s.into()),
|
||||||
|
attributes: vec![],
|
||||||
}),
|
}),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<VariableData> for Option<Def> {
|
impl Into<Option<Def>> for VariableData {
|
||||||
fn from(data: VariableData) -> Option<Def> {
|
fn into(self) -> Option<Def> {
|
||||||
match data.visibility {
|
match self.visibility {
|
||||||
Visibility::Public => Some(Def {
|
Visibility::Public => Some(Def {
|
||||||
kind: match data.kind {
|
kind: match self.kind {
|
||||||
VariableKind::Static => DefKind::Static,
|
VariableKind::Static => DefKind::Static,
|
||||||
VariableKind::Const => DefKind::Const,
|
VariableKind::Const => DefKind::Const,
|
||||||
VariableKind::Local => { return None }
|
VariableKind::Local => { return None }
|
||||||
VariableKind::Field => DefKind::Field,
|
VariableKind::Field => DefKind::Field,
|
||||||
},
|
},
|
||||||
id: From::from(data.id),
|
id: id_from_def_id(self.id),
|
||||||
span: data.span,
|
span: self.span,
|
||||||
name: data.name,
|
name: self.name,
|
||||||
qualname: data.qualname,
|
qualname: self.qualname,
|
||||||
value: data.value,
|
value: self.value,
|
||||||
children: vec![],
|
children: vec![],
|
||||||
parent: data.parent.map(|id| From::from(id)),
|
parent: self.parent.map(|id| id_from_def_id(id)),
|
||||||
decl_id: None,
|
decl_id: None,
|
||||||
docs: data.docs,
|
docs: self.docs,
|
||||||
sig: data.sig.map(|s| From::from(s)),
|
sig: self.sig.map(|s| s.into()),
|
||||||
|
attributes: vec![],
|
||||||
}),
|
}),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, RustcEncodable)]
|
|
||||||
struct Relation {
|
|
||||||
span: SpanData,
|
|
||||||
kind: RelationKind,
|
|
||||||
from: Id,
|
|
||||||
to: Id,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, RustcEncodable)]
|
|
||||||
enum RelationKind {
|
|
||||||
Impl,
|
|
||||||
SuperTrait,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<ImplData> for Relation {
|
|
||||||
fn from(data: ImplData) -> Relation {
|
|
||||||
Relation {
|
|
||||||
span: data.span,
|
|
||||||
kind: RelationKind::Impl,
|
|
||||||
from: From::from(data.self_ref.unwrap_or(null_def_id())),
|
|
||||||
to: From::from(data.trait_ref.unwrap_or(null_def_id())),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<InheritanceData> for Relation {
|
|
||||||
fn from(data: InheritanceData) -> Relation {
|
|
||||||
Relation {
|
|
||||||
span: data.span,
|
|
||||||
kind: RelationKind::SuperTrait,
|
|
||||||
from: From::from(data.base_id),
|
|
||||||
to: From::from(data.deriv_id),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[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,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -136,7 +136,7 @@ fn inheritance(&mut self, data: InheritanceData) {
|
|||||||
|
|
||||||
// DefId::index is a newtype and so the JSON serialisation is ugly. Therefore
|
// DefId::index is a newtype and so the JSON serialisation is ugly. Therefore
|
||||||
// we use our own Id which is the same, but without the newtype.
|
// we use our own Id which is the same, but without the newtype.
|
||||||
fn id_from_def_id(id: DefId) -> Id {
|
pub fn id_from_def_id(id: DefId) -> Id {
|
||||||
Id {
|
Id {
|
||||||
krate: id.krate.as_u32(),
|
krate: id.krate.as_u32(),
|
||||||
index: id.index.as_u32(),
|
index: id.index.as_u32(),
|
||||||
|
Loading…
Reference in New Issue
Block a user