]> git.lizzy.rs Git - rust.git/commitdiff
save-analysis: implement JSON dumps
authorNick Cameron <ncameron@mozilla.com>
Mon, 25 Apr 2016 08:54:00 +0000 (20:54 +1200)
committerNick Cameron <ncameron@mozilla.com>
Mon, 25 Apr 2016 08:54:00 +0000 (20:54 +1200)
mk/crates.mk
src/librustc_save_analysis/Cargo.toml
src/librustc_save_analysis/csv_dumper.rs
src/librustc_save_analysis/data.rs
src/librustc_save_analysis/dump.rs
src/librustc_save_analysis/dump_visitor.rs
src/librustc_save_analysis/json_dumper.rs [new file with mode: 0644]
src/librustc_save_analysis/lib.rs

index 02b95f5b1a9276ecd6aa7d1ce23f3cf41f3e98e7..fec9e985e04cdc4d9c49340bb1418ba94b9062d9 100644 (file)
@@ -120,7 +120,7 @@ DEPS_rustc_trans := arena flate getopts graphviz libc rustc rustc_back rustc_mir
                     log syntax serialize rustc_llvm rustc_platform_intrinsics \
                     rustc_const_math rustc_const_eval rustc_incremental
 DEPS_rustc_incremental := rbml rustc serialize rustc_data_structures
-DEPS_rustc_save_analysis := rustc log syntax
+DEPS_rustc_save_analysis := rustc log syntax serialize
 DEPS_rustc_typeck := rustc syntax rustc_platform_intrinsics rustc_const_math \
                      rustc_const_eval
 
index 52fa91934723dd25fe1bb682fab3fb7993d5ffb5..76f5569ecb6a22d278133fcfd6f0ea2d2bf9987e 100644 (file)
@@ -12,3 +12,4 @@ crate-type = ["dylib"]
 log = { path = "../liblog" }
 rustc = { path = "../librustc" }
 syntax = { path = "../libsyntax" }
+serialize = { path = "../librustc_serialize" }
index 69de5365c1409a088390dc6b2dcd6180e46fc1f7..4d6512db861e5063aa0d53992f33f45d1459e11d 100644 (file)
@@ -42,24 +42,20 @@ fn record_raw(&mut self, info: &str) {
 }
 
 impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
