Skip to content

Commit

Permalink
save-analysis: use a decoupled representation for dumped data
Browse files Browse the repository at this point in the history
Closes #33348
  • Loading branch information
aochagavia committed May 3, 2016
1 parent 7d8100a commit dca29d7
Show file tree
Hide file tree
Showing 8 changed files with 752 additions and 838 deletions.
119 changes: 35 additions & 84 deletions src/librustc_save_analysis/csv_dumper.rs
Expand Up @@ -10,25 +10,20 @@

use std::io::Write;

use rustc::hir::def_id::{DefId, DefIndex};
use syntax::codemap::Span;

use super::data::*;
use super::external_data::*;
use super::dump::Dump;
use super::span_utils::SpanUtils;

pub struct CsvDumper<'tcx, 'b, W: 'b> {
output: &'b mut W,
span: SpanUtils<'tcx>
pub struct CsvDumper<'b, W: 'b> {
output: &'b mut W
}

impl<'a, 'b, W: Write> CsvDumper<'a, 'b, W> {
pub fn new(writer: &'b mut W, span: SpanUtils<'a>) -> CsvDumper<'a, 'b, W> {
CsvDumper { output: writer, span: span }
impl<'b, W: Write> CsvDumper<'b, W> {
pub fn new(writer: &'b mut W) -> CsvDumper<'b, W> {
CsvDumper { output: writer }
}

fn record(&mut self, kind: &str, span: Span, values: String) {
let span_str = self.span.extent_str(span);
fn record(&mut self, kind: &str, span: SpanData, values: String) {
let span_str = span_extent_str(span);
if let Err(_) = write!(self.output, "{},{}{}\n", kind, span_str, values) {
error!("Error writing output");
}
Expand All @@ -41,7 +36,7 @@ impl<'a, 'b, W: Write> CsvDumper<'a, 'b, W> {
}
}

impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
impl<'b, W: Write + 'b> Dump for CsvDumper<'b, W> {
fn crate_prelude(&mut self, data: CratePreludeData) {
let values = make_values_str(&[
("name", &data.crate_name),
Expand Down Expand Up @@ -93,68 +88,50 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
}

fn impl_data(&mut self, data: ImplData) {
let self_ref = data.self_ref.unwrap_or(null_def_id());
let trait_ref = data.trait_ref.unwrap_or(null_def_id());

let id = data.id.to_string();
let ref_id = self_ref.index.as_usize().to_string();
let ref_id_crate = self_ref.krate.to_string();
let trait_id = trait_ref.index.as_usize().to_string();
let trait_id_crate = trait_ref.krate.to_string();
let ref_id = data.self_ref.unwrap_or(Id::null()).to_string();
let trait_id = data.trait_ref.unwrap_or(Id::null()).to_string();
let scope = data.scope.to_string();
let values = make_values_str(&[
("id", &id),
("refid", &ref_id),
("refidcrate", &ref_id_crate),
("traitid", &trait_id),
("traitidcrate", &trait_id_crate),
("scopeid", &scope)
]);

self.record("impl", data.span, values);
}

fn inheritance(&mut self, data: InheritanceData) {
let base_id = data.base_id.index.as_usize().to_string();
let base_crate = data.base_id.krate.to_string();
let deriv_id = data.deriv_id.to_string();
let deriv_crate = 0.to_string();
let values = make_values_str(&[
("base", &base_id),
("basecrate", &base_crate),
("derived", &deriv_id),
("derivedcrate", &deriv_crate)
]);
let base_id = data.base_id.to_string();
let deriv_id = data.deriv_id.to_string();
let values = make_values_str(&[
("base", &base_id),
("derived", &deriv_id),
]);

self.record("inheritance", data.span, values);
}

fn function(&mut self, data: FunctionData) {
let (decl_id, decl_crate) = match data.declaration {
Some(id) => (id.index.as_usize().to_string(), id.krate.to_string()),
None => (String::new(), String::new())
};

let id = data.id.to_string();
let decl_id = data.declaration.unwrap_or(Id::null()).to_string();
let scope = data.scope.to_string();
let values = make_values_str(&[
("id", &id),
("qualname", &data.qualname),
("declid", &decl_id),
("declidcrate", &decl_crate),
("scopeid", &scope)
]);

self.record("function", data.span, values);
}

fn function_ref(&mut self, data: FunctionRefData) {
let ref_id = data.ref_id.index.as_usize().to_string();
let ref_crate = data.ref_id.krate.to_string();
let ref_id = data.ref_id.to_string();
let scope = data.scope.to_string();
let values = make_values_str(&[
("refid", &ref_id),
("refidcrate", &ref_crate),
("qualname", ""),
("scopeid", &scope)
]);
Expand All @@ -163,13 +140,11 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
}

fn function_call(&mut self, data: FunctionCallData) {
let ref_id = data.ref_id.index.as_usize().to_string();
let ref_crate = data.ref_id.krate.to_string();
let ref_id = data.ref_id.to_string();
let qualname = String::new();
let scope = data.scope.to_string();
let values = make_values_str(&[
("refid", &ref_id),
("refidcrate", &ref_crate),
("qualname", &qualname),
("scopeid", &scope)
]);
Expand All @@ -190,21 +165,12 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
}

fn method_call(&mut self, data: MethodCallData) {
let (dcn, dck) = match data.decl_id {
Some(declid) => (declid.index.as_usize().to_string(), declid.krate.to_string()),
None => (String::new(), String::new()),
};

let ref_id = data.ref_id.unwrap_or(null_def_id());

let def_id = ref_id.index.as_usize().to_string();
let def_crate = ref_id.krate.to_string();
let decl_id = data.decl_id.unwrap_or(Id::null()).to_string();
let ref_id = data.ref_id.unwrap_or(Id::null()).to_string();
let scope = data.scope.to_string();
let values = make_values_str(&[
("refid", &def_id),
("refidcrate", &def_crate),
("declid", &dcn),
("declidcrate", &dck),
("refid", &ref_id),
("declid", &decl_id),
("scopeid", &scope)
]);

Expand Down Expand Up @@ -245,15 +211,11 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
}

fn mod_ref(&mut self, data: ModRefData) {
let (ref_id, ref_crate) = match data.ref_id {
Some(rid) => (rid.index.as_usize().to_string(), rid.krate.to_string()),
None => (0.to_string(), 0.to_string())
};
let ref_id = data.ref_id.unwrap_or(Id::null()).to_string();

let scope = data.scope.to_string();
let values = make_values_str(&[
("refid", &ref_id),
("refidcrate", &ref_crate),
("qualname", &data.qualname),
("scopeid", &scope)
]);
Expand Down Expand Up @@ -320,15 +282,10 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
}

fn type_ref(&mut self, data: TypeRefData) {
let (ref_id, ref_crate) = match data.ref_id {
Some(id) => (id.index.as_usize().to_string(), id.krate.to_string()),
None => (0.to_string(), 0.to_string())
};

let ref_id = data.ref_id.unwrap_or(Id::null()).to_string();
let scope = data.scope.to_string();
let values = make_values_str(&[
("refid", &ref_id),
("refidcrate", &ref_crate),
("qualname", &data.qualname),
("scopeid", &scope)
]);
Expand All @@ -348,16 +305,12 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
}

fn use_data(&mut self, data: UseData) {
let mod_id = data.mod_id.unwrap_or(null_def_id());

let id = data.id.to_string();
let ref_id = mod_id.index.as_usize().to_string();
let ref_crate = mod_id.krate.to_string();
let mod_id = data.mod_id.unwrap_or(Id::null()).to_string();
let scope = data.scope.to_string();
let values = make_values_str(&[
("id", &id),
("refid", &ref_id),
("refidcrate", &ref_crate),
("mod_id", &mod_id),
("name", &data.name),
("scopeid", &scope)
]);
Expand Down Expand Up @@ -395,12 +348,10 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
}

fn variable_ref(&mut self, data: VariableRefData) {
let ref_id = data.ref_id.index.as_usize().to_string();
let ref_crate = data.ref_id.krate.to_string();
let id = data.ref_id.to_string();
let scope = data.scope.to_string();
let values = make_values_str(&[
("refid", &ref_id),
("refidcrate", &ref_crate),
("id", &id),
("qualname", ""),
("scopeid", &scope)
]);
Expand Down Expand Up @@ -431,9 +382,9 @@ fn make_values_str(pairs: &[(&'static str, &str)]) -> String {
})
}

fn null_def_id() -> DefId {
DefId {
krate: 0,
index: DefIndex::new(0),
}
fn span_extent_str(span: SpanData) -> String {
format!("file_name,\"{}\",file_line,{},file_col,{},byte_start,{}\
file_line_end,{},file_col_end,{},byte_end,{}",
span.file_name, span.line_start, span.column_start, span.byte_start,
span.line_end, span.column_end, span.byte_end)
}
88 changes: 1 addition & 87 deletions src/librustc_save_analysis/data.rs
Expand Up @@ -16,39 +16,8 @@
use std::hash::Hasher;

use rustc::hir::def_id::DefId;
use rustc::ty;
use syntax::ast::{CrateNum, NodeId};
use syntax::codemap::{Span, CodeMap};

#[derive(Debug, Clone, RustcEncodable)]
pub struct SpanData {
file_name: String,
byte_start: u32,
byte_end: u32,
/// 1-based.
line_start: usize,
line_end: usize,
/// 1-based, character offset.
column_start: usize,
column_end: usize,
}

impl SpanData {
pub fn from_span(span: Span, cm: &CodeMap) -> SpanData {
let start = cm.lookup_char_pos(span.lo);
let end = cm.lookup_char_pos(span.hi);

SpanData {
file_name: start.file.name.clone(),
byte_start: span.lo.0,
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,
}
}
}
use syntax::codemap::Span;

pub struct CrateData {
pub name: String,
Expand Down Expand Up @@ -359,58 +328,3 @@ pub struct VariableRefData {
pub scope: NodeId,
pub ref_id: DefId,
}

// Emitted ids are used to cross-reference items across crates. DefIds and
// NodeIds do not usually correspond in any way. The strategy is to use the
// index from the DefId as a crate-local id. However, within a crate, DefId
// indices and NodeIds can overlap. So, we must adjust the NodeIds. If an
// item can be identified by a DefId as well as a NodeId, then we use the
// DefId index as the id. If it can't, then we have to use the NodeId, but
// need to adjust it so it will not clash with any possible DefId index.
pub fn normalize_node_id<'a>(tcx: &ty::TyCtxt<'a>, id: NodeId) -> usize {
match tcx.map.opt_local_def_id(id) {
Some(id) => id.index.as_usize(),
None => id as usize + tcx.map.num_local_def_ids()
}
}

// Macro to implement a normalize() function (see below for usage)
macro_rules! impl_normalize {
($($t:ty => $($field:ident),*);*) => {
$(
impl $t {
pub fn normalize<'a>(mut self, tcx: &ty::TyCtxt<'a>) -> $t {
$(
self.$field = normalize_node_id(tcx, self.$field) as u32;
)*
self
}
}
)*
}
}

impl_normalize! {
EnumData => id, scope;
ExternCrateData => id, scope;
FunctionCallData => scope;
FunctionData => id, scope;
FunctionRefData => scope;
ImplData => id, scope;
InheritanceData => deriv_id;
MacroUseData => scope;
MethodCallData => scope;
MethodData => id, scope;
ModData => id, scope;
ModRefData => scope;
StructData => ctor_id, id, scope;
StructVariantData => id, scope;
TupleVariantData => id, scope;
TraitData => id, scope;
TypedefData => id;
TypeRefData => scope;
UseData => id, scope;
UseGlobData => id, scope;
VariableData => id;
VariableRefData => scope
}
2 changes: 1 addition & 1 deletion src/librustc_save_analysis/dump.rs
Expand Up @@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use super::data::*;
use super::external_data::*;

pub trait Dump {
fn crate_prelude(&mut self, CratePreludeData) {}
Expand Down

0 comments on commit dca29d7

Please sign in to comment.