]> git.lizzy.rs Git - rust.git/commitdiff
save-analysis-json: introduce a lowering step
authorNick Cameron <ncameron@mozilla.com>
Mon, 25 Apr 2016 10:53:01 +0000 (22:53 +1200)
committerNick Cameron <ncameron@mozilla.com>
Mon, 25 Apr 2016 10:53:01 +0000 (22:53 +1200)
...in which we make the spans nice.

src/librustc_save_analysis/data.rs
src/librustc_save_analysis/json_dumper.rs

index 2fbeac8be835941be06804483a12900d538e5323..b79c459920a3e5f075cbb28a6eff8f53343b4d09 100644 (file)
 use rustc::hir::def_id::DefId;
 use rustc::ty;
 use syntax::ast::{CrateNum, NodeId};
-use syntax::codemap::Span;
+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,
+        }
+    }
+}
 
 pub struct CrateData {
     pub name: String,
index 8a631ad8b32c62d086066157b9951532085cc6fb..e040b392ae7218e8d3d8812345ea893982412bbd 100644 (file)
 use std::io::Write;
 
 use rustc_serialize::json::as_json;
+use syntax::codemap::CodeMap;
 
-use super::data::*;
+use rustc::hir::def_id::DefId;
+use syntax::ast::{CrateNum, NodeId};
+
+use super::data::{self, SpanData};
 use super::dump::Dump;
 
-pub struct JsonDumper<'b, W: 'b> {
+pub struct JsonDumper<'a, 'b, W: 'b> {
     output: &'b mut W,
+    codemap: &'a CodeMap,
 }
 
-impl<'b, W: Write> JsonDumper<'b, W> {
-    pub fn new(writer: &'b mut W) -> JsonDumper<'b, W> {
-        JsonDumper { output: writer }
+impl<'a, 'b, W: Write> JsonDumper<'a, 'b, W> {
+    pub fn new(writer: &'b mut W, codemap: &'a CodeMap) -> JsonDumper<'a, 'b, W> {
+        JsonDumper { output: writer, codemap:codemap }
     }
 }
 
 macro_rules! impl_fn {
     ($fn_name: ident, $data_type: ident) => {
-        fn $fn_name(&mut self, data: $data_type) {
+        fn $fn_name(&mut self, data: data::$data_type) {
+            let data = data.lower(self.codemap);
             if let Err(_) = write!(self.output, "{}", as_json(&data)) {
                 error!("Error writing output '{}'", as_json(&data));
             }
-        }        
+        }
     }
 }
 
-impl<'b, W: Write + 'b> Dump for JsonDumper<'b, W> {
+impl<'a, 'b, W: Write + 'b> Dump for JsonDumper<'a, 'b, W> {
     impl_fn!(crate_prelude, CratePreludeData);
     impl_fn!(enum_data, EnumData);
     impl_fn!(extern_crate, ExternCrateData);
@@ -61,3 +67,565 @@ impl<'b, W: Write + 'b> Dump for JsonDumper<'b, W> {
     impl_fn!(variable, VariableData);
     impl_fn!(variable_ref, VariableRefData);
 }
+
+trait Lower {
+    type Target;
+    fn lower(self, cm: &CodeMap) -> Self::Target;
+}
+
+#[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 {
+    type Target = CratePreludeData;
+
+    fn lower(self, cm: &CodeMap) -> CratePreludeData {
+        CratePreludeData {
+            crate_name: self.crate_name,
+            crate_root: self.crate_root,
+            external_crates: self.external_crates,
+            span: SpanData::from_span(self.span, cm),    
+        }
+    }
+}
+
+/// Data for enum declarations.
+#[derive(Clone, Debug, RustcEncodable)]
+pub struct EnumData {
+    pub id: NodeId,
+    pub value: String,
+    pub qualname: String,
+    pub span: SpanData,
+    pub scope: NodeId,
+}
+
+impl Lower for data::EnumData {
+    type Target = EnumData;
+
+    fn lower(self, cm: &CodeMap) -> EnumData {
+        EnumData {
+            id: self.id,
+            value: self.value,
+            qualname: self.qualname,
+            span: SpanData::from_span(self.span, cm),    
+            scope: self.scope,
+        }
+    }
+}
+
+/// Data for extern crates.
+#[derive(Debug, RustcEncodable)]
+pub struct ExternCrateData {
+    pub id: NodeId,
+    pub name: String,
+    pub crate_num: CrateNum,
+    pub location: String,
+    pub span: SpanData,
+    pub scope: NodeId,
+}
+
+impl Lower for data::ExternCrateData {
+    type Target = ExternCrateData;
+
+    fn lower(self, cm: &CodeMap) -> ExternCrateData {
+        ExternCrateData {
+            id: self.id,
+            name: self.name,
+            crate_num: self.crate_num,
+            location: self.location,
+            span: SpanData::from_span(self.span, cm),    
+            scope: self.scope,
+        }
+    }
+}
+
+/// Data about a function call.
+#[derive(Debug, RustcEncodable)]
+pub struct FunctionCallData {
+    pub span: SpanData,
+    pub scope: NodeId,
+    pub ref_id: DefId,
+}
+
+impl Lower for data::FunctionCallData {
+    type Target = FunctionCallData;
+
+    fn lower(self, cm: &CodeMap) -> FunctionCallData {
+        FunctionCallData {
+            span: SpanData::from_span(self.span, cm),    
+            scope: self.scope,
+            ref_id: self.ref_id,
+        }
+    }
+}
+
+/// Data for all kinds of functions and methods.
+#[derive(Clone, Debug, RustcEncodable)]
+pub struct FunctionData {
+    pub id: NodeId,
+    pub name: String,
+    pub qualname: String,
+    pub declaration: Option<DefId>,
+    pub span: SpanData,
+    pub scope: NodeId,
+}
+
+impl Lower for data::FunctionData {
+    type Target = FunctionData;
+
+    fn lower(self, cm: &CodeMap) -> FunctionData {
+        FunctionData {
+            id: self.id,
+            name: self.name,
+            qualname: self.qualname,
+            declaration: self.declaration,
+            span: SpanData::from_span(self.span, cm),    
+            scope: self.scope,
+        }
+    }
+}
+
+/// Data about a function call.
+#[derive(Debug, RustcEncodable)]
+pub struct FunctionRefData {
+    pub span: SpanData,
+    pub scope: NodeId,
+    pub ref_id: DefId,
+}
+
+impl Lower for data::FunctionRefData {
+    type Target = FunctionRefData;
+
+    fn lower(self, cm: &CodeMap) -> FunctionRefData {
+        FunctionRefData {
+            span: SpanData::from_span(self.span, cm),    
+            scope: self.scope,
+            ref_id: self.ref_id,
+        }
+    }
+}
+#[derive(Debug, RustcEncodable)]
+pub struct ImplData {
+    pub id: NodeId,
+    pub span: SpanData,
+    pub scope: NodeId,
+    pub trait_ref: Option<DefId>,
+    pub self_ref: Option<DefId>,
+}
+
+impl Lower for data::ImplData {
+    type Target = ImplData;
+
+    fn lower(self, cm: &CodeMap) -> ImplData {
+        ImplData {
+            id: self.id,
+            span: SpanData::from_span(self.span, cm),    
+            scope: self.scope,
+            trait_ref: self.trait_ref,
+            self_ref: self.self_ref,
+        }
+    }
+}
+
+#[derive(Debug, RustcEncodable)]
+pub struct InheritanceData {
+    pub span: SpanData,
+    pub base_id: DefId,
+    pub deriv_id: NodeId
+}
+
+impl Lower for data::InheritanceData {
+    type Target = InheritanceData;
+
+    fn lower(self, cm: &CodeMap) -> InheritanceData {
+        InheritanceData {
+            span: SpanData::from_span(self.span, cm),    
+            base_id: self.base_id,
+            deriv_id: self.deriv_id
+        }
+    }
+}
+
+/// Data about a macro declaration.
+#[derive(Debug, RustcEncodable)]
+pub struct MacroData {
+    pub span: SpanData,
+    pub name: String,
+    pub qualname: String,
+}
+
+impl Lower for data::MacroData {
+    type Target = MacroData;
+
+    fn lower(self, cm: &CodeMap) -> MacroData {
+        MacroData {
+            span: SpanData::from_span(self.span, cm),    
+            name: self.name,
+            qualname: self.qualname,
+        }
+    }
+}
+
+/// Data about a macro use.
+#[derive(Debug, RustcEncodable)]
+pub struct MacroUseData {
+    pub span: SpanData,
+    pub name: String,
+    pub qualname: String,
+    // Because macro expansion happens before ref-ids are determined,
+    // we use the callee span to reference the associated macro definition.
+    pub callee_span: SpanData,
+    pub scope: NodeId,
+    pub imported: bool,
+}
+
+impl Lower for data::MacroUseData {
+    type Target = MacroUseData;
+
+    fn lower(self, cm: &CodeMap) -> MacroUseData {
+        MacroUseData {
+            span: SpanData::from_span(self.span, cm),    
+            name: self.name,
+            qualname: self.qualname,
+            callee_span: SpanData::from_span(self.callee_span, cm),
+            scope: self.scope,
+            imported: self.imported,
+        }
+    }
+}
+
+/// Data about a method call.
+#[derive(Debug, RustcEncodable)]
+pub struct MethodCallData {
+    pub span: SpanData,
+    pub scope: NodeId,
+    pub ref_id: Option<DefId>,
+    pub decl_id: Option<DefId>,
+}
+
+impl Lower for data::MethodCallData {
+    type Target = MethodCallData;
+
+    fn lower(self, cm: &CodeMap) -> MethodCallData {
+        MethodCallData {
+            span: SpanData::from_span(self.span, cm),    
+            scope: self.scope,
+            ref_id: self.ref_id,
+            decl_id: self.decl_id,
+        }
+    }
+}
+
+/// Data for method declarations (methods with a body are treated as functions).
+#[derive(Clone, Debug, RustcEncodable)]
+pub struct MethodData {
+    pub id: NodeId,
+    pub qualname: String,
+    pub span: SpanData,
+    pub scope: NodeId,
+}
+
+impl Lower for data::MethodData {
+    type Target = MethodData;
+
+    fn lower(self, cm: &CodeMap) -> MethodData {
+        MethodData {
+            span: SpanData::from_span(self.span, cm),    
+            scope: self.scope,
+            id: self.id,
+            qualname: self.qualname,
+        }
+    }
+}
+
+/// Data for modules.
+#[derive(Debug, RustcEncodable)]
+pub struct ModData {
+    pub id: NodeId,
+    pub name: String,
+    pub qualname: String,
+    pub span: SpanData,
+    pub scope: NodeId,
+    pub filename: String,
+}
+
+impl Lower for data::ModData {
+    type Target = ModData;
+
+    fn lower(self, cm: &CodeMap) -> ModData {
+        ModData {
+            id: self.id,
+            name: self.name,
+            qualname: self.qualname,
+            span: SpanData::from_span(self.span, cm),    
+            scope: self.scope,
+            filename: self.filename,
+        }
+    }
+}
+
+/// Data for a reference to a module.
+#[derive(Debug, RustcEncodable)]
+pub struct ModRefData {
+    pub span: SpanData,
+    pub scope: NodeId,
+    pub ref_id: Option<DefId>,
+    pub qualname: String
+}
+
+impl Lower for data::ModRefData {
+    type Target = ModRefData;
+
+    fn lower(self, cm: &CodeMap) -> ModRefData {
+        ModRefData {
+            span: SpanData::from_span(self.span, cm),    
+            scope: self.scope,
+            ref_id: self.ref_id,
+            qualname: self.qualname,
+        }
+    }
+}
+
+#[derive(Debug, RustcEncodable)]
+pub struct StructData {
+    pub span: SpanData,
+    pub id: NodeId,
+    pub ctor_id: NodeId,
+    pub qualname: String,
+    pub scope: NodeId,
+    pub value: String
+}
+
+impl Lower for data::StructData {
+    type Target = StructData;
+
+    fn lower(self, cm: &CodeMap) -> StructData {
+        StructData {
+            span: SpanData::from_span(self.span, cm),    
+            id: self.id,
+            ctor_id: self.ctor_id,
+            qualname: self.qualname,
+            scope: self.scope,
+            value: self.value
+        }
+    }
+}
+
+#[derive(Debug, RustcEncodable)]
+pub struct StructVariantData {
+    pub span: SpanData,
+    pub id: NodeId,
+    pub qualname: String,
+    pub type_value: String,
+    pub value: String,
+    pub scope: NodeId
+}
+
+impl Lower for data::StructVariantData {
+    type Target = StructVariantData;
+
+    fn lower(self, cm: &CodeMap) -> StructVariantData {
+        StructVariantData {
+            span: SpanData::from_span(self.span, cm),    
+            id: self.id,
+            qualname: self.qualname,
+            type_value: self.type_value,
+            value: self.value,
+            scope: self.scope,
+        }
+    }
+}
+
+#[derive(Debug, RustcEncodable)]
+pub struct TraitData {
+    pub span: SpanData,
+    pub id: NodeId,
+    pub qualname: String,
+    pub scope: NodeId,
+    pub value: String
+}
+
+impl Lower for data::TraitData {
+    type Target = TraitData;
+
+    fn lower(self, cm: &CodeMap) -> TraitData {
+        TraitData {
+            span: SpanData::from_span(self.span, cm),    
+            id: self.id,
+            qualname: self.qualname,
+            scope: self.scope,
+            value: self.value,
+        }
+    }
+}
+
+#[derive(Debug, RustcEncodable)]
+pub struct TupleVariantData {
+    pub span: SpanData,
+    pub id: NodeId,
+    pub name: String,
+    pub qualname: String,
+    pub type_value: String,
+    pub value: String,
+    pub scope: NodeId,
+}
+
+impl Lower for data::TupleVariantData {
+    type Target = TupleVariantData;
+
+    fn lower(self, cm: &CodeMap) -> TupleVariantData {
+        TupleVariantData {
+            span: SpanData::from_span(self.span, cm),    
+            id: self.id,
+            name: self.name,
+            qualname: self.qualname,
+            type_value: self.type_value,
+            value: self.value,
+            scope: self.scope,
+        }
+    }
+}
+
+/// Data for a typedef.
+#[derive(Debug, RustcEncodable)]
+pub struct TypedefData {
+    pub id: NodeId,
+    pub span: SpanData,
+    pub qualname: String,
+    pub value: String,
+}
+
+impl Lower for data::TypedefData {
+    type Target = TypedefData;
+
+    fn lower(self, cm: &CodeMap) -> TypedefData {
+        TypedefData {
+            id: self.id,
+            span: SpanData::from_span(self.span, cm),    
+            qualname: self.qualname,
+            value: self.value,
+        }
+    }
+}
+
+/// Data for a reference to a type or trait.
+#[derive(Clone, Debug, RustcEncodable)]
+pub struct TypeRefData {
+    pub span: SpanData,
+    pub scope: NodeId,
+    pub ref_id: Option<DefId>,
+    pub qualname: String,
+}
+
+impl Lower for data::TypeRefData {
+    type Target = TypeRefData;
+
+    fn lower(self, cm: &CodeMap) -> TypeRefData {
+        TypeRefData {
+            span: SpanData::from_span(self.span, cm),    
+            scope: self.scope,
+            ref_id: self.ref_id,
+            qualname: self.qualname,
+        }
+    }
+}
+
+#[derive(Debug, RustcEncodable)]
+pub struct UseData {
+    pub id: NodeId,
+    pub span: SpanData,
+    pub name: String,
+    pub mod_id: Option<DefId>,
+    pub scope: NodeId
+}
+
+impl Lower for data::UseData {
+    type Target = UseData;
+
+    fn lower(self, cm: &CodeMap) -> UseData {
+        UseData {
+            id: self.id,
+            span: SpanData::from_span(self.span, cm),    
+            name: self.name,
+            mod_id: self.mod_id,
+            scope: self.scope,
+        }
+    }
+}
+
+#[derive(Debug, RustcEncodable)]
+pub struct UseGlobData {
+    pub id: NodeId,
+    pub span: SpanData,
+    pub names: Vec<String>,
+    pub scope: NodeId
+}
+
+impl Lower for data::UseGlobData {
+    type Target = UseGlobData;
+
+    fn lower(self, cm: &CodeMap) -> UseGlobData {
+        UseGlobData {
+            id: self.id,
+            span: SpanData::from_span(self.span, cm),    
+            names: self.names,
+            scope: self.scope,
+        }
+    }
+}
+
+/// Data for local and global variables (consts and statics).
+#[derive(Debug, RustcEncodable)]
+pub struct VariableData {
+    pub id: NodeId,
+    pub name: String,
+    pub qualname: String,
+    pub span: SpanData,
+    pub scope: NodeId,
+    pub value: String,
+    pub type_value: String,
+}
+
+impl Lower for data::VariableData {
+    type Target = VariableData;
+
+    fn lower(self, cm: &CodeMap) -> VariableData {
+        VariableData {
+            id: self.id,
+            name: self.name,
+            qualname: self.qualname,
+            span: SpanData::from_span(self.span, cm),    
+            scope: self.scope,
+            value: self.value,
+            type_value: self.type_value,
+        }
+    }
+}
+
+/// Data for the use of some item (e.g., the use of a local variable, which
+/// will refer to that variables declaration (by ref_id)).
+#[derive(Debug, RustcEncodable)]
+pub struct VariableRefData {
+    pub name: String,
+    pub span: SpanData,
+    pub scope: NodeId,
+    pub ref_id: DefId,
+}
+
+impl Lower for data::VariableRefData {
+    type Target = VariableRefData;
+
+    fn lower(self, cm: &CodeMap) -> VariableRefData {
+        VariableRefData {
+            name: self.name,
+            span: SpanData::from_span(self.span, cm),    
+            scope: self.scope,
+            ref_id: self.ref_id,
+        }
+    }
+}