-    fn crate_prelude(&mut self, span: Span, data: CratePreludeData) {
-        let crate_root = data.crate_root.unwrap_or("<no source>".to_owned());
-
+    fn crate_prelude(&mut self, data: CratePreludeData) {
         let values = make_values_str(&[
             ("name", &data.crate_name),
-            ("crate_root", &crate_root)
+            ("crate_root", &data.crate_root)
         ]);
 
-        self.record("crate", span, values);
+        self.record("crate", data.span, values);
 
         for c in data.external_crates {
             let num = c.num.to_string();
-            let lo_loc = self.span.sess.codemap().lookup_char_pos(span.lo);
-            let file_name = SpanUtils::make_path_string(&lo_loc.file.name);
             let values = make_values_str(&[
                 ("name", &c.name),
                 ("crate", &num),
-                ("file_name", &file_name)
+                ("file_name", &c.file_name)
             ]);
 
             self.record_raw(&format!("external_crate{}\n", values));
index 7f2f2618c3c96aa19f85966eba741cbb47112c19..2fbeac8be835941be06804483a12900d538e5323 100644 (file)
 pub struct CrateData {
     pub name: String,
     pub number: u32,
+    pub span: Span,
 }
 
 /// Data for any entity in the Rust language. The actual data contained varies
 /// with the kind of entity being queried. See the nested structs for details.
-#[derive(Debug)]
+#[derive(Debug, RustcEncodable)]
 pub enum Data {
     /// Data for Enums.
     EnumData(EnumData),
@@ -79,22 +80,24 @@ pub enum Data {
 }
 
 /// Data for the prelude of a crate.
-#[derive(Debug)]
+#[derive(Debug, RustcEncodable)]
 pub struct CratePreludeData {
     pub crate_name: String,
-    pub crate_root: Option<String>,
-    pub external_crates: Vec<ExternalCrateData>
+    pub crate_root: String,
+    pub external_crates: Vec<ExternalCrateData>,
+    pub span: Span,
 }
 
 /// Data for external crates in the prelude of a crate.
-#[derive(Debug)]
+#[derive(Debug, RustcEncodable)]
 pub struct ExternalCrateData {
     pub name: String,
-    pub num: CrateNum
+    pub num: CrateNum,
+    pub file_name: String,
 }
 
 /// Data for enum declarations.
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, RustcEncodable)]
 pub struct EnumData {
     pub id: NodeId,
     pub value: String,
@@ -104,7 +107,7 @@ pub struct EnumData {
 }
 
 /// Data for extern crates.
-#[derive(Debug)]
+#[derive(Debug, RustcEncodable)]
 pub struct ExternCrateData {
     pub id: NodeId,
     pub name: String,
@@ -115,7 +118,7 @@ pub struct ExternCrateData {
 }
 
 /// Data about a function call.
-#[derive(Debug)]
+#[derive(Debug, RustcEncodable)]
 pub struct FunctionCallData {
     pub span: Span,
     pub scope: NodeId,
@@ -123,7 +126,7 @@ pub struct FunctionCallData {
 }
 
 /// Data for all kinds of functions and methods.
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, RustcEncodable)]
 pub struct FunctionData {
     pub id: NodeId,
     pub name: String,
@@ -134,14 +137,14 @@ pub struct FunctionData {
 }
 
 /// Data about a function call.
-#[derive(Debug)]
+#[derive(Debug, RustcEncodable)]
 pub struct FunctionRefData {
     pub span: Span,
     pub scope: NodeId,
     pub ref_id: DefId,
 }
 
-#[derive(Debug)]
+#[derive(Debug, RustcEncodable)]
 pub struct ImplData {
     pub id: NodeId,
     pub span: Span,
@@ -150,7 +153,7 @@ pub struct ImplData {
     pub self_ref: Option<DefId>,
 }
 
-#[derive(Debug)]
+#[derive(Debug, RustcEncodable)]
 // FIXME: this struct should not exist. However, removing it requires heavy
 // refactoring of dump_visitor.rs. See PR 31838 for more info.
 pub struct ImplData2 {
@@ -164,7 +167,7 @@ pub struct ImplData2 {
     pub self_ref: Option<TypeRefData>,
 }
 
-#[derive(Debug)]
+#[derive(Debug, RustcEncodable)]
 pub struct InheritanceData {
     pub span: Span,
     pub base_id: DefId,
@@ -172,7 +175,7 @@ pub struct InheritanceData {
 }
 
 /// Data about a macro declaration.
-#[derive(Debug)]
+#[derive(Debug, RustcEncodable)]
 pub struct MacroData {
     pub span: Span,
     pub name: String,
@@ -180,7 +183,7 @@ pub struct MacroData {
 }
 
 /// Data about a macro use.
-#[derive(Debug)]
+#[derive(Debug, RustcEncodable)]
 pub struct MacroUseData {
     pub span: Span,
     pub name: String,
@@ -193,7 +196,7 @@ pub struct MacroUseData {
 }
 
 /// Data about a method call.
-#[derive(Debug)]
+#[derive(Debug, RustcEncodable)]
 pub struct MethodCallData {
     pub span: Span,
     pub scope: NodeId,
@@ -202,7 +205,7 @@ pub struct MethodCallData {
 }
 
 /// Data for method declarations (methods with a body are treated as functions).
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, RustcEncodable)]
 pub struct MethodData {
     pub id: NodeId,
     pub qualname: String,
@@ -211,7 +214,7 @@ pub struct MethodData {
 }
 
 /// Data for modules.
-#[derive(Debug)]
+#[derive(Debug, RustcEncodable)]
 pub struct ModData {
     pub id: NodeId,
     pub name: String,
@@ -222,7 +225,7 @@ pub struct ModData {
 }
 
 /// Data for a reference to a module.
-#[derive(Debug)]
+#[derive(Debug, RustcEncodable)]
 pub struct ModRefData {
     pub span: Span,
     pub scope: NodeId,
@@ -230,7 +233,7 @@ pub struct ModRefData {
     pub qualname: String
 }
 
-#[derive(Debug)]
+#[derive(Debug, RustcEncodable)]
 pub struct StructData {
     pub span: Span,
     pub id: NodeId,
@@ -240,7 +243,7 @@ pub struct StructData {
     pub value: String
 }
 
-#[derive(Debug)]
+#[derive(Debug, RustcEncodable)]
 pub struct StructVariantData {
     pub span: Span,
     pub id: NodeId,
@@ -250,7 +253,7 @@ pub struct StructVariantData {
     pub scope: NodeId
 }
 
-#[derive(Debug)]
+#[derive(Debug, RustcEncodable)]
 pub struct TraitData {
     pub span: Span,
     pub id: NodeId,
@@ -259,7 +262,7 @@ pub struct TraitData {
     pub value: String
 }
 
-#[derive(Debug)]
+#[derive(Debug, RustcEncodable)]
 pub struct TupleVariantData {
     pub span: Span,
     pub id: NodeId,
@@ -271,7 +274,7 @@ pub struct TupleVariantData {
 }
 
 /// Data for a typedef.
-#[derive(Debug)]
+#[derive(Debug, RustcEncodable)]
 pub struct TypedefData {
     pub id: NodeId,
     pub span: Span,
@@ -280,7 +283,7 @@ pub struct TypedefData {
 }
 
 /// Data for a reference to a type or trait.
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, RustcEncodable)]
 pub struct TypeRefData {
     pub span: Span,
     pub scope: NodeId,
@@ -288,7 +291,7 @@ pub struct TypeRefData {
     pub qualname: String,
 }
 
-#[derive(Debug)]
+#[derive(Debug, RustcEncodable)]
 pub struct UseData {
     pub id: NodeId,
     pub span: Span,
@@ -297,7 +300,7 @@ pub struct UseData {
     pub scope: NodeId
 }
 
-#[derive(Debug)]
+#[derive(Debug, RustcEncodable)]
 pub struct UseGlobData {
     pub id: NodeId,
     pub span: Span,
@@ -306,7 +309,7 @@ pub struct UseGlobData {
 }
 
 /// Data for local and global variables (consts and statics).
-#[derive(Debug)]
+#[derive(Debug, RustcEncodable)]
 pub struct VariableData {
     pub id: NodeId,
     pub name: String,
@@ -319,7 +322,7 @@ pub struct VariableData {
 
 /// 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)]
+#[derive(Debug, RustcEncodable)]
 pub struct VariableRefData {
     pub name: String,
     pub span: Span,
index 69efa74c582f321a0b071dd04df86b7dce1b5513..feb428b07462e484ef314756041408a3f298bdf5 100644 (file)
@@ -8,33 +8,31 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use syntax::codemap::Span;
-
 use super::data::*;
 
 pub trait Dump {
-    fn crate_prelude(&mut self, _: Span, _: CratePreludeData) {}
-    fn enum_data(&mut self, EnumData) {}
-    fn extern_crate(&mut self, ExternCrateData) {}
-    fn impl_data(&mut self, ImplData) {}
-    fn inheritance(&mut self, InheritanceData) {}
-    fn function(&mut self, FunctionData) {}
-    fn function_ref(&mut self, FunctionRefData) {}
-    fn function_call(&mut self, FunctionCallData) {}
-    fn method(&mut self, MethodData) {}
-    fn method_call(&mut self, MethodCallData) {}
-    fn macro_data(&mut self, MacroData) {}
-    fn macro_use(&mut self, MacroUseData) {}
-    fn mod_data(&mut self, ModData) {}
-    fn mod_ref(&mut self, ModRefData) {}
-    fn struct_data(&mut self, StructData) {}
-    fn struct_variant(&mut self, StructVariantData) {}
-    fn trait_data(&mut self, TraitData) {}
-    fn tuple_variant(&mut self, TupleVariantData) {}
-    fn type_ref(&mut self, TypeRefData) {}
-    fn typedef(&mut self, TypedefData) {}
-    fn use_data(&mut self, UseData) {}
-    fn use_glob(&mut self, UseGlobData) {}
-    fn variable(&mut self, VariableData) {}
-    fn variable_ref(&mut self, VariableRefData) {}
+    fn crate_prelude(&mut self, CratePreludeData);
+    fn enum_data(&mut self, EnumData);
+    fn extern_crate(&mut self, ExternCrateData);
+    fn impl_data(&mut self, ImplData);
+    fn inheritance(&mut self, InheritanceData);
+    fn function(&mut self, FunctionData);
+    fn function_ref(&mut self, FunctionRefData);
+    fn function_call(&mut self, FunctionCallData);
+    fn method(&mut self, MethodData);
+    fn method_call(&mut self, MethodCallData);
+    fn macro_data(&mut self, MacroData);
+    fn macro_use(&mut self, MacroUseData);
+    fn mod_data(&mut self, ModData);
+    fn mod_ref(&mut self, ModRefData);
+    fn struct_data(&mut self, StructData);
+    fn struct_variant(&mut self, StructVariantData);
+    fn trait_data(&mut self, TraitData);
+    fn tuple_variant(&mut self, TupleVariantData);
+    fn type_ref(&mut self, TypeRefData);
+    fn typedef(&mut self, TypedefData);
+    fn use_data(&mut self, UseData);
+    fn use_glob(&mut self, UseGlobData);
+    fn variable(&mut self, VariableData);
+    fn variable_ref(&mut self, VariableRefData);
 }
index c6513a8288b0b568c802ad61f07db0556170f16a..a4efb68e63c25f78ca9c80934c223fc5a60d4c83 100644 (file)
@@ -119,20 +119,23 @@ pub fn dump_crate_info(&mut self, name: &str, krate: &ast::Crate) {
 
         // Info about all the external crates referenced from this crate.
         let external_crates = self.save_ctxt.get_external_crates().into_iter().map(|c| {
+            let lo_loc = self.span.sess.codemap().lookup_char_pos(c.span.lo);
             ExternalCrateData {
                 name: c.name,
-                num: c.number
+                num: c.number,
+                file_name: SpanUtils::make_path_string(&lo_loc.file.name),
             }
         }).collect();
 
         // The current crate.
         let data = CratePreludeData {
             crate_name: name.into(),
-            crate_root: crate_root,
-            external_crates: external_crates
+            crate_root: crate_root.unwrap_or("<no source>".to_owned()),
+            external_crates: external_crates,
+            span: krate.span,
         };
 
-        self.dumper.crate_prelude(krate.span, data);
+        self.dumper.crate_prelude(data);
     }
 
     // Return all non-empty prefixes of a path.
diff --git a/src/librustc_save_analysis/json_dumper.rs b/src/librustc_save_analysis/json_dumper.rs
new file mode 100644 (file)
index 0000000..8a631ad
--- /dev/null
@@ -0,0 +1,63 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::io::Write;
+
+use rustc_serialize::json::as_json;
+
+use super::data::*;
+use super::dump::Dump;
+
+pub struct JsonDumper<'b, W: 'b> {
+    output: &'b mut W,
+}
+
+impl<'b, W: Write> JsonDumper<'b, W> {
+    pub fn new(writer: &'b mut W) -> JsonDumper<'b, W> {
+        JsonDumper { output: writer }
+    }
+}
+
+macro_rules! impl_fn {
+    ($fn_name: ident, $data_type: ident) => {
+        fn $fn_name(&mut self, data: $data_type) {
+            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_fn!(crate_prelude, CratePreludeData);
+    impl_fn!(enum_data, EnumData);
+    impl_fn!(extern_crate, ExternCrateData);
+    impl_fn!(impl_data, ImplData);
+    impl_fn!(inheritance, InheritanceData);
+    impl_fn!(function, FunctionData);
+    impl_fn!(function_ref, FunctionRefData);
+    impl_fn!(function_call, FunctionCallData);
+    impl_fn!(method, MethodData);
+    impl_fn!(method_call, MethodCallData);
+    impl_fn!(macro_data, MacroData);
+    impl_fn!(macro_use, MacroUseData);
+    impl_fn!(mod_data, ModData);
+    impl_fn!(mod_ref, ModRefData);
+    impl_fn!(struct_data, StructData);
+    impl_fn!(struct_variant, StructVariantData);
+    impl_fn!(trait_data, TraitData);
+    impl_fn!(tuple_variant, TupleVariantData);
+    impl_fn!(type_ref, TypeRefData);
+    impl_fn!(typedef, TypedefData);
+    impl_fn!(use_data, UseData);
+    impl_fn!(use_glob, UseGlobData);
+    impl_fn!(variable, VariableData);
+    impl_fn!(variable_ref, VariableRefData);
+}
index 9148b53322bfe61b125620c0d80f1e3011bdf097..db7a7a64998a1658d699c84ecf3cc962fa54d150 100644 (file)
@@ -26,6 +26,7 @@
 
 #[macro_use] extern crate log;
 #[macro_use] extern crate syntax;
+extern crate serialize as rustc_serialize;
 
 use rustc::hir::{self, lowering};
 use rustc::hir::map::NodeItem;
@@ -45,6 +46,7 @@
 use syntax::print::pprust::ty_to_string;
 
 mod csv_dumper;
+mod json_dumper;
 mod data;
 mod dump;
 mod dump_visitor;
@@ -52,6 +54,7 @@
 pub mod span_utils;
 
 pub use self::csv_dumper::CsvDumper;
+pub use self::json_dumper::JsonDumper;
 pub use self::data::*;
 pub use self::dump::Dump;
 pub use self::dump_visitor::DumpVisitor;
@@ -104,9 +107,17 @@ pub fn get_external_crates(&self) -> Vec<CrateData> {
         let mut result = Vec::new();
 
         for n in self.tcx.sess.cstore.crates() {
+            let span = match self.tcx.sess.cstore.extern_crate(n) {
+                Some(ref c) => c.span,
+                None => {
+                    debug!("Skipping crate {}, no data", n);
+                    continue;
+                }
+            };
             result.push(CrateData {
                 name: (&self.tcx.sess.cstore.crate_name(n)[..]).to_owned(),
                 number: n,
+                span: span,
             });
         }