Change json dumper (and a few other bits and pieces) to use rls-data rather than its own data structures

This commit is contained in:
Nick Cameron 2017-03-14 17:08:47 +13:00
parent fee1f64434
commit a77e52875b
7 changed files with 260 additions and 397 deletions

View File

@ -13,6 +13,8 @@ use std::io::Write;
use super::external_data::*; use super::external_data::*;
use super::dump::Dump; use super::dump::Dump;
use rls_data::{SpanData, CratePreludeData};
pub struct CsvDumper<'b, W: 'b> { pub struct CsvDumper<'b, W: 'b> {
output: &'b mut W output: &'b mut W
} }
@ -429,6 +431,6 @@ fn make_values_str(pairs: &[(&'static str, &str)]) -> String {
fn span_extent_str(span: SpanData) -> String { fn span_extent_str(span: SpanData) -> String {
format!("file_name,\"{}\",file_line,{},file_col,{},byte_start,{},\ format!("file_name,\"{}\",file_line,{},file_col,{},byte_start,{},\
file_line_end,{},file_col_end,{},byte_end,{}", file_line_end,{},file_col_end,{},byte_end,{}",
span.file_name, span.line_start, span.column_start, span.byte_start, span.file_name.to_str().unwrap(), span.line_start.0, span.column_start.0,
span.line_end, span.column_end, span.byte_end) span.byte_start, span.line_end.0, span.column_end.0, span.byte_end)
} }

View File

@ -18,6 +18,8 @@ use rustc::hir::def_id::{CrateNum, DefId};
use syntax::ast::{self, Attribute, NodeId}; use syntax::ast::{self, Attribute, NodeId};
use syntax_pos::Span; use syntax_pos::Span;
use rls_data::ExternalCrateData;
pub struct CrateData { pub struct CrateData {
pub name: String, pub name: String,
pub number: u32, pub number: u32,
@ -115,14 +117,6 @@ pub struct CratePreludeData {
pub span: Span, pub span: Span,
} }
/// Data for external crates in the prelude of a crate.
#[derive(Debug, RustcEncodable)]
pub struct ExternalCrateData {
pub name: String,
pub num: CrateNum,
pub file_name: String,
}
/// Data for enum declarations. /// Data for enum declarations.
#[derive(Clone, Debug, RustcEncodable)] #[derive(Clone, Debug, RustcEncodable)]
pub struct EnumData { pub struct EnumData {

View File

@ -10,6 +10,8 @@
use super::external_data::*; use super::external_data::*;
use rls_data::CratePreludeData;
pub trait Dump { pub trait Dump {
fn crate_prelude(&mut self, CratePreludeData) {} fn crate_prelude(&mut self, CratePreludeData) {}
fn enum_data(&mut self, EnumData) {} fn enum_data(&mut self, EnumData) {}

View File

@ -54,6 +54,8 @@ use super::external_data::{Lower, make_def_id};
use super::span_utils::SpanUtils; use super::span_utils::SpanUtils;
use super::recorder; use super::recorder;
use rls_data::ExternalCrateData;
macro_rules! down_cast_data { macro_rules! down_cast_data {
($id:ident, $kind:ident, $sp:expr) => { ($id:ident, $kind:ident, $sp:expr) => {
let $id = if let super::Data::$kind(data) = $id { let $id = if let super::Data::$kind(data) = $id {

View File

@ -17,8 +17,12 @@ use syntax::print::pprust;
use syntax::symbol::Symbol; use syntax::symbol::Symbol;
use syntax_pos::Span; use syntax_pos::Span;
use std::path::PathBuf;
use data::{self, Visibility, SigElement}; use data::{self, Visibility, SigElement};
use rls_data::{SpanData, CratePreludeData};
// FIXME: this should be pub(crate), but the current snapshot doesn't allow it yet // FIXME: this should be pub(crate), but the current snapshot doesn't allow it yet
pub trait Lower { pub trait Lower {
type Target; type Target;
@ -36,41 +40,26 @@ pub fn null_def_id() -> DefId {
} }
} }
#[derive(Clone, Debug, RustcEncodable)] pub fn span_from_span(span: Span, cm: &CodeMap) -> SpanData {
pub struct SpanData { let start = cm.lookup_char_pos(span.lo);
pub file_name: String, let end = cm.lookup_char_pos(span.hi);
pub byte_start: u32,
pub byte_end: u32,
/// 1-based.
pub line_start: usize,
pub line_end: usize,
/// 1-based, character offset.
pub column_start: usize,
pub column_end: usize,
}
impl SpanData { SpanData {
pub fn from_span(span: Span, cm: &CodeMap) -> SpanData { file_name: start.file.name.clone().into(),
let start = cm.lookup_char_pos(span.lo); byte_start: span.lo.0,
let end = cm.lookup_char_pos(span.hi); byte_end: span.hi.0,
line_start: start.line,
SpanData { line_end: end.line,
file_name: start.file.name.clone(), column_start: start.col.0 + 1,
byte_start: span.lo.0, column_end: end.col.0 + 1,
byte_end: span.hi.0,
line_start: start.line,
line_end: end.line,
column_start: start.col.0 + 1,
column_end: end.col.0 + 1,
}
} }
} }
/// Represent an arbitrary attribute on a code element /// Represent an arbitrary attribute on a code element
#[derive(Clone, Debug, RustcEncodable)] #[derive(Clone, Debug, RustcEncodable)]
pub struct Attribute { pub struct Attribute {
value: String, pub value: String,
span: SpanData, pub span: SpanData,
} }
impl Lower for Vec<ast::Attribute> { impl Lower for Vec<ast::Attribute> {
@ -93,20 +82,12 @@ impl Lower for Vec<ast::Attribute> {
Attribute { Attribute {
value: value, value: value,
span: SpanData::from_span(attr.span, tcx.sess.codemap()), span: span_from_span(attr.span, tcx.sess.codemap()),
} }
}).collect() }).collect()
} }
} }
#[derive(Debug, RustcEncodable)]
pub struct CratePreludeData {
pub crate_name: String,
pub crate_root: String,
pub external_crates: Vec<data::ExternalCrateData>,
pub span: SpanData,
}
impl Lower for data::CratePreludeData { impl Lower for data::CratePreludeData {
type Target = CratePreludeData; type Target = CratePreludeData;
@ -115,7 +96,7 @@ impl Lower for data::CratePreludeData {
crate_name: self.crate_name, crate_name: self.crate_name,
crate_root: self.crate_root, crate_root: self.crate_root,
external_crates: self.external_crates, external_crates: self.external_crates,
span: SpanData::from_span(self.span, tcx.sess.codemap()), span: span_from_span(self.span, tcx.sess.codemap()),
} }
} }
} }
@ -145,7 +126,7 @@ impl Lower for data::EnumData {
name: self.name, name: self.name,
value: self.value, value: self.value,
qualname: self.qualname, qualname: self.qualname,
span: SpanData::from_span(self.span, tcx.sess.codemap()), span: span_from_span(self.span, tcx.sess.codemap()),
scope: make_def_id(self.scope, &tcx.hir), scope: make_def_id(self.scope, &tcx.hir),
variants: self.variants.into_iter().map(|id| make_def_id(id, &tcx.hir)).collect(), variants: self.variants.into_iter().map(|id| make_def_id(id, &tcx.hir)).collect(),
visibility: self.visibility, visibility: self.visibility,
@ -176,7 +157,7 @@ impl Lower for data::ExternCrateData {
name: self.name, name: self.name,
crate_num: self.crate_num, crate_num: self.crate_num,
location: self.location, location: self.location,
span: SpanData::from_span(self.span, tcx.sess.codemap()), span: span_from_span(self.span, tcx.sess.codemap()),
scope: make_def_id(self.scope, &tcx.hir), scope: make_def_id(self.scope, &tcx.hir),
} }
} }
@ -195,7 +176,7 @@ impl Lower for data::FunctionCallData {
fn lower(self, tcx: TyCtxt) -> FunctionCallData { fn lower(self, tcx: TyCtxt) -> FunctionCallData {
FunctionCallData { FunctionCallData {
span: SpanData::from_span(self.span, tcx.sess.codemap()), span: span_from_span(self.span, tcx.sess.codemap()),
scope: make_def_id(self.scope, &tcx.hir), scope: make_def_id(self.scope, &tcx.hir),
ref_id: self.ref_id, ref_id: self.ref_id,
} }
@ -228,7 +209,7 @@ impl Lower for data::FunctionData {
name: self.name, name: self.name,
qualname: self.qualname, qualname: self.qualname,
declaration: self.declaration, declaration: self.declaration,
span: SpanData::from_span(self.span, tcx.sess.codemap()), span: span_from_span(self.span, tcx.sess.codemap()),
scope: make_def_id(self.scope, &tcx.hir), scope: make_def_id(self.scope, &tcx.hir),
value: self.value, value: self.value,
visibility: self.visibility, visibility: self.visibility,
@ -253,7 +234,7 @@ impl Lower for data::FunctionRefData {
fn lower(self, tcx: TyCtxt) -> FunctionRefData { fn lower(self, tcx: TyCtxt) -> FunctionRefData {
FunctionRefData { FunctionRefData {
span: SpanData::from_span(self.span, tcx.sess.codemap()), span: span_from_span(self.span, tcx.sess.codemap()),
scope: make_def_id(self.scope, &tcx.hir), scope: make_def_id(self.scope, &tcx.hir),
ref_id: self.ref_id, ref_id: self.ref_id,
} }
@ -274,7 +255,7 @@ impl Lower for data::ImplData {
fn lower(self, tcx: TyCtxt) -> ImplData { fn lower(self, tcx: TyCtxt) -> ImplData {
ImplData { ImplData {
id: make_def_id(self.id, &tcx.hir), id: make_def_id(self.id, &tcx.hir),
span: SpanData::from_span(self.span, tcx.sess.codemap()), span: span_from_span(self.span, tcx.sess.codemap()),
scope: make_def_id(self.scope, &tcx.hir), scope: make_def_id(self.scope, &tcx.hir),
trait_ref: self.trait_ref, trait_ref: self.trait_ref,
self_ref: self.self_ref, self_ref: self.self_ref,
@ -294,7 +275,7 @@ impl Lower for data::InheritanceData {
fn lower(self, tcx: TyCtxt) -> InheritanceData { fn lower(self, tcx: TyCtxt) -> InheritanceData {
InheritanceData { InheritanceData {
span: SpanData::from_span(self.span, tcx.sess.codemap()), span: span_from_span(self.span, tcx.sess.codemap()),
base_id: self.base_id, base_id: self.base_id,
deriv_id: make_def_id(self.deriv_id, &tcx.hir) deriv_id: make_def_id(self.deriv_id, &tcx.hir)
} }
@ -315,7 +296,7 @@ impl Lower for data::MacroData {
fn lower(self, tcx: TyCtxt) -> MacroData { fn lower(self, tcx: TyCtxt) -> MacroData {
MacroData { MacroData {
span: SpanData::from_span(self.span, tcx.sess.codemap()), span: span_from_span(self.span, tcx.sess.codemap()),
name: self.name, name: self.name,
qualname: self.qualname, qualname: self.qualname,
docs: self.docs, docs: self.docs,
@ -340,10 +321,10 @@ impl Lower for data::MacroUseData {
fn lower(self, tcx: TyCtxt) -> MacroUseData { fn lower(self, tcx: TyCtxt) -> MacroUseData {
MacroUseData { MacroUseData {
span: SpanData::from_span(self.span, tcx.sess.codemap()), span: span_from_span(self.span, tcx.sess.codemap()),
name: self.name, name: self.name,
qualname: self.qualname, qualname: self.qualname,
callee_span: SpanData::from_span(self.callee_span, tcx.sess.codemap()), callee_span: span_from_span(self.callee_span, tcx.sess.codemap()),
scope: make_def_id(self.scope, &tcx.hir), scope: make_def_id(self.scope, &tcx.hir),
} }
} }
@ -363,7 +344,7 @@ impl Lower for data::MethodCallData {
fn lower(self, tcx: TyCtxt) -> MethodCallData { fn lower(self, tcx: TyCtxt) -> MethodCallData {
MethodCallData { MethodCallData {
span: SpanData::from_span(self.span, tcx.sess.codemap()), span: span_from_span(self.span, tcx.sess.codemap()),
scope: make_def_id(self.scope, &tcx.hir), scope: make_def_id(self.scope, &tcx.hir),
ref_id: self.ref_id, ref_id: self.ref_id,
decl_id: self.decl_id, decl_id: self.decl_id,
@ -393,7 +374,7 @@ impl Lower for data::MethodData {
fn lower(self, tcx: TyCtxt) -> MethodData { fn lower(self, tcx: TyCtxt) -> MethodData {
MethodData { MethodData {
span: SpanData::from_span(self.span, tcx.sess.codemap()), span: span_from_span(self.span, tcx.sess.codemap()),
name: self.name, name: self.name,
scope: make_def_id(self.scope, &tcx.hir), scope: make_def_id(self.scope, &tcx.hir),
id: make_def_id(self.id, &tcx.hir), id: make_def_id(self.id, &tcx.hir),
@ -433,7 +414,7 @@ impl Lower for data::ModData {
id: make_def_id(self.id, &tcx.hir), id: make_def_id(self.id, &tcx.hir),
name: self.name, name: self.name,
qualname: self.qualname, qualname: self.qualname,
span: SpanData::from_span(self.span, tcx.sess.codemap()), span: span_from_span(self.span, tcx.sess.codemap()),
scope: make_def_id(self.scope, &tcx.hir), scope: make_def_id(self.scope, &tcx.hir),
filename: self.filename, filename: self.filename,
items: self.items.into_iter().map(|id| make_def_id(id, &tcx.hir)).collect(), items: self.items.into_iter().map(|id| make_def_id(id, &tcx.hir)).collect(),
@ -459,7 +440,7 @@ impl Lower for data::ModRefData {
fn lower(self, tcx: TyCtxt) -> ModRefData { fn lower(self, tcx: TyCtxt) -> ModRefData {
ModRefData { ModRefData {
span: SpanData::from_span(self.span, tcx.sess.codemap()), span: span_from_span(self.span, tcx.sess.codemap()),
scope: make_def_id(self.scope, &tcx.hir), scope: make_def_id(self.scope, &tcx.hir),
ref_id: self.ref_id, ref_id: self.ref_id,
qualname: self.qualname, qualname: self.qualname,
@ -488,7 +469,7 @@ impl Lower for data::StructData {
fn lower(self, tcx: TyCtxt) -> StructData { fn lower(self, tcx: TyCtxt) -> StructData {
StructData { StructData {
span: SpanData::from_span(self.span, tcx.sess.codemap()), span: span_from_span(self.span, tcx.sess.codemap()),
name: self.name, name: self.name,
id: make_def_id(self.id, &tcx.hir), id: make_def_id(self.id, &tcx.hir),
ctor_id: make_def_id(self.ctor_id, &tcx.hir), ctor_id: make_def_id(self.ctor_id, &tcx.hir),
@ -524,7 +505,7 @@ impl Lower for data::StructVariantData {
fn lower(self, tcx: TyCtxt) -> StructVariantData { fn lower(self, tcx: TyCtxt) -> StructVariantData {
StructVariantData { StructVariantData {
span: SpanData::from_span(self.span, tcx.sess.codemap()), span: span_from_span(self.span, tcx.sess.codemap()),
name: self.name, name: self.name,
id: make_def_id(self.id, &tcx.hir), id: make_def_id(self.id, &tcx.hir),
qualname: self.qualname, qualname: self.qualname,
@ -559,7 +540,7 @@ impl Lower for data::TraitData {
fn lower(self, tcx: TyCtxt) -> TraitData { fn lower(self, tcx: TyCtxt) -> TraitData {
TraitData { TraitData {
span: SpanData::from_span(self.span, tcx.sess.codemap()), span: span_from_span(self.span, tcx.sess.codemap()),
name: self.name, name: self.name,
id: make_def_id(self.id, &tcx.hir), id: make_def_id(self.id, &tcx.hir),
qualname: self.qualname, qualname: self.qualname,
@ -594,7 +575,7 @@ impl Lower for data::TupleVariantData {
fn lower(self, tcx: TyCtxt) -> TupleVariantData { fn lower(self, tcx: TyCtxt) -> TupleVariantData {
TupleVariantData { TupleVariantData {
span: SpanData::from_span(self.span, tcx.sess.codemap()), span: span_from_span(self.span, tcx.sess.codemap()),
id: make_def_id(self.id, &tcx.hir), id: make_def_id(self.id, &tcx.hir),
name: self.name, name: self.name,
qualname: self.qualname, qualname: self.qualname,
@ -631,7 +612,7 @@ impl Lower for data::TypeDefData {
TypeDefData { TypeDefData {
id: make_def_id(self.id, &tcx.hir), id: make_def_id(self.id, &tcx.hir),
name: self.name, name: self.name,
span: SpanData::from_span(self.span, tcx.sess.codemap()), span: span_from_span(self.span, tcx.sess.codemap()),
qualname: self.qualname, qualname: self.qualname,
value: self.value, value: self.value,
visibility: self.visibility, visibility: self.visibility,
@ -657,7 +638,7 @@ impl Lower for data::TypeRefData {
fn lower(self, tcx: TyCtxt) -> TypeRefData { fn lower(self, tcx: TyCtxt) -> TypeRefData {
TypeRefData { TypeRefData {
span: SpanData::from_span(self.span, tcx.sess.codemap()), span: span_from_span(self.span, tcx.sess.codemap()),
scope: make_def_id(self.scope, &tcx.hir), scope: make_def_id(self.scope, &tcx.hir),
ref_id: self.ref_id, ref_id: self.ref_id,
qualname: self.qualname, qualname: self.qualname,
@ -681,7 +662,7 @@ impl Lower for data::UseData {
fn lower(self, tcx: TyCtxt) -> UseData { fn lower(self, tcx: TyCtxt) -> UseData {
UseData { UseData {
id: make_def_id(self.id, &tcx.hir), id: make_def_id(self.id, &tcx.hir),
span: SpanData::from_span(self.span, tcx.sess.codemap()), span: span_from_span(self.span, tcx.sess.codemap()),
name: self.name, name: self.name,
mod_id: self.mod_id, mod_id: self.mod_id,
scope: make_def_id(self.scope, &tcx.hir), scope: make_def_id(self.scope, &tcx.hir),
@ -705,7 +686,7 @@ impl Lower for data::UseGlobData {
fn lower(self, tcx: TyCtxt) -> UseGlobData { fn lower(self, tcx: TyCtxt) -> UseGlobData {
UseGlobData { UseGlobData {
id: make_def_id(self.id, &tcx.hir), id: make_def_id(self.id, &tcx.hir),
span: SpanData::from_span(self.span, tcx.sess.codemap()), span: span_from_span(self.span, tcx.sess.codemap()),
names: self.names, names: self.names,
scope: make_def_id(self.scope, &tcx.hir), scope: make_def_id(self.scope, &tcx.hir),
visibility: self.visibility, visibility: self.visibility,
@ -740,7 +721,7 @@ impl Lower for data::VariableData {
kind: self.kind, kind: self.kind,
name: self.name, name: self.name,
qualname: self.qualname, qualname: self.qualname,
span: SpanData::from_span(self.span, tcx.sess.codemap()), span: span_from_span(self.span, tcx.sess.codemap()),
scope: make_def_id(self.scope, &tcx.hir), scope: make_def_id(self.scope, &tcx.hir),
value: self.value, value: self.value,
type_value: self.type_value, type_value: self.type_value,
@ -769,7 +750,7 @@ impl Lower for data::VariableRefData {
fn lower(self, tcx: TyCtxt) -> VariableRefData { fn lower(self, tcx: TyCtxt) -> VariableRefData {
VariableRefData { VariableRefData {
name: self.name, name: self.name,
span: SpanData::from_span(self.span, tcx.sess.codemap()), span: span_from_span(self.span, tcx.sess.codemap()),
scope: make_def_id(self.scope, &tcx.hir), scope: make_def_id(self.scope, &tcx.hir),
ref_id: self.ref_id, ref_id: self.ref_id,
} }
@ -793,7 +774,7 @@ impl Lower for data::Signature {
fn lower(self, tcx: TyCtxt) -> Signature { fn lower(self, tcx: TyCtxt) -> Signature {
Signature { Signature {
span: SpanData::from_span(self.span, tcx.sess.codemap()), span: span_from_span(self.span, tcx.sess.codemap()),
text: self.text, text: self.text,
ident_start: self.ident_start, ident_start: self.ident_start,
ident_end: self.ident_end, ident_end: self.ident_end,

View File

@ -18,6 +18,8 @@ use data::{VariableKind, Visibility, SigElement};
use dump::Dump; use dump::Dump;
use super::Format; use super::Format;
use rls_data::{SpanData, 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
// libraries distributed without their source. Clients are likely to use type // libraries distributed without their source. Clients are likely to use type

View File

@ -13,8 +13,12 @@ use std::io::Write;
use rustc::hir::def_id::DefId; use rustc::hir::def_id::DefId;
use rustc_serialize::json::as_json; use rustc_serialize::json::as_json;
use rls_data::{self, Id, Analysis, Import, ImportKind, Def, DefKind, Ref, RefKind, MacroRef,
Relation, RelationKind, Signature, SigElement, CratePreludeData};
use external_data;
use external_data::*; use external_data::*;
use data::{VariableKind, SigElement}; use data::{self, VariableKind};
use dump::Dump; use dump::Dump;
use super::Format; use super::Format;
@ -40,7 +44,7 @@ impl<'b, W: Write> Drop for JsonDumper<'b, W> {
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) {
self.result.$bucket.push(From::from(data)); self.result.$bucket.push(data.into());
} }
} }
} }
@ -75,21 +79,22 @@ impl<'b, W: Write + 'b> Dump for JsonDumper<'b, W> {
impl_fn!(macro_use, MacroUseData, macro_refs); impl_fn!(macro_use, MacroUseData, macro_refs);
fn mod_data(&mut self, data: ModData) { fn mod_data(&mut self, data: ModData) {
let id: Id = From::from(data.id); let id: Id = id_from_def_id(data.id);
let mut def = Def { let mut def = Def {
kind: DefKind::Mod, kind: DefKind::Mod,
id: id, id: id,
span: data.span, span: data.span.into(),
name: data.name, name: data.name,
qualname: data.qualname, qualname: data.qualname,
value: data.filename, value: data.filename,
children: data.items.into_iter().map(|id| From::from(id)).collect(), parent: None,
children: data.items.into_iter().map(|id| id_from_def_id(id)).collect(),
decl_id: None, decl_id: None,
docs: data.docs, docs: data.docs,
sig: Some(From::from(data.sig)), sig: Some(data.sig.into()),
attributes: data.attributes, attributes: data.attributes.into_iter().map(|a| a.into()).collect(),
}; };
if def.span.file_name != def.value { if data.span.file_name.to_str().unwrap() != def.value {
// If the module is an out-of-line defintion, then we'll make the // If the module is an out-of-line defintion, then we'll make the
// defintion the first character in the module's file and turn the // defintion the first character in the module's file and turn the
// the declaration into a reference to it. // the declaration into a reference to it.
@ -99,8 +104,8 @@ impl<'b, W: Write + 'b> Dump for JsonDumper<'b, W> {
ref_id: id, ref_id: id,
}; };
self.result.refs.push(rf); self.result.refs.push(rf);
def.span = SpanData { def.span = rls_data::SpanData {
file_name: def.value.clone(), file_name: def.value.clone().into(),
byte_start: 0, byte_start: 0,
byte_end: 0, byte_end: 0,
line_start: 1, line_start: 1,
@ -115,11 +120,11 @@ impl<'b, W: Write + 'b> Dump for JsonDumper<'b, W> {
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());
} }
} }
@ -129,476 +134,351 @@ impl<'b, W: Write + 'b> Dump for JsonDumper<'b, W> {
// 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)]
struct Analysis {
kind: Format,
prelude: Option<CratePreludeData>,
imports: Vec<Import>,
defs: Vec<Def>,
refs: Vec<Ref>,
macro_refs: Vec<MacroRef>,
relations: Vec<Relation>,
}
impl Analysis {
fn new() -> Analysis {
Analysis {
kind: Format::Json,
prelude: None,
imports: vec![],
defs: vec![],
refs: vec![],
macro_refs: vec![],
relations: vec![],
}
}
}
// 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.
#[derive(Clone, Copy, Debug, RustcEncodable)] fn id_from_def_id(id: DefId) -> Id {
struct Id { Id {
krate: u32, krate: id.krate.as_u32(),
index: u32, index: id.index.as_u32(),
}
} }
impl From<DefId> for Id { impl Into<rls_data::Attribute> for Attribute {
fn from(id: DefId) -> Id { fn into(self) -> rls_data::Attribute {
Id { rls_data::Attribute {
krate: id.krate.as_u32(), value: self.value,
index: id.index.as_u32(), span: self.span,
} }
} }
} }
#[derive(Debug, RustcEncodable)] impl Into<Import> for ExternCrateData {
struct Import { fn into(self) -> Import {
kind: ImportKind,
ref_id: Option<Id>,
span: SpanData,
name: String,
value: String,
}
#[derive(Debug, RustcEncodable)]
enum ImportKind {
ExternCrate,
Use,
GlobUse,
}
impl From<ExternCrateData> for Import {
fn from(data: ExternCrateData) -> Import {
Import { Import {
kind: ImportKind::ExternCrate, kind: ImportKind::ExternCrate,
ref_id: None, ref_id: None,
span: data.span, span: self.span,
name: data.name, name: self.name,
value: String::new(), value: String::new(),
} }
} }
} }
impl From<UseData> for Import { impl Into<Import> for UseData {
fn from(data: UseData) -> Import { fn into(self) -> Import {
Import { Import {
kind: ImportKind::Use, kind: ImportKind::Use,
ref_id: data.mod_id.map(|id| From::from(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(),
} }
} }
} }
impl From<UseGlobData> for Import { impl Into<Import> for UseGlobData {
fn from(data: UseGlobData) -> Import { fn into(self) -> Import {
Import { Import {
kind: ImportKind::GlobUse, kind: ImportKind::GlobUse,
ref_id: None, ref_id: None,
span: data.span, span: self.span,
name: "*".to_owned(), name: "*".to_owned(),
value: data.names.join(", "), value: self.names.join(", "),
} }
} }
} }
#[derive(Debug, RustcEncodable)] impl Into<Def> for EnumData {
struct Def { fn into(self) -> Def {
kind: DefKind,
id: Id,
span: SpanData,
name: String,
qualname: String,
value: String,
children: Vec<Id>,
decl_id: Option<Id>,
docs: String,
sig: Option<JsonSignature>,
attributes: Vec<Attribute>,
}
#[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).
Local,
Static,
Const,
Field,
}
impl From<EnumData> for Def {
fn from(data: EnumData) -> Def {
Def { 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,
children: data.variants.into_iter().map(|id| From::from(id)).collect(), parent: None,
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: data.attributes, attributes: self.attributes.into_iter().map(|a| a.into()).collect(),
} }
} }
} }
impl From<TupleVariantData> for Def { impl Into<Def> for TupleVariantData {
fn from(data: TupleVariantData) -> Def { fn into(self) -> Def {
Def { 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: None,
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: data.attributes, attributes: self.attributes.into_iter().map(|a| a.into()).collect(),
} }
} }
} }
impl From<StructVariantData> for Def { impl Into<Def> for StructVariantData {
fn from(data: StructVariantData) -> Def { fn into(self) -> Def {
Def { 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,
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: data.attributes, attributes: self.attributes.into_iter().map(|a| a.into()).collect(),
} }
} }
} }
impl From<StructData> for Def { impl Into<Def> for StructData {
fn from(data: StructData) -> Def { fn into(self) -> Def {
Def { 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,
children: data.fields.into_iter().map(|id| From::from(id)).collect(), parent: None,
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: data.attributes, attributes: self.attributes.into_iter().map(|a| a.into()).collect(),
} }
} }
} }
impl From<TraitData> for Def { impl Into<Def> for TraitData {
fn from(data: TraitData) -> Def { fn into(self) -> Def {
Def { 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(), parent: None,
children: self.items.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: data.attributes, attributes: self.attributes.into_iter().map(|a| a.into()).collect(),
} }
} }
} }
impl From<FunctionData> for Def { impl Into<Def> for FunctionData {
fn from(data: FunctionData) -> Def { fn into(self) -> Def {
Def { 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,
parent: None,
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: data.attributes, attributes: self.attributes.into_iter().map(|a| a.into()).collect(),
} }
} }
} }
impl From<MethodData> for Def { impl Into<Def> for MethodData {
fn from(data: MethodData) -> Def { fn into(self) -> Def {
Def { 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,
parent: None,
children: vec![], children: vec![],
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: data.attributes, attributes: self.attributes.into_iter().map(|a| a.into()).collect(),
} }
} }
} }
impl From<MacroData> for Def { impl Into<Def> for MacroData {
fn from(data: MacroData) -> Def { fn into(self) -> Def {
Def { 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(),
parent: None,
children: vec![], children: vec![],
decl_id: None, decl_id: None,
docs: data.docs, docs: self.docs,
sig: None, sig: None,
attributes: vec![], attributes: vec![],
} }
} }
} }
impl From<TypeDefData> for Def { impl Into<Def> for TypeDefData {
fn from(data: TypeDefData) -> Def { fn into(self) -> Def {
Def { 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,
parent: None,
children: vec![], children: vec![],
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: data.attributes, attributes: self.attributes.into_iter().map(|a| a.into()).collect(),
} }
} }
} }
impl From<VariableData> for Def { impl Into<Def> for VariableData {
fn from(data: VariableData) -> Def { fn into(self) -> Def {
Def { 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 => DefKind::Local, VariableKind::Local => DefKind::Local,
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.type_value, value: self.type_value,
parent: None,
children: vec![], children: vec![],
decl_id: None, decl_id: None,
docs: data.docs, docs: self.docs,
sig: None, sig: None,
attributes: data.attributes, attributes: self.attributes.into_iter().map(|a| a.into()).collect(),
} }
} }
} }
#[derive(Debug, RustcEncodable)] impl Into<Ref> for FunctionRefData {
enum RefKind { fn into(self) -> Ref {
Function,
Mod,
Type,
Variable,
}
#[derive(Debug, RustcEncodable)]
struct Ref {
kind: RefKind,
span: SpanData,
ref_id: Id,
}
impl From<FunctionRefData> for Ref {
fn from(data: FunctionRefData) -> Ref {
Ref { Ref {
kind: RefKind::Function, kind: RefKind::Function,
span: data.span, span: self.span,
ref_id: From::from(data.ref_id), ref_id: id_from_def_id(self.ref_id),
} }
} }
} }
impl From<FunctionCallData> for Ref { impl Into<Ref> for FunctionCallData {
fn from(data: FunctionCallData) -> Ref { fn into(self) -> Ref {
Ref { Ref {
kind: RefKind::Function, kind: RefKind::Function,
span: data.span, span: self.span,
ref_id: From::from(data.ref_id), ref_id: id_from_def_id(self.ref_id),
} }
} }
} }
impl From<MethodCallData> for Ref { impl Into<Ref> for MethodCallData {
fn from(data: MethodCallData) -> Ref { fn into(self) -> Ref {
Ref { Ref {
kind: RefKind::Function, kind: RefKind::Function,
span: data.span, span: self.span,
ref_id: From::from(data.ref_id.or(data.decl_id).unwrap_or(null_def_id())), ref_id: id_from_def_id(self.ref_id.or(self.decl_id).unwrap_or(null_def_id())),
} }
} }
} }
impl From<ModRefData> for Ref { impl Into<Ref> for ModRefData {
fn from(data: ModRefData) -> Ref { fn into(self) -> Ref {
Ref { Ref {
kind: RefKind::Mod, kind: RefKind::Mod,
span: data.span, span: self.span,
ref_id: From::from(data.ref_id.unwrap_or(null_def_id())), ref_id: id_from_def_id(self.ref_id.unwrap_or(null_def_id())),
} }
} }
} }
impl From<TypeRefData> for Ref { impl Into<Ref> for TypeRefData {
fn from(data: TypeRefData) -> Ref { fn into(self) -> Ref {
Ref { Ref {
kind: RefKind::Type, kind: RefKind::Type,
span: data.span, span: self.span,
ref_id: From::from(data.ref_id.unwrap_or(null_def_id())), ref_id: id_from_def_id(self.ref_id.unwrap_or(null_def_id())),
} }
} }
} }
impl From<VariableRefData> for Ref { impl Into<Ref> for VariableRefData {
fn from(data: VariableRefData) -> Ref { fn into(self) -> Ref {
Ref { Ref {
kind: RefKind::Variable, kind: RefKind::Variable,
span: data.span, span: self.span,
ref_id: From::from(data.ref_id), ref_id: id_from_def_id(self.ref_id),
} }
} }
} }
#[derive(Debug, RustcEncodable)] impl Into<MacroRef> for MacroUseData {
struct MacroRef { fn into(self) -> MacroRef {
span: SpanData,
qualname: String,
callee_span: SpanData,
}
impl From<MacroUseData> for MacroRef {
fn from(data: MacroUseData) -> MacroRef {
MacroRef { MacroRef {
span: data.span, span: self.span,
qualname: data.qualname, qualname: self.qualname,
callee_span: data.callee_span, callee_span: self.callee_span.into(),
} }
} }
} }
#[derive(Debug, RustcEncodable)] impl Into<Relation> for ImplData {
struct Relation { fn into(self) -> 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 { Relation {
span: data.span, span: self.span,
kind: RelationKind::Impl, kind: RelationKind::Impl,
from: From::from(data.self_ref.unwrap_or(null_def_id())), from: id_from_def_id(self.self_ref.unwrap_or(null_def_id())),
to: From::from(data.trait_ref.unwrap_or(null_def_id())), to: id_from_def_id(self.trait_ref.unwrap_or(null_def_id())),
} }
} }
} }
impl From<InheritanceData> for Relation { impl Into<Relation> for InheritanceData {
fn from(data: InheritanceData) -> Relation { fn into(self) -> Relation {
Relation { Relation {
span: data.span, span: self.span,
kind: RelationKind::SuperTrait, kind: RelationKind::SuperTrait,
from: From::from(data.base_id), from: id_from_def_id(self.base_id),
to: From::from(data.deriv_id), to: id_from_def_id(self.deriv_id),
} }
} }
} }
#[derive(Debug, RustcEncodable)] impl Into<Signature> for external_data::Signature {
pub struct JsonSignature { fn into(self) -> Signature {
span: SpanData, Signature {
text: String, span: self.span,
ident_start: usize, text: self.text,
ident_end: usize, ident_start: self.ident_start,
defs: Vec<JsonSigElement>, ident_end: self.ident_end,
refs: Vec<JsonSigElement>, defs: self.defs.into_iter().map(|s| s.into()).collect(),
} refs: self.refs.into_iter().map(|s| s.into()).collect(),
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)] impl Into<SigElement> for data::SigElement {
pub struct JsonSigElement { fn into(self) -> SigElement {
id: Id, SigElement {
start: usize, id: id_from_def_id(self.id),
end: usize, start: self.start,
} end: self.end,
impl From<SigElement> for JsonSigElement {
fn from(data: SigElement) -> JsonSigElement {
JsonSigElement {
id: From::from(data.id),
start: data.start,
end: data.end,
} }
} }
} }