diff --git a/src/Cargo.lock b/src/Cargo.lock index afe7f841f25..6b722db53ed 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -1685,6 +1685,15 @@ dependencies = [ "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rls-data" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rls-rustc" version = "0.2.1" @@ -2122,7 +2131,7 @@ name = "rustc_save_analysis" version = "0.0.0" dependencies = [ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rls-data 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rls-data 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3107,6 +3116,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8e931c58b93d86f080c734bfd2bce7dd0079ae2331235818133c8be7f422e20e" "checksum rls-analysis 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "38841e3c5271715a574ac220d9b408b59ed9e2626909c3bc54b5853b4eaadb7b" "checksum rls-data 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8024f1feaca72d0aa4ae1e2a8d454a31b9a33ed02f8d0e9c8559bf53c267ec3c" +"checksum rls-data 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bea04462e94b5512a78499837eecb7db182ff082144cd1b4bc32ef5d43de6510" "checksum rls-rustc 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "85cfb9dde19e313da3e47738008f8a472e470cc42d910b71595a9238494701f2" "checksum rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d7c7046dc6a92f2ae02ed302746db4382e75131b9ce20ce967259f6b5867a6a" "checksum rls-vfs 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ffd34691a510938bb67fe0444fb363103c73ffb31c121d1e16bc92d8945ea8ff" diff --git a/src/librustc_save_analysis/Cargo.toml b/src/librustc_save_analysis/Cargo.toml index 8b2658b2a88..005faa55b58 100644 --- a/src/librustc_save_analysis/Cargo.toml +++ b/src/librustc_save_analysis/Cargo.toml @@ -15,7 +15,7 @@ rustc_data_structures = { path = "../librustc_data_structures" } rustc_typeck = { path = "../librustc_typeck" } syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } -rls-data = "0.14" +rls-data = "0.15" rls-span = "0.4" # FIXME(#40527) should move rustc serialize out of tree rustc-serialize = "0.3" diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 69cef20622b..47530c42085 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -770,8 +770,12 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { impl_items: &'l [ast::ImplItem], ) { if let Some(impl_data) = self.save_ctxt.get_item_data(item) { - down_cast_data!(impl_data, RelationData, item.span); - self.dumper.dump_relation(impl_data); + if let super::Data::RelationData(rel, imp) = impl_data { + self.dumper.dump_relation(rel); + self.dumper.dump_impl(imp); + } else { + span_bug!(item.span, "unexpected data kind: {:?}", impl_data); + } } self.visit_ty(&typ); if let &Some(ref trait_ref) = trait_ref { diff --git a/src/librustc_save_analysis/json_dumper.rs b/src/librustc_save_analysis/json_dumper.rs index 2b35a412383..1b09df16a7d 100644 --- a/src/librustc_save_analysis/json_dumper.rs +++ b/src/librustc_save_analysis/json_dumper.rs @@ -13,7 +13,7 @@ use std::io::Write; use rustc_serialize::json::as_json; use rls_data::{self, Analysis, CratePreludeData, Def, DefKind, Import, MacroRef, Ref, RefKind, - Relation}; + Relation, Impl}; use rls_data::config::Config; use rls_span::{Column, Row}; @@ -142,4 +142,8 @@ impl<'b, O: DumpOutput + 'b> JsonDumper { pub fn dump_relation(&mut self, data: Relation) { self.result.relations.push(data); } + + pub fn dump_impl(&mut self, data: Impl) { + self.result.impls.push(data); + } } diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 841350bdb68..490dc4e5ac4 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -45,6 +45,7 @@ use rustc::session::config::CrateType::CrateTypeExecutable; use rustc::ty::{self, TyCtxt}; use rustc_typeck::hir_ty_to_ty; +use std::cell::Cell; use std::default::Default; use std::env; use std::fs::File; @@ -65,7 +66,7 @@ use dump_visitor::DumpVisitor; use span_utils::SpanUtils; use rls_data::{Def, DefKind, ExternalCrateData, GlobalCrateId, MacroRef, Ref, RefKind, Relation, - RelationKind, SpanData}; + RelationKind, SpanData, Impl, ImplKind}; use rls_data::config::Config; @@ -75,13 +76,14 @@ pub struct SaveContext<'l, 'tcx: 'l> { analysis: &'l ty::CrateAnalysis, span_utils: SpanUtils<'tcx>, config: Config, + impl_counter: Cell, } #[derive(Debug)] pub enum Data { RefData(Ref), DefData(Def), - RelationData(Relation), + RelationData(Relation, Impl), } impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { @@ -315,7 +317,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { attributes: lower_attributes(item.attrs.to_owned(), self), })) } - ast::ItemKind::Impl(.., ref trait_ref, ref typ, _) => { + ast::ItemKind::Impl(.., ref trait_ref, ref typ, ref impls) => { if let ast::TyKind::Path(None, ref path) = typ.node { // Common case impl for a struct or something basic. if generated_code(path.span) { @@ -324,17 +326,39 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { let sub_span = self.span_utils.sub_span_for_type_name(path.span); filter!(self.span_utils, sub_span, typ.span, None); + let impl_id = self.next_impl_id(); + let span = self.span_from_span(sub_span.unwrap()); + let type_data = self.lookup_ref_id(typ.id); type_data.map(|type_data| { Data::RelationData(Relation { - kind: RelationKind::Impl, - span: self.span_from_span(sub_span.unwrap()), + kind: RelationKind::Impl { + id: impl_id, + }, + span: span.clone(), from: id_from_def_id(type_data), to: trait_ref .as_ref() .and_then(|t| self.lookup_ref_id(t.ref_id)) .map(id_from_def_id) .unwrap_or(null_id()), + }, + Impl { + id: impl_id, + kind: match *trait_ref { + Some(_) => ImplKind::Direct, + None => ImplKind::Inherent, + }, + span: span, + value: String::new(), + parent: None, + children: impls + .iter() + .map(|i| id_from_node_id(i.id, self)) + .collect(), + docs: String::new(), + sig: None, + attributes: vec![], }) }) } else { @@ -893,6 +917,12 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { result } + + fn next_impl_id(&self) -> u32 { + let next = self.impl_counter.get(); + self.impl_counter.set(next + 1); + next + } } fn make_signature(decl: &ast::FnDecl, generics: &ast::Generics) -> String { @@ -1099,6 +1129,7 @@ pub fn process_crate<'l, 'tcx, H: SaveHandler>( analysis, span_utils: SpanUtils::new(&tcx.sess), config: find_config(config), + impl_counter: Cell::new(0), }; handler.save(save_ctxt, krate, cratename)