From 8a2857e6449c1b90355223367fb4884adb0ba860 Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Thu, 8 Jun 2017 14:45:15 +1200 Subject: [PATCH] Remove intermediate forms and some other refactoring --- src/librustc_save_analysis/data.rs | 421 -------- src/librustc_save_analysis/dump.rs | 40 - src/librustc_save_analysis/dump_visitor.rs | 998 ++++++++---------- src/librustc_save_analysis/external_data.rs | 748 ------------- src/librustc_save_analysis/json_api_dumper.rs | 308 +----- src/librustc_save_analysis/json_dumper.rs | 401 +------ src/librustc_save_analysis/lib.rs | 626 ++++++----- src/librustc_save_analysis/span_utils.rs | 129 +-- 8 files changed, 843 insertions(+), 2828 deletions(-) delete mode 100644 src/librustc_save_analysis/data.rs delete mode 100644 src/librustc_save_analysis/dump.rs delete mode 100644 src/librustc_save_analysis/external_data.rs diff --git a/src/librustc_save_analysis/data.rs b/src/librustc_save_analysis/data.rs deleted file mode 100644 index e15e3f6e79e..00000000000 --- a/src/librustc_save_analysis/data.rs +++ /dev/null @@ -1,421 +0,0 @@ -// Copyright 2012-2014 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Structs representing the analysis data from a crate. -//! -//! The `Dump` trait can be used together with `DumpVisitor` in order to -//! retrieve the data from a crate. - -use rustc::hir; -use rustc::hir::def_id::{CrateNum, DefId}; -use syntax::ast::{self, Attribute, NodeId}; -use syntax_pos::Span; - -use rls_data::{ExternalCrateData, Signature}; - -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)] -pub enum Data { - /// Data for Enums. - EnumData(EnumData), - /// Data for extern crates. - ExternCrateData(ExternCrateData), - /// Data about a function call. - FunctionCallData(FunctionCallData), - /// Data for all kinds of functions and methods. - FunctionData(FunctionData), - /// Data about a function ref. - FunctionRefData(FunctionRefData), - /// Data for impls. - ImplData(ImplData2), - /// Data for trait inheritance. - InheritanceData(InheritanceData), - /// Data about a macro declaration. - MacroData(MacroData), - /// Data about a macro use. - MacroUseData(MacroUseData), - /// Data about a method call. - MethodCallData(MethodCallData), - /// Data for method declarations (methods with a body are treated as functions). - MethodData(MethodData), - /// Data for modules. - ModData(ModData), - /// Data for a reference to a module. - ModRefData(ModRefData), - /// Data for a struct declaration. - StructData(StructData), - /// Data for a struct variant. - StructVariantDat(StructVariantData), - /// Data for a trait declaration. - TraitData(TraitData), - /// Data for a tuple variant. - TupleVariantData(TupleVariantData), - /// Data for a typedef. - TypeDefData(TypeDefData), - /// Data for a reference to a type or trait. - TypeRefData(TypeRefData), - /// Data for a use statement. - UseData(UseData), - /// Data for a global use statement. - UseGlobData(UseGlobData), - /// Data for local and global variables (consts and statics), and fields. - VariableData(VariableData), - /// Data for the use of some variable (e.g., the use of a local variable, which - /// will refere to that variables declaration). - VariableRefData(VariableRefData), -} - -#[derive(Eq, PartialEq, Clone, Copy, Debug)] -pub enum Visibility { - Public, - Restricted, - Inherited, -} - -impl<'a> From<&'a ast::Visibility> for Visibility { - fn from(v: &'a ast::Visibility) -> Visibility { - match *v { - ast::Visibility::Public => Visibility::Public, - ast::Visibility::Crate(_) => Visibility::Restricted, - ast::Visibility::Restricted { .. } => Visibility::Restricted, - ast::Visibility::Inherited => Visibility::Inherited, - } - } -} - -impl<'a> From<&'a hir::Visibility> for Visibility { - fn from(v: &'a hir::Visibility) -> Visibility { - match *v { - hir::Visibility::Public => Visibility::Public, - hir::Visibility::Crate => Visibility::Restricted, - hir::Visibility::Restricted { .. } => Visibility::Restricted, - hir::Visibility::Inherited => Visibility::Inherited, - } - } -} - -/// Data for the prelude of a crate. -#[derive(Debug)] -pub struct CratePreludeData { - pub crate_name: String, - pub crate_root: String, - pub external_crates: Vec, - pub span: Span, -} - -/// Data for enum declarations. -#[derive(Clone, Debug)] -pub struct EnumData { - pub id: NodeId, - pub name: String, - pub value: String, - pub qualname: String, - pub span: Span, - pub scope: NodeId, - pub variants: Vec, - pub visibility: Visibility, - pub docs: String, - pub sig: Option, - pub attributes: Vec, -} - -/// Data for extern crates. -#[derive(Debug)] -pub struct ExternCrateData { - pub id: NodeId, - pub name: String, - pub crate_num: CrateNum, - pub location: String, - pub span: Span, - pub scope: NodeId, -} - -/// Data about a function call. -#[derive(Debug)] -pub struct FunctionCallData { - pub span: Span, - pub scope: NodeId, - pub ref_id: DefId, -} - -/// Data for all kinds of functions and methods. -#[derive(Clone, Debug)] -pub struct FunctionData { - pub id: NodeId, - pub name: String, - pub qualname: String, - pub declaration: Option, - pub span: Span, - pub scope: NodeId, - pub value: String, - pub visibility: Visibility, - pub parent: Option, - pub docs: String, - pub sig: Option, - pub attributes: Vec, -} - -/// Data about a function call. -#[derive(Debug)] -pub struct FunctionRefData { - pub span: Span, - pub scope: NodeId, - pub ref_id: DefId, -} - -#[derive(Debug)] -pub struct ImplData { - pub id: NodeId, - pub span: Span, - pub scope: NodeId, - pub trait_ref: Option, - pub self_ref: Option, -} - -#[derive(Debug)] -// 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 { - pub id: NodeId, - pub span: Span, - pub scope: NodeId, - // FIXME: I'm not really sure inline data is the best way to do this. Seems - // OK in this case, but generalising leads to returning chunks of AST, which - // feels wrong. - pub trait_ref: Option, - pub self_ref: Option, -} - -#[derive(Debug)] -pub struct InheritanceData { - pub span: Span, - pub base_id: DefId, - pub deriv_id: NodeId -} - -/// Data about a macro declaration. -#[derive(Debug)] -pub struct MacroData { - pub span: Span, - pub name: String, - pub qualname: String, - pub docs: String, -} - -/// Data about a macro use. -#[derive(Debug)] -pub struct MacroUseData { - pub span: Span, - 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: Span, - pub scope: NodeId, - pub imported: bool, -} - -/// Data about a method call. -#[derive(Debug)] -pub struct MethodCallData { - pub span: Span, - pub scope: NodeId, - pub ref_id: Option, - pub decl_id: Option, -} - -/// Data for method declarations (methods with a body are treated as functions). -#[derive(Clone, Debug)] -pub struct MethodData { - pub id: NodeId, - pub name: String, - pub qualname: String, - pub span: Span, - pub scope: NodeId, - pub value: String, - pub decl_id: Option, - pub parent: Option, - pub visibility: Visibility, - pub docs: String, - pub sig: Option, - pub attributes: Vec, -} - -/// Data for modules. -#[derive(Debug)] -pub struct ModData { - pub id: NodeId, - pub name: String, - pub qualname: String, - pub span: Span, - pub scope: NodeId, - pub filename: String, - pub items: Vec, - pub visibility: Visibility, - pub docs: String, - pub sig: Option, - pub attributes: Vec, -} - -/// Data for a reference to a module. -#[derive(Debug)] -pub struct ModRefData { - pub span: Span, - pub scope: NodeId, - pub ref_id: Option, - pub qualname: String -} - -#[derive(Debug)] -pub struct StructData { - pub span: Span, - pub name: String, - pub id: NodeId, - pub ctor_id: NodeId, - pub qualname: String, - pub scope: NodeId, - pub value: String, - pub fields: Vec, - pub visibility: Visibility, - pub docs: String, - pub sig: Option, - pub attributes: Vec, -} - -#[derive(Debug)] -pub struct StructVariantData { - pub span: Span, - pub name: String, - pub id: NodeId, - pub qualname: String, - pub type_value: String, - pub value: String, - pub scope: NodeId, - pub parent: Option, - pub docs: String, - pub sig: Option, - pub attributes: Vec, -} - -#[derive(Debug)] -pub struct TraitData { - pub span: Span, - pub id: NodeId, - pub name: String, - pub qualname: String, - pub scope: NodeId, - pub value: String, - pub items: Vec, - pub visibility: Visibility, - pub docs: String, - pub sig: Option, - pub attributes: Vec, -} - -#[derive(Debug)] -pub struct TupleVariantData { - pub span: Span, - pub id: NodeId, - pub name: String, - pub qualname: String, - pub type_value: String, - pub value: String, - pub scope: NodeId, - pub parent: Option, - pub docs: String, - pub sig: Option, - pub attributes: Vec, -} - -/// Data for a typedef. -#[derive(Debug)] -pub struct TypeDefData { - pub id: NodeId, - pub name: String, - pub span: Span, - pub qualname: String, - pub value: String, - pub visibility: Visibility, - pub parent: Option, - pub docs: String, - pub sig: Option, - pub attributes: Vec, -} - -/// Data for a reference to a type or trait. -#[derive(Clone, Debug)] -pub struct TypeRefData { - pub span: Span, - pub scope: NodeId, - pub ref_id: Option, - pub qualname: String, -} - -#[derive(Debug)] -pub struct UseData { - pub id: NodeId, - pub span: Span, - pub name: String, - pub mod_id: Option, - pub scope: NodeId, - pub visibility: Visibility, -} - -#[derive(Debug)] -pub struct UseGlobData { - pub id: NodeId, - pub span: Span, - pub names: Vec, - pub scope: NodeId, - pub visibility: Visibility, -} - -/// Data for local and global variables (consts and statics). -#[derive(Debug)] -pub struct VariableData { - pub id: NodeId, - pub kind: VariableKind, - pub name: String, - pub qualname: String, - pub span: Span, - pub scope: NodeId, - pub parent: Option, - pub value: String, - pub type_value: String, - pub visibility: Visibility, - pub docs: String, - pub sig: Option, - pub attributes: Vec, -} - -#[derive(Debug)] -pub enum VariableKind { - Static, - Const, - Local, - Field, -} - -/// 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)] -pub struct VariableRefData { - pub name: String, - pub span: Span, - pub scope: NodeId, - pub ref_id: DefId, -} diff --git a/src/librustc_save_analysis/dump.rs b/src/librustc_save_analysis/dump.rs deleted file mode 100644 index 795ff58e206..00000000000 --- a/src/librustc_save_analysis/dump.rs +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2012-2014 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use super::external_data::*; - -use rls_data::CratePreludeData; - -pub trait Dump { - 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) {} -} diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index ea346d99e31..cc33d3db8eb 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -8,10 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! Write the output of rustc's analysis to an implementor of Dump. The data is -//! primarily designed to be used as input to the DXR tool, specifically its -//! Rust plugin. It could also be used by IDEs or other code browsing, search, or -//! cross-referencing tools. +//! Write the output of rustc's analysis to an implementor of Dump. //! //! Dumping the analysis is implemented by walking the AST and getting a bunch of //! info out from all over the place. We use Def IDs to identify objects. The @@ -27,16 +24,12 @@ //! is used for recording the output in a format-agnostic way (see CsvDumper //! for an example). -use rustc::hir; -use rustc::hir::def::Def; -use rustc::hir::def_id::{DefId, LOCAL_CRATE}; -use rustc::hir::map::{Node, NodeItem}; +use rustc::hir::def::Def as HirDef; +use rustc::hir::def_id::DefId; +use rustc::hir::map::Node; use rustc::session::Session; -use rustc::ty::{self, TyCtxt, AssociatedItemContainer}; +use rustc::ty::{self, TyCtxt}; -use std::collections::HashSet; -use std::collections::hash_map::DefaultHasher; -use std::hash::*; use std::path::Path; use syntax::ast::{self, NodeId, PatKind, Attribute, CRATE_NODE_ID}; @@ -48,15 +41,12 @@ use syntax::codemap::Spanned; use syntax_pos::*; -use {escape, generated_code, SaveContext, PathCollector, docs_for_attrs}; -use data::*; -use dump::Dump; -use external_data::{Lower, make_def_id}; -use recorder; +use {escape, generated_code, SaveContext, PathCollector, docs_for_attrs, lower_attributes, Dump}; use span_utils::SpanUtils; use sig; -use rls_data::ExternalCrateData; +use rls_data::{CratePreludeData, Import, ImportKind, SpanData, Ref, RefKind, + Def, DefKind, Relation, RelationKind}; macro_rules! down_cast_data { ($id:ident, $kind:ident, $sp:expr) => { @@ -82,8 +72,7 @@ pub struct DumpVisitor<'l, 'tcx: 'l, 'll, D: 'll> { // of macro use (callsite) spans. We store these to ensure // we only write one macro def per unique macro definition, and // one macro use per unique callsite span. - mac_defs: HashSet, - mac_uses: HashSet, + // mac_defs: HashSet, } impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { @@ -98,8 +87,7 @@ pub fn new(save_ctxt: SaveContext<'l, 'tcx>, dumper: dumper, span: span_utils.clone(), cur_scope: CRATE_NODE_ID, - mac_defs: HashSet::new(), - mac_uses: HashSet::new(), + // mac_defs: HashSet::new(), } } @@ -127,6 +115,10 @@ fn nest_tables(&mut self, item_id: NodeId, f: F) } } + fn span_from_span(&self, span: Span) -> SpanData { + self.save_ctxt.span_from_span(span) + } + pub fn dump_crate_info(&mut self, name: &str, krate: &ast::Crate) { let source_file = self.tcx.sess.local_crate_source_file.as_ref(); let crate_root = source_file.map(|source_file| { @@ -137,25 +129,14 @@ 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, - 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.unwrap_or("".to_owned()), - external_crates: external_crates, - span: krate.span, + external_crates: self.save_ctxt.get_external_crates(), + span: self.span_from_span(krate.span), }; - self.dumper.crate_prelude(data.lower(self.tcx)); + self.dumper.crate_prelude(data); } // Return all non-empty prefixes of a path. @@ -211,13 +192,13 @@ fn process_path_prefixes(&self, path: &ast::Path) -> Vec<(Span, String)> { fn write_sub_paths(&mut self, path: &ast::Path) { let sub_paths = self.process_path_prefixes(path); - for (span, qualname) in sub_paths { - self.dumper.mod_ref(ModRefData { - span: span, - qualname: qualname, - scope: self.cur_scope, - ref_id: None - }.lower(self.tcx)); + for (span, _) in sub_paths { + let span = self.span_from_span(span); + self.dumper.dump_ref(Ref { + kind: RefKind::Mod, + span, + ref_id: ::null_id(), + }); } } @@ -230,13 +211,13 @@ fn write_sub_paths_truncated(&mut self, path: &ast::Path) { return; } - for (span, qualname) in sub_paths.into_iter().take(len - 1) { - self.dumper.mod_ref(ModRefData { - span: span, - qualname: qualname, - scope: self.cur_scope, - ref_id: None - }.lower(self.tcx)); + for (span, _) in sub_paths.into_iter().take(len - 1) { + let span = self.span_from_span(span); + self.dumper.dump_ref(Ref { + kind: RefKind::Mod, + span, + ref_id: ::null_id(), + }); } } @@ -251,32 +232,32 @@ fn write_sub_path_trait_truncated(&mut self, path: &ast::Path) { let sub_paths = &sub_paths[.. (len-1)]; // write the trait part of the sub-path - let (ref span, ref qualname) = sub_paths[len-2]; - self.dumper.type_ref(TypeRefData { - ref_id: None, - span: *span, - qualname: qualname.to_owned(), - scope: CRATE_NODE_ID - }.lower(self.tcx)); + let (ref span, _) = sub_paths[len-2]; + let span = self.span_from_span(*span); + self.dumper.dump_ref(Ref { + kind: RefKind::Type, + ref_id: ::null_id(), + span, + }); // write the other sub-paths if len <= 2 { return; } let sub_paths = &sub_paths[..len-2]; - for &(ref span, ref qualname) in sub_paths { - self.dumper.mod_ref(ModRefData { - span: *span, - qualname: qualname.to_owned(), - scope: self.cur_scope, - ref_id: None - }.lower(self.tcx)); + for &(ref span, _) in sub_paths { + let span = self.span_from_span(*span); + self.dumper.dump_ref(Ref { + kind: RefKind::Mod, + span, + ref_id: ::null_id(), + }); } } fn lookup_def_id(&self, ref_id: NodeId) -> Option { match self.save_ctxt.get_path_def(ref_id) { - Def::PrimTy(..) | Def::SelfTy(..) | Def::Err => None, + HirDef::PrimTy(..) | HirDef::SelfTy(..) | HirDef::Err => None, def => Some(def.def_id()), } } @@ -285,67 +266,67 @@ fn process_def_kind(&mut self, ref_id: NodeId, span: Span, sub_span: Option, - def_id: DefId, - scope: NodeId) { + def_id: DefId) { if self.span.filter_generated(sub_span, span) { return; } let def = self.save_ctxt.get_path_def(ref_id); match def { - Def::Mod(_) => { - self.dumper.mod_ref(ModRefData { - span: sub_span.expect("No span found for mod ref"), - ref_id: Some(def_id), - scope: scope, - qualname: String::new() - }.lower(self.tcx)); + HirDef::Mod(_) => { + let span = self.span_from_span(sub_span.expect("No span found for mod ref")); + self.dumper.dump_ref(Ref { + kind: RefKind::Mod, + span, + ref_id: ::id_from_def_id(def_id), + }); } - Def::Struct(..) | - Def::Variant(..) | - Def::Union(..) | - Def::Enum(..) | - Def::TyAlias(..) | - Def::Trait(_) => { - self.dumper.type_ref(TypeRefData { - span: sub_span.expect("No span found for type ref"), - ref_id: Some(def_id), - scope: scope, - qualname: String::new() - }.lower(self.tcx)); + HirDef::Struct(..) | + HirDef::Variant(..) | + HirDef::Union(..) | + HirDef::Enum(..) | + HirDef::TyAlias(..) | + HirDef::Trait(_) => { + let span = self.span_from_span(sub_span.expect("No span found for type ref")); + self.dumper.dump_ref(Ref { + kind: RefKind::Type, + span, + ref_id: ::id_from_def_id(def_id), + }); } - Def::Static(..) | - Def::Const(..) | - Def::StructCtor(..) | - Def::VariantCtor(..) => { - self.dumper.variable_ref(VariableRefData { - span: sub_span.expect("No span found for var ref"), - ref_id: def_id, - scope: scope, - name: String::new() - }.lower(self.tcx)); + HirDef::Static(..) | + HirDef::Const(..) | + HirDef::StructCtor(..) | + HirDef::VariantCtor(..) => { + let span = self.span_from_span(sub_span.expect("No span found for var ref")); + self.dumper.dump_ref(Ref { + kind: RefKind::Variable, + span, + ref_id: ::id_from_def_id(def_id), + }); } - Def::Fn(..) => { - self.dumper.function_ref(FunctionRefData { - span: sub_span.expect("No span found for fn ref"), - ref_id: def_id, - scope: scope - }.lower(self.tcx)); + HirDef::Fn(..) => { + let span = self.span_from_span(sub_span.expect("No span found for fn ref")); + self.dumper.dump_ref(Ref { + kind: RefKind::Function, + span, + ref_id: ::id_from_def_id(def_id), + }); } // With macros 2.0, we can legitimately get a ref to a macro, but // we don't handle it properly for now (FIXME). - Def::Macro(..) => {} - Def::Local(..) | - Def::Upvar(..) | - Def::SelfTy(..) | - Def::Label(_) | - Def::TyParam(..) | - Def::Method(..) | - Def::AssociatedTy(..) | - Def::AssociatedConst(..) | - Def::PrimTy(_) | - Def::GlobalAsm(_) | - Def::Err => { + HirDef::Macro(..) => {} + HirDef::Local(..) | + HirDef::Upvar(..) | + HirDef::SelfTy(..) | + HirDef::Label(_) | + HirDef::TyParam(..) | + HirDef::Method(..) | + HirDef::AssociatedTy(..) | + HirDef::AssociatedConst(..) | + HirDef::PrimTy(_) | + HirDef::GlobalAsm(_) | + HirDef::Err => { span_bug!(span, "process_def_kind for unexpected item: {:?}", def); @@ -368,21 +349,23 @@ fn process_formals(&mut self, formals: &'l [ast::Arg], qualname: &str) { // variable name, but who knows?) let sub_span = span_utils.span_for_last_ident(p.span); if !self.span.filter_generated(sub_span, p.span) { - self.dumper.variable(VariableData { - id: id, - kind: VariableKind::Local, - span: sub_span.expect("No span found for variable"), + let id = ::id_from_node_id(id, &self.save_ctxt); + let span = self.span_from_span(sub_span.expect("No span found for variable")); + + self.dumper.dump_def(false, Def { + kind: DefKind::Local, + id, + span, name: path_to_string(p), qualname: format!("{}::{}", qualname, path_to_string(p)), - type_value: typ, - value: String::new(), - scope: CRATE_NODE_ID, + value: typ, parent: None, - visibility: Visibility::Inherited, + children: vec![], + decl_id: None, docs: String::new(), sig: None, - attributes: vec![], - }.lower(self.tcx)); + attributes:vec![], + }); } } } @@ -393,12 +376,11 @@ fn process_method(&mut self, body: Option<&'l ast::Block>, id: ast::NodeId, name: ast::Ident, - vis: Visibility, - attrs: &'l [Attribute], + vis: ast::Visibility, span: Span) { debug!("process_method: {}:{}", id, name); - if let Some(method_data) = self.save_ctxt.get_method_data(id, name.name, span) { + if let Some(mut method_data) = self.save_ctxt.get_method_data(id, name.name, span) { let sig_str = ::make_signature(&sig.decl, &sig.generics); if body.is_some() { @@ -407,61 +389,11 @@ fn process_method(&mut self, }); } - // If the method is defined in an impl, then try and find the corresponding - // method decl in a trait, and if there is one, make a decl_id for it. This - // requires looking up the impl, then the trait, then searching for a method - // with the right name. - if !self.span.filter_generated(Some(method_data.span), span) { - let container = - self.tcx.associated_item(self.tcx.hir.local_def_id(id)).container; - let mut trait_id; - let mut decl_id = None; - match container { - AssociatedItemContainer::ImplContainer(id) => { - trait_id = self.tcx.trait_id_of_impl(id); - - match trait_id { - Some(id) => { - for item in self.tcx.associated_items(id) { - if item.kind == ty::AssociatedKind::Method { - if item.name == name.name { - decl_id = Some(item.def_id); - break; - } - } - } - } - None => { - if let Some(NodeItem(item)) = self.tcx.hir.get_if_local(id) { - if let hir::ItemImpl(_, _, _, _, _, ref ty, _) = item.node { - trait_id = self.lookup_def_id(ty.id); - } - } - } - } - } - AssociatedItemContainer::TraitContainer(id) => { - trait_id = Some(id); - } - } - - self.dumper.method(MethodData { - id: method_data.id, - name: method_data.name, - span: method_data.span, - scope: method_data.scope, - qualname: method_data.qualname.clone(), - value: sig_str, - decl_id: decl_id, - parent: trait_id, - visibility: vis, - docs: docs_for_attrs(attrs), - sig: sig::method_signature(id, name, sig, &self.save_ctxt), - attributes: attrs.to_vec(), - }.lower(self.tcx)); - } - self.process_generic_params(&sig.generics, span, &method_data.qualname, id); + + method_data.value = sig_str; + method_data.sig = sig::method_signature(id, name, sig, &self.save_ctxt); + self.dumper.dump_def(vis == ast::Visibility::Public, method_data); } // walk arg and return types @@ -480,22 +412,17 @@ fn process_method(&mut self, } fn process_trait_ref(&mut self, trait_ref: &'l ast::TraitRef) { - let trait_ref_data = self.save_ctxt.get_trait_ref_data(trait_ref, self.cur_scope); + let trait_ref_data = self.save_ctxt.get_trait_ref_data(trait_ref); if let Some(trait_ref_data) = trait_ref_data { - if !self.span.filter_generated(Some(trait_ref_data.span), trait_ref.path.span) { - self.dumper.type_ref(trait_ref_data.lower(self.tcx)); - } + self.dumper.dump_ref(trait_ref_data); } - self.process_path(trait_ref.ref_id, &trait_ref.path, Some(recorder::TypeRef)); + self.process_path(trait_ref.ref_id, &trait_ref.path); } fn process_struct_field_def(&mut self, field: &ast::StructField, parent_id: NodeId) { let field_data = self.save_ctxt.get_field_data(field, parent_id); - if let Some(mut field_data) = field_data { - if !self.span.filter_generated(Some(field_data.span), field.span) { - field_data.value = String::new(); - self.dumper.variable(field_data.lower(self.tcx)); - } + if let Some(field_data) = field_data { + self.dumper.dump_def(field.vis == ast::Visibility::Public, field_data); } } @@ -519,18 +446,23 @@ fn process_generic_params(&mut self, name, id); if !self.span.filter_generated(Some(param_ss), full_span) { - self.dumper.typedef(TypeDefData { - span: param_ss, - name: name, - id: param.id, - qualname: qualname, + let id = ::id_from_node_id(param.id, &self.save_ctxt); + let span = self.span_from_span(param_ss); + + self.dumper.dump_def(false, Def { + kind: DefKind::Type, + id, + span, + name, + qualname, value: String::new(), - visibility: Visibility::Inherited, parent: None, + children: vec![], + decl_id: None, docs: String::new(), sig: None, attributes: vec![], - }.lower(self.tcx)); + }); } } self.visit_generics(generics); @@ -542,13 +474,10 @@ fn process_fn(&mut self, ty_params: &'l ast::Generics, body: &'l ast::Block) { if let Some(fn_data) = self.save_ctxt.get_item_data(item) { - down_cast_data!(fn_data, FunctionData, item.span); - if !self.span.filter_generated(Some(fn_data.span), item.span) { - self.dumper.function(fn_data.clone().lower(self.tcx)); - } - + down_cast_data!(fn_data, DefData, item.span); self.nest_tables(item.id, |v| v.process_formals(&decl.inputs, &fn_data.qualname)); self.process_generic_params(ty_params, item.span, &fn_data.qualname, item.id); + self.dumper.dump_def(item.vis == ast::Visibility::Public, fn_data); } for arg in &decl.inputs { @@ -567,10 +496,8 @@ fn process_static_or_const_item(&mut self, typ: &'l ast::Ty, expr: &'l ast::Expr) { if let Some(var_data) = self.save_ctxt.get_item_data(item) { - down_cast_data!(var_data, VariableData, item.span); - if !self.span.filter_generated(Some(var_data.span), item.span) { - self.dumper.variable(var_data.lower(self.tcx)); - } + down_cast_data!(var_data, DefData, item.span); + self.dumper.dump_def(item.vis == ast::Visibility::Public, var_data); } self.visit_ty(&typ); self.visit_expr(expr); @@ -583,29 +510,31 @@ fn process_assoc_const(&mut self, typ: &'l ast::Ty, expr: Option<&'l ast::Expr>, parent_id: DefId, - vis: Visibility, + vis: ast::Visibility, attrs: &'l [Attribute]) { let qualname = format!("::{}", self.tcx.node_path_str(id)); let sub_span = self.span.sub_span_after_keyword(span, keywords::Const); - let value = expr.map(|e| self.span.snippet(e.span)).unwrap_or(String::new()); if !self.span.filter_generated(sub_span, span) { - self.dumper.variable(VariableData { - span: sub_span.expect("No span found for variable"), - kind: VariableKind::Const, - id: id, + let sig = sig::assoc_const_signature(id, name, typ, expr, &self.save_ctxt); + let id = ::id_from_node_id(id, &self.save_ctxt); + let span = self.span_from_span(sub_span.expect("No span found for variable")); + + self.dumper.dump_def(vis == ast::Visibility::Public, Def { + kind: DefKind::Const, + id, + span, name: name.to_string(), - qualname: qualname, - value: value, - type_value: ty_to_string(&typ), - scope: self.cur_scope, - parent: Some(parent_id), - visibility: vis, + qualname, + value: ty_to_string(&typ), + parent: Some(::id_from_def_id(parent_id)), + children: vec![], + decl_id: None, docs: docs_for_attrs(attrs), - sig: sig::assoc_const_signature(id, name, typ, expr, &self.save_ctxt), - attributes: attrs.to_vec(), - }.lower(self.tcx)); + sig, + attributes: lower_attributes(attrs.to_owned(), &self.save_ctxt), + }); } // walk type and init value @@ -624,7 +553,7 @@ fn process_struct(&mut self, let qualname = format!("::{}", self.tcx.node_path_str(item.id)); let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Struct); - let (val, fields) = + let (value, fields) = if let ast::ItemKind::Struct(ast::VariantData::Struct(ref fields, _), _) = item.node { let fields_str = fields.iter() @@ -633,26 +562,28 @@ fn process_struct(&mut self, .unwrap_or(i.to_string())) .collect::>() .join(", "); - (format!("{} {{ {} }}", name, fields_str), fields.iter().map(|f| f.id).collect()) + (format!("{} {{ {} }}", name, fields_str), + fields.iter().map(|f| ::id_from_node_id(f.id, &self.save_ctxt)).collect()) } else { (String::new(), vec![]) }; if !self.span.filter_generated(sub_span, item.span) { - self.dumper.struct_data(StructData { - span: sub_span.expect("No span found for struct"), - id: item.id, - name: name, - ctor_id: def.id(), + let span = self.span_from_span(sub_span.expect("No span found for struct")); + self.dumper.dump_def(item.vis == ast::Visibility::Public, Def { + kind: DefKind::Struct, + id: ::id_from_node_id(item.id, &self.save_ctxt), + span, + name, qualname: qualname.clone(), - scope: self.cur_scope, - value: val, - fields: fields, - visibility: From::from(&item.vis), + value, + parent: None, + children: fields, + decl_id: None, docs: docs_for_attrs(&item.attrs), sig: sig::item_signature(item, &self.save_ctxt), - attributes: item.attrs.clone(), - }.lower(self.tcx)); + attributes: lower_attributes(item.attrs.clone(), &self.save_ctxt), + }); } for field in def.fields() { @@ -672,10 +603,7 @@ fn process_enum(&mut self, None => return, Some(data) => data, }; - down_cast_data!(enum_data, EnumData, item.span); - if !self.span.filter_generated(Some(enum_data.span), item.span) { - self.dumper.enum_data(enum_data.clone().lower(self.tcx)); - } + down_cast_data!(enum_data, DefData, item.span); for variant in &enum_definition.variants { let name = variant.node.name.name.to_string(); @@ -692,48 +620,62 @@ fn process_enum(&mut self, .unwrap_or(i.to_string())) .collect::>() .join(", "); - let val = format!("{}::{} {{ {} }}", enum_data.name, name, fields_str); + let value = format!("{}::{} {{ {} }}", enum_data.name, name, fields_str); if !self.span.filter_generated(sub_span, variant.span) { - self.dumper.struct_variant(StructVariantData { - span: sub_span.expect("No span found for struct variant"), - id: variant.node.data.id(), - name: name, - qualname: qualname, - type_value: enum_data.qualname.clone(), - value: val, - scope: enum_data.scope, - parent: Some(make_def_id(item.id, &self.tcx.hir)), + let span = self.span_from_span( + sub_span.expect("No span found for struct variant")); + let id = ::id_from_node_id(variant.node.data.id(), &self.save_ctxt); + let parent = Some(::id_from_node_id(item.id, &self.save_ctxt)); + + self.dumper.dump_def(item.vis == ast::Visibility::Public, Def { + kind: DefKind::Struct, + id, + span, + name, + qualname, + value, + parent, + children: vec![], + decl_id: None, docs: docs_for_attrs(&variant.node.attrs), sig: sig::variant_signature(variant, &self.save_ctxt), - attributes: variant.node.attrs.clone(), - }.lower(self.tcx)); + attributes: lower_attributes(variant.node.attrs.clone(), + &self.save_ctxt), + }); } } ref v => { let sub_span = self.span.span_for_first_ident(variant.span); - let mut val = format!("{}::{}", enum_data.name, name); + let mut value = format!("{}::{}", enum_data.name, name); if let &ast::VariantData::Tuple(ref fields, _) = v { - val.push('('); - val.push_str(&fields.iter() - .map(|f| ty_to_string(&f.ty)) - .collect::>() - .join(", ")); - val.push(')'); + value.push('('); + value.push_str(&fields.iter() + .map(|f| ty_to_string(&f.ty)) + .collect::>() + .join(", ")); + value.push(')'); } if !self.span.filter_generated(sub_span, variant.span) { - self.dumper.tuple_variant(TupleVariantData { - span: sub_span.expect("No span found for tuple variant"), - id: variant.node.data.id(), - name: name, - qualname: qualname, - type_value: enum_data.qualname.clone(), - value: val, - scope: enum_data.scope, - parent: Some(make_def_id(item.id, &self.tcx.hir)), + let span = + self.span_from_span(sub_span.expect("No span found for tuple variant")); + let id = ::id_from_node_id(variant.node.data.id(), &self.save_ctxt); + let parent = Some(::id_from_node_id(item.id, &self.save_ctxt)); + + self.dumper.dump_def(item.vis == ast::Visibility::Public, Def { + kind: DefKind::Tuple, + id, + span, + name, + qualname, + value, + parent, + children: vec![], + decl_id: None, docs: docs_for_attrs(&variant.node.attrs), sig: sig::variant_signature(variant, &self.save_ctxt), - attributes: variant.node.attrs.clone(), - }.lower(self.tcx)); + attributes: lower_attributes(variant.node.attrs.clone(), + &self.save_ctxt), + }); } } } @@ -744,7 +686,8 @@ fn process_enum(&mut self, self.visit_ty(&field.ty); } } - self.process_generic_params(ty_params, item.span, &enum_data.qualname, enum_data.id); + self.process_generic_params(ty_params, item.span, &enum_data.qualname, item.id); + self.dumper.dump_def(item.vis == ast::Visibility::Public, enum_data); } fn process_impl(&mut self, @@ -754,25 +697,17 @@ fn process_impl(&mut self, typ: &'l ast::Ty, impl_items: &'l [ast::ImplItem]) { if let Some(impl_data) = self.save_ctxt.get_item_data(item) { - down_cast_data!(impl_data, ImplData, item.span); - if !self.span.filter_generated(Some(impl_data.span), item.span) { - self.dumper.impl_data(ImplData { - id: impl_data.id, - span: impl_data.span, - scope: impl_data.scope, - trait_ref: impl_data.trait_ref.map(|d| d.ref_id.unwrap()), - self_ref: impl_data.self_ref.map(|d| d.ref_id.unwrap()) - }.lower(self.tcx)); - } + down_cast_data!(impl_data, RelationData, item.span); + self.dumper.dump_relation(impl_data); } self.visit_ty(&typ); if let &Some(ref trait_ref) = trait_ref { - self.process_path(trait_ref.ref_id, &trait_ref.path, Some(recorder::TypeRef)); + self.process_path(trait_ref.ref_id, &trait_ref.path); } self.process_generic_params(type_parameters, item.span, "", item.id); for impl_item in impl_items { let map = &self.tcx.hir; - self.process_impl_item(impl_item, make_def_id(item.id, map)); + self.process_impl_item(impl_item, map.local_def_id(item.id)); } } @@ -793,19 +728,24 @@ fn process_trait(&mut self, } let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Trait); if !self.span.filter_generated(sub_span, item.span) { - self.dumper.trait_data(TraitData { - span: sub_span.expect("No span found for trait"), - id: item.id, - name: name, + let id = ::id_from_node_id(item.id, &self.save_ctxt); + let span = self.span_from_span(sub_span.expect("No span found for trait")); + let children = + methods.iter().map(|i| ::id_from_node_id(i.id, &self.save_ctxt)).collect(); + self.dumper.dump_def(item.vis == ast::Visibility::Public, Def { + kind: DefKind::Trait, + id, + span, + name, qualname: qualname.clone(), - scope: self.cur_scope, value: val, - items: methods.iter().map(|i| i.id).collect(), - visibility: From::from(&item.vis), + parent: None, + children, + decl_id: None, docs: docs_for_attrs(&item.attrs), sig: sig::item_signature(item, &self.save_ctxt), - attributes: item.attrs.clone(), - }.lower(self.tcx)); + attributes: lower_attributes(item.attrs.clone(), &self.save_ctxt), + }); } // super-traits @@ -823,21 +763,22 @@ fn process_trait(&mut self, if let Some(id) = self.lookup_def_id(trait_ref.ref_id) { let sub_span = self.span.sub_span_for_type_name(trait_ref.path.span); if !self.span.filter_generated(sub_span, trait_ref.path.span) { - self.dumper.type_ref(TypeRefData { - span: sub_span.expect("No span found for trait ref"), - ref_id: Some(id), - scope: self.cur_scope, - qualname: String::new() - }.lower(self.tcx)); + let span = self.span_from_span(sub_span.expect("No span found for trait ref")); + self.dumper.dump_ref(Ref { + kind: RefKind::Type, + span, + ref_id: ::id_from_def_id(id), + }); } if !self.span.filter_generated(sub_span, trait_ref.path.span) { - let sub_span = sub_span.expect("No span for inheritance"); - self.dumper.inheritance(InheritanceData { + let sub_span = self.span_from_span(sub_span.expect("No span for inheritance")); + self.dumper.dump_relation(Relation { + kind: RelationKind::SuperTrait, span: sub_span, - base_id: id, - deriv_id: item.id - }.lower(self.tcx)); + from: ::id_from_def_id(id), + to: ::id_from_node_id(item.id, &self.save_ctxt), + }); } } } @@ -846,21 +787,19 @@ fn process_trait(&mut self, self.process_generic_params(generics, item.span, &qualname, item.id); for method in methods { let map = &self.tcx.hir; - self.process_trait_item(method, make_def_id(item.id, map)) + self.process_trait_item(method, map.local_def_id(item.id)) } } // `item` is the module in question, represented as an item. fn process_mod(&mut self, item: &ast::Item) { if let Some(mod_data) = self.save_ctxt.get_item_data(item) { - down_cast_data!(mod_data, ModData, item.span); - if !self.span.filter_generated(Some(mod_data.span), item.span) { - self.dumper.mod_data(mod_data.lower(self.tcx)); - } + down_cast_data!(mod_data, DefData, item.span); + self.dumper.dump_def(item.vis == ast::Visibility::Public, mod_data); } } - fn process_path(&mut self, id: NodeId, path: &ast::Path, ref_kind: Option) { + fn process_path(&mut self, id: NodeId, path: &ast::Path) { let path_data = self.save_ctxt.get_path_data(id, path); if generated_code(path.span) && path_data.is_none() { return; @@ -873,81 +812,29 @@ fn process_path(&mut self, id: NodeId, path: &ast::Path, ref_kind: Option { - // FIXME: this whole block duplicates the code in process_def_kind - if !self.span.filter_generated(Some(vrd.span), path.span) { - match ref_kind { - Some(recorder::TypeRef) => { - self.dumper.type_ref(TypeRefData { - span: vrd.span, - ref_id: Some(vrd.ref_id), - scope: vrd.scope, - qualname: String::new() - }.lower(self.tcx)); - } - Some(recorder::FnRef) => { - self.dumper.function_ref(FunctionRefData { - span: vrd.span, - ref_id: vrd.ref_id, - scope: vrd.scope - }.lower(self.tcx)); - } - Some(recorder::ModRef) => { - self.dumper.mod_ref( ModRefData { - span: vrd.span, - ref_id: Some(vrd.ref_id), - scope: vrd.scope, - qualname: String::new() - }.lower(self.tcx)); - } - Some(recorder::VarRef) | None - => self.dumper.variable_ref(vrd.lower(self.tcx)) - } - } - - } - Data::TypeRefData(trd) => { - if !self.span.filter_generated(Some(trd.span), path.span) { - self.dumper.type_ref(trd.lower(self.tcx)); - } - } - Data::MethodCallData(mcd) => { - if !self.span.filter_generated(Some(mcd.span), path.span) { - self.dumper.method_call(mcd.lower(self.tcx)); - } - } - Data::FunctionCallData(fcd) => { - if !self.span.filter_generated(Some(fcd.span), path.span) { - self.dumper.function_call(fcd.lower(self.tcx)); - } - } - _ => { - span_bug!(path.span, "Unexpected data: {:?}", path_data); - } - } + self.dumper.dump_ref(path_data); // Modules or types in the path prefix. match self.save_ctxt.get_path_def(id) { - Def::Method(did) => { + HirDef::Method(did) => { let ti = self.tcx.associated_item(did); if ti.kind == ty::AssociatedKind::Method && ti.method_has_self_argument { self.write_sub_path_trait_truncated(path); } } - Def::Fn(..) | - Def::Const(..) | - Def::Static(..) | - Def::StructCtor(..) | - Def::VariantCtor(..) | - Def::AssociatedConst(..) | - Def::Local(..) | - Def::Upvar(..) | - Def::Struct(..) | - Def::Union(..) | - Def::Variant(..) | - Def::TyAlias(..) | - Def::AssociatedTy(..) => self.write_sub_paths_truncated(path), + HirDef::Fn(..) | + HirDef::Const(..) | + HirDef::Static(..) | + HirDef::StructCtor(..) | + HirDef::VariantCtor(..) | + HirDef::AssociatedConst(..) | + HirDef::Local(..) | + HirDef::Upvar(..) | + HirDef::Struct(..) | + HirDef::Union(..) | + HirDef::Variant(..) | + HirDef::TyAlias(..) | + HirDef::AssociatedTy(..) => self.write_sub_paths_truncated(path), _ => {} } } @@ -961,20 +848,15 @@ fn process_struct_lit(&mut self, self.write_sub_paths_truncated(path); if let Some(struct_lit_data) = self.save_ctxt.get_expr_data(ex) { - down_cast_data!(struct_lit_data, TypeRefData, ex.span); - if !self.span.filter_generated(Some(struct_lit_data.span), ex.span) { - self.dumper.type_ref(struct_lit_data.lower(self.tcx)); + down_cast_data!(struct_lit_data, RefData, ex.span); + if !generated_code(ex.span) { + self.dumper.dump_ref(struct_lit_data); } - let scope = self.save_ctxt.enclosing_scope(ex.id); - for field in fields { if let Some(field_data) = self.save_ctxt - .get_field_ref_data(field, variant, scope) { - - if !self.span.filter_generated(Some(field_data.span), field.ident.span) { - self.dumper.variable_ref(field_data.lower(self.tcx)); - } + .get_field_ref_data(field, variant) { + self.dumper.dump_ref(field_data); } self.visit_expr(&field.expr) @@ -986,9 +868,9 @@ fn process_struct_lit(&mut self, fn process_method_call(&mut self, ex: &'l ast::Expr, args: &'l [P]) { if let Some(mcd) = self.save_ctxt.get_expr_data(ex) { - down_cast_data!(mcd, MethodCallData, ex.span); - if !self.span.filter_generated(Some(mcd.span), ex.span) { - self.dumper.method_call(mcd.lower(self.tcx)); + down_cast_data!(mcd, RefData, ex.span); + if !generated_code(ex.span) { + self.dumper.dump_ref(mcd); } } @@ -1013,12 +895,13 @@ fn process_pat(&mut self, p: &'l ast::Pat) { let sub_span = self.span.span_for_first_ident(span); if let Some(f) = variant.find_field_named(field.ident.name) { if !self.span.filter_generated(sub_span, span) { - self.dumper.variable_ref(VariableRefData { - span: sub_span.expect("No span fund for var ref"), - ref_id: f.did, - scope: self.cur_scope, - name: String::new() - }.lower(self.tcx)); + let span = + self.span_from_span(sub_span.expect("No span fund for var ref")); + self.dumper.dump_ref(Ref { + kind: RefKind::Variable, + span, + ref_id: ::id_from_def_id(f.did), + }); } } self.visit_pat(&field.pat); @@ -1036,7 +919,7 @@ fn process_var_decl(&mut self, p: &'l ast::Pat, value: String) { collector.visit_pat(&p); self.visit_pat(&p); - for &(id, ref p, immut, _) in &collector.collected_paths { + for &(id, ref p, immut) in &collector.collected_paths { let mut value = match immut { ast::Mutability::Immutable => value.to_string(), _ => String::new(), @@ -1058,21 +941,24 @@ fn process_var_decl(&mut self, p: &'l ast::Pat, value: String) { let sub_span = self.span.span_for_last_ident(p.span); // Rust uses the id of the pattern for var lookups, so we'll use it too. if !self.span.filter_generated(sub_span, p.span) { - self.dumper.variable(VariableData { - span: sub_span.expect("No span found for variable"), - kind: VariableKind::Local, - id: id, + let qualname = format!("{}${}", path_to_string(p), id); + let id = ::id_from_node_id(id, &self.save_ctxt); + let span = self.span_from_span(sub_span.expect("No span found for variable")); + + self.dumper.dump_def(false, Def { + kind: DefKind::Local, + id, + span, name: path_to_string(p), - qualname: format!("{}${}", path_to_string(p), id), - value: value, - type_value: typ, - scope: CRATE_NODE_ID, + qualname, + value: typ, parent: None, - visibility: Visibility::Inherited, + children: vec![], + decl_id: None, docs: String::new(), sig: None, - attributes: vec![], - }.lower(self.tcx)); + attributes:vec![], + }); } } } @@ -1084,46 +970,36 @@ fn process_var_decl(&mut self, p: &'l ast::Pat, value: String) { /// If the span is not macro-generated, do nothing, else use callee and /// callsite spans to record macro definition and use data, using the /// mac_uses and mac_defs sets to prevent multiples. - fn process_macro_use(&mut self, span: Span, id: NodeId) { - let data = match self.save_ctxt.get_macro_use_data(span, id) { + fn process_macro_use(&mut self, span: Span) { + let data = match self.save_ctxt.get_macro_use_data(span) { None => return, Some(data) => data, }; - let mut hasher = DefaultHasher::new(); - data.callee_span.hash(&mut hasher); - let hash = hasher.finish(); - let qualname = format!("{}::{}", data.name, hash); + + // FIXME write the macro def + // let mut hasher = DefaultHasher::new(); + // data.callee_span.hash(&mut hasher); + // let hash = hasher.finish(); + // let qualname = format!("{}::{}", data.name, hash); // Don't write macro definition for imported macros - if !self.mac_defs.contains(&data.callee_span) - && !data.imported { - self.mac_defs.insert(data.callee_span); - if let Some(sub_span) = self.span.span_for_macro_def_name(data.callee_span) { - self.dumper.macro_data(MacroData { - span: sub_span, - name: data.name.clone(), - qualname: qualname.clone(), - // FIXME where do macro docs come from? - docs: String::new(), - }.lower(self.tcx)); - } - } - if !self.mac_uses.contains(&data.span) { - self.mac_uses.insert(data.span); - if let Some(sub_span) = self.span.span_for_macro_use_name(data.span) { - self.dumper.macro_use(MacroUseData { - span: sub_span, - name: data.name, - qualname: qualname, - scope: data.scope, - callee_span: data.callee_span, - imported: data.imported, - }.lower(self.tcx)); - } - } + // if !self.mac_defs.contains(&data.callee_span) + // && !data.imported { + // self.mac_defs.insert(data.callee_span); + // if let Some(sub_span) = self.span.span_for_macro_def_name(data.callee_span) { + // self.dumper.macro_data(MacroData { + // span: sub_span, + // name: data.name.clone(), + // qualname: qualname.clone(), + // // FIXME where do macro docs come from? + // docs: String::new(), + // }.lower(self.tcx)); + // } + // } + self.dumper.macro_use(data); } fn process_trait_item(&mut self, trait_item: &'l ast::TraitItem, trait_id: DefId) { - self.process_macro_use(trait_item.span, trait_item.id); + self.process_macro_use(trait_item.span); match trait_item.node { ast::TraitItemKind::Const(ref ty, ref expr) => { self.process_assoc_const(trait_item.id, @@ -1132,7 +1008,7 @@ fn process_trait_item(&mut self, trait_item: &'l ast::TraitItem, trait_id: DefId &ty, expr.as_ref().map(|e| &**e), trait_id, - Visibility::Public, + ast::Visibility::Public, &trait_item.attrs); } ast::TraitItemKind::Method(ref sig, ref body) => { @@ -1140,8 +1016,7 @@ fn process_trait_item(&mut self, trait_item: &'l ast::TraitItem, trait_id: DefId body.as_ref().map(|x| &**x), trait_item.id, trait_item.ident, - Visibility::Public, - &trait_item.attrs, + ast::Visibility::Public, trait_item.span); } ast::TraitItemKind::Type(ref bounds, ref default_ty) => { @@ -1151,22 +1026,27 @@ fn process_trait_item(&mut self, trait_item: &'l ast::TraitItem, trait_id: DefId let sub_span = self.span.sub_span_after_keyword(trait_item.span, keywords::Type); if !self.span.filter_generated(sub_span, trait_item.span) { - self.dumper.typedef(TypeDefData { - span: sub_span.expect("No span found for assoc type"), - name: name, - id: trait_item.id, - qualname: qualname, + let span = self.span_from_span(sub_span.expect("No span found for assoc type")); + let id = ::id_from_node_id(trait_item.id, &self.save_ctxt); + + self.dumper.dump_def(true, Def { + kind: DefKind::Type, + id, + span, + name, + qualname, value: self.span.snippet(trait_item.span), - visibility: Visibility::Public, - parent: Some(trait_id), + parent: Some(::id_from_def_id(trait_id)), + children: vec![], + decl_id: None, docs: docs_for_attrs(&trait_item.attrs), sig: sig::assoc_type_signature(trait_item.id, trait_item.ident, Some(bounds), default_ty.as_ref().map(|ty| &**ty), &self.save_ctxt), - attributes: trait_item.attrs.clone(), - }.lower(self.tcx)); + attributes: lower_attributes(trait_item.attrs.clone(), &self.save_ctxt), + }); } if let &Some(ref default_ty) = default_ty { @@ -1178,7 +1058,7 @@ fn process_trait_item(&mut self, trait_item: &'l ast::TraitItem, trait_id: DefId } fn process_impl_item(&mut self, impl_item: &'l ast::ImplItem, impl_id: DefId) { - self.process_macro_use(impl_item.span, impl_item.id); + self.process_macro_use(impl_item.span); match impl_item.node { ast::ImplItemKind::Const(ref ty, ref expr) => { self.process_assoc_const(impl_item.id, @@ -1187,7 +1067,7 @@ fn process_impl_item(&mut self, impl_item: &'l ast::ImplItem, impl_id: DefId) { &ty, Some(expr), impl_id, - From::from(&impl_item.vis), + impl_item.vis.clone(), &impl_item.attrs); } ast::ImplItemKind::Method(ref sig, ref body) => { @@ -1195,8 +1075,7 @@ fn process_impl_item(&mut self, impl_item: &'l ast::ImplItem, impl_id: DefId) { Some(body), impl_item.id, impl_item.ident, - From::from(&impl_item.vis), - &impl_item.attrs, + impl_item.vis.clone(), impl_item.span); } ast::ImplItemKind::Type(ref ty) => { @@ -1220,25 +1099,30 @@ fn visit_mod(&mut self, m: &'l ast::Mod, span: Span, attrs: &[ast::Attribute], i let cm = self.tcx.sess.codemap(); let filename = cm.span_to_filename(span); - self.dumper.mod_data(ModData { - id: id, + let data_id = ::id_from_node_id(id, &self.save_ctxt); + let children = m.items.iter().map(|i| ::id_from_node_id(i.id, &self.save_ctxt)).collect(); + let span = self.span_from_span(span); + + self.dumper.dump_def(true, Def { + kind: DefKind::Mod, + id: data_id, name: String::new(), - qualname: qualname, - span: span, - scope: id, - filename: filename, - items: m.items.iter().map(|i| i.id).collect(), - visibility: Visibility::Public, + qualname, + span, + value: filename, + children, + parent: None, + decl_id: None, docs: docs_for_attrs(attrs), sig: None, - attributes: attrs.to_owned(), - }.lower(self.tcx)); + attributes: lower_attributes(attrs.to_owned(), &self.save_ctxt), + }); self.nest_scope(id, |v| visit::walk_mod(v, m)); } fn visit_item(&mut self, item: &'l ast::Item) { use syntax::ast::ItemKind::*; - self.process_macro_use(item.span, item.id); + self.process_macro_use(item.span); match item.node { Use(ref use_item) => { match use_item.node { @@ -1246,9 +1130,7 @@ fn visit_item(&mut self, item: &'l ast::Item) { let sub_span = self.span.span_for_last_ident(path.span); let mod_id = match self.lookup_def_id(item.id) { Some(def_id) => { - let scope = self.cur_scope; - self.process_def_kind(item.id, path.span, sub_span, def_id, scope); - + self.process_def_kind(item.id, path.span, sub_span, def_id); Some(def_id) } None => None, @@ -1263,14 +1145,15 @@ fn visit_item(&mut self, item: &'l ast::Item) { }; if !self.span.filter_generated(sub_span, path.span) { - self.dumper.use_data(UseData { - span: sub_span.expect("No span found for use"), - id: item.id, - mod_id: mod_id, + let span = + self.span_from_span(sub_span.expect("No span found for use")); + self.dumper.import(item.vis == ast::Visibility::Public, Import { + kind: ImportKind::Use, + ref_id: mod_id.map(|id| ::id_from_def_id(id)), + span, name: ident.to_string(), - scope: self.cur_scope, - visibility: From::from(&item.vis), - }.lower(self.tcx)); + value: String::new(), + }); } self.write_sub_paths_truncated(path); } @@ -1288,23 +1171,24 @@ fn visit_item(&mut self, item: &'l ast::Item) { let sub_span = self.span .sub_span_of_token(item.span, token::BinOp(token::Star)); if !self.span.filter_generated(sub_span, item.span) { - self.dumper.use_glob(UseGlobData { - span: sub_span.expect("No span found for use glob"), - id: item.id, - names: names, - scope: self.cur_scope, - visibility: From::from(&item.vis), - }.lower(self.tcx)); + let span = + self.span_from_span(sub_span.expect("No span found for use glob")); + self.dumper.import(item.vis == ast::Visibility::Public, Import { + kind: ImportKind::GlobUse, + ref_id: None, + span, + name: "*".to_owned(), + value: names.join(", "), + }); } self.write_sub_paths(path); } ast::ViewPathList(ref path, ref list) => { for plid in list { - let scope = self.cur_scope; let id = plid.node.id; if let Some(def_id) = self.lookup_def_id(id) { let span = plid.span; - self.process_def_kind(id, span, Some(span), def_id, scope); + self.process_def_kind(id, span, Some(span), def_id); } } @@ -1312,26 +1196,19 @@ fn visit_item(&mut self, item: &'l ast::Item) { } } } - ExternCrate(ref s) => { - let location = match *s { - Some(s) => s.to_string(), - None => item.ident.to_string(), - }; + ExternCrate(_) => { let alias_span = self.span.span_for_last_ident(item.span); - let cnum = match self.sess.cstore.extern_mod_stmt_cnum(item.id) { - Some(cnum) => cnum, - None => LOCAL_CRATE, - }; if !self.span.filter_generated(alias_span, item.span) { - self.dumper.extern_crate(ExternCrateData { - id: item.id, + let span = + self.span_from_span(alias_span.expect("No span found for extern crate")); + self.dumper.import(false, Import { + kind: ImportKind::ExternCrate, + ref_id: None, + span, name: item.ident.to_string(), - crate_num: cnum, - location: location, - span: alias_span.expect("No span found for extern crate"), - scope: self.cur_scope, - }.lower(self.tcx)); + value: String::new(), + }); } } Fn(ref decl, .., ref ty_params, ref body) => @@ -1360,18 +1237,23 @@ fn visit_item(&mut self, item: &'l ast::Item) { let value = ty_to_string(&ty); let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Type); if !self.span.filter_generated(sub_span, item.span) { - self.dumper.typedef(TypeDefData { - span: sub_span.expect("No span found for typedef"), + let span = self.span_from_span(sub_span.expect("No span found for typedef")); + let id = ::id_from_node_id(item.id, &self.save_ctxt); + + self.dumper.dump_def(item.vis == ast::Visibility::Public, Def { + kind: DefKind::Type, + id, + span, name: item.ident.to_string(), - id: item.id, qualname: qualname.clone(), - value: value, - visibility: From::from(&item.vis), + value, parent: None, + children: vec![], + decl_id: None, docs: docs_for_attrs(&item.attrs), sig: sig::item_signature(item, &self.save_ctxt), - attributes: item.attrs.clone(), - }.lower(self.tcx)); + attributes: lower_attributes(item.attrs.clone(), &self.save_ctxt), + }); } self.visit_ty(&ty); @@ -1396,7 +1278,7 @@ fn visit_generics(&mut self, generics: &'l ast::Generics) { } fn visit_ty(&mut self, t: &'l ast::Ty) { - self.process_macro_use(t.span, t.id); + self.process_macro_use(t.span); match t.node { ast::TyKind::Path(_, ref path) => { if generated_code(t.span) { @@ -1405,12 +1287,12 @@ fn visit_ty(&mut self, t: &'l ast::Ty) { if let Some(id) = self.lookup_def_id(t.id) { if let Some(sub_span) = self.span.sub_span_for_type_name(t.span) { - self.dumper.type_ref(TypeRefData { - span: sub_span, - ref_id: Some(id), - scope: self.cur_scope, - qualname: String::new() - }.lower(self.tcx)); + let span = self.span_from_span(sub_span); + self.dumper.dump_ref(Ref { + kind: RefKind::Type, + span, + ref_id: ::id_from_def_id(id), + }); } } @@ -1427,7 +1309,7 @@ fn visit_ty(&mut self, t: &'l ast::Ty) { fn visit_expr(&mut self, ex: &'l ast::Expr) { debug!("visit_expr {:?}", ex.node); - self.process_macro_use(ex.span, ex.id); + self.process_macro_use(ex.span); match ex.node { ast::ExprKind::Struct(ref path, ref fields, ref base) => { let hir_expr = self.save_ctxt.tcx.hir.expect_expr(ex.id); @@ -1446,9 +1328,9 @@ fn visit_expr(&mut self, ex: &'l ast::Expr) { self.visit_expr(&sub_ex); if let Some(field_data) = self.save_ctxt.get_expr_data(ex) { - down_cast_data!(field_data, VariableRefData, ex.span); - if !self.span.filter_generated(Some(field_data.span), ex.span) { - self.dumper.variable_ref(field_data.lower(self.tcx)); + down_cast_data!(field_data, RefData, ex.span); + if !generated_code(ex.span) { + self.dumper.dump_ref(field_data); } } } @@ -1474,12 +1356,13 @@ fn visit_expr(&mut self, ex: &'l ast::Expr) { ty::TyAdt(def, _) => { let sub_span = self.span.sub_span_after_token(ex.span, token::Dot); if !self.span.filter_generated(sub_span, ex.span) { - self.dumper.variable_ref(VariableRefData { - span: sub_span.expect("No span found for var ref"), - ref_id: def.struct_variant().fields[idx.node].did, - scope: self.cur_scope, - name: String::new() - }.lower(self.tcx)); + let span = + self.span_from_span(sub_span.expect("No span found for var ref")); + self.dumper.dump_ref(Ref { + kind: RefKind::Variable, + span: span, + ref_id: ::id_from_def_id(def.struct_variant().fields[idx.node].did), + }); } } ty::TyTuple(..) => {} @@ -1540,7 +1423,7 @@ fn visit_mac(&mut self, mac: &'l ast::Mac) { } fn visit_pat(&mut self, p: &'l ast::Pat) { - self.process_macro_use(p.span, p.id); + self.process_macro_use(p.span); self.process_pat(p); } @@ -1556,9 +1439,9 @@ fn visit_arm(&mut self, arm: &'l ast::Arm) { let mut paths_to_process = vec![]; // process collected paths - for &(id, ref p, immut, ref_kind) in &collector.collected_paths { + for &(id, ref p, immut) in &collector.collected_paths { match self.save_ctxt.get_path_def(id) { - Def::Local(def_id) => { + HirDef::Local(def_id) => { let id = self.tcx.hir.as_local_node_id(def_id).unwrap(); let mut value = if immut == ast::Mutability::Immutable { self.span.snippet(p.span).to_string() @@ -1573,53 +1456,56 @@ fn visit_arm(&mut self, arm: &'l ast::Arm) { assert!(p.segments.len() == 1, "qualified path for local variable def in arm"); if !self.span.filter_generated(Some(p.span), p.span) { - self.dumper.variable(VariableData { - span: p.span, - kind: VariableKind::Local, - id: id, + let qualname = format!("{}${}", path_to_string(p), id); + let id = ::id_from_node_id(id, &self.save_ctxt); + let span = self.span_from_span(p.span); + + self.dumper.dump_def(false, Def { + kind: DefKind::Local, + id, + span, name: path_to_string(p), - qualname: format!("{}${}", path_to_string(p), id), - value: value, - type_value: typ, - scope: CRATE_NODE_ID, + qualname, + value: typ, parent: None, - visibility: Visibility::Inherited, + children: vec![], + decl_id: None, docs: String::new(), sig: None, - attributes: vec![], - }.lower(self.tcx)); + attributes:vec![], + }); } } - Def::StructCtor(..) | Def::VariantCtor(..) | - Def::Const(..) | Def::AssociatedConst(..) | - Def::Struct(..) | Def::Variant(..) | - Def::TyAlias(..) | Def::AssociatedTy(..) | - Def::SelfTy(..) => { - paths_to_process.push((id, p.clone(), Some(ref_kind))) + HirDef::StructCtor(..) | HirDef::VariantCtor(..) | + HirDef::Const(..) | HirDef::AssociatedConst(..) | + HirDef::Struct(..) | HirDef::Variant(..) | + HirDef::TyAlias(..) | HirDef::AssociatedTy(..) | + HirDef::SelfTy(..) => { + paths_to_process.push((id, p.clone())) } def => error!("unexpected definition kind when processing collected paths: {:?}", def), } } - for &(id, ref path, ref_kind) in &paths_to_process { - self.process_path(id, path, ref_kind); + for &(id, ref path) in &paths_to_process { + self.process_path(id, path); } walk_list!(self, visit_expr, &arm.guard); self.visit_expr(&arm.body); } fn visit_path(&mut self, p: &'l ast::Path, id: NodeId) { - self.process_path(id, p, None); + self.process_path(id, p); } fn visit_stmt(&mut self, s: &'l ast::Stmt) { - self.process_macro_use(s.span, s.id); + self.process_macro_use(s.span); visit::walk_stmt(self, s) } fn visit_local(&mut self, l: &'l ast::Local) { - self.process_macro_use(l.span, l.id); + self.process_macro_use(l.span); let value = l.init.as_ref().map(|i| self.span.snippet(i.span)).unwrap_or(String::new()); self.process_var_decl(&l.pat, value); @@ -1632,14 +1518,12 @@ fn visit_foreign_item(&mut self, item: &'l ast::ForeignItem) { match item.node { ast::ForeignItemKind::Fn(ref decl, ref generics) => { if let Some(fn_data) = self.save_ctxt.get_extern_item_data(item) { - down_cast_data!(fn_data, FunctionData, item.span); - if !self.span.filter_generated(Some(fn_data.span), item.span) { - self.dumper.function(fn_data.clone().lower(self.tcx)); - } + down_cast_data!(fn_data, DefData, item.span); self.nest_tables(item.id, |v| v.process_formals(&decl.inputs, &fn_data.qualname)); self.process_generic_params(generics, item.span, &fn_data.qualname, item.id); + self.dumper.dump_def(item.vis == ast::Visibility::Public, fn_data); } for arg in &decl.inputs { @@ -1652,10 +1536,8 @@ fn visit_foreign_item(&mut self, item: &'l ast::ForeignItem) { } ast::ForeignItemKind::Static(ref ty, _) => { if let Some(var_data) = self.save_ctxt.get_extern_item_data(item) { - down_cast_data!(var_data, VariableData, item.span); - if !self.span.filter_generated(Some(var_data.span), item.span) { - self.dumper.variable(var_data.lower(self.tcx)); - } + down_cast_data!(var_data, DefData, item.span); + self.dumper.dump_def(item.vis == ast::Visibility::Public, var_data); } self.visit_ty(ty); diff --git a/src/librustc_save_analysis/external_data.rs b/src/librustc_save_analysis/external_data.rs deleted file mode 100644 index 245a3bcc617..00000000000 --- a/src/librustc_save_analysis/external_data.rs +++ /dev/null @@ -1,748 +0,0 @@ -// 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use rustc::hir::def_id::{CrateNum, DefId, DefIndex}; -use rustc::hir::map::Map; -use rustc::ty::TyCtxt; -use syntax::ast::{self, NodeId}; -use syntax::codemap::CodeMap; -use syntax::print::pprust; -use syntax_pos::Span; - -use data::{self, Visibility}; - -use rls_data::{SpanData, CratePreludeData, Attribute, Signature}; -use rls_span::{Column, Row}; - -// FIXME: this should be pub(crate), but the current snapshot doesn't allow it yet -pub trait Lower { - type Target; - fn lower(self, tcx: TyCtxt) -> Self::Target; -} - -pub fn make_def_id(id: NodeId, map: &Map) -> DefId { - map.opt_local_def_id(id).unwrap_or(null_def_id()) -} - -pub fn null_def_id() -> DefId { - DefId { - krate: CrateNum::from_u32(u32::max_value()), - index: DefIndex::from_u32(u32::max_value()) - } -} - -pub fn span_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().into(), - byte_start: span.lo.0, - byte_end: span.hi.0, - line_start: Row::new_one_indexed(start.line as u32), - line_end: Row::new_one_indexed(end.line as u32), - column_start: Column::new_one_indexed(start.col.0 as u32 + 1), - column_end: Column::new_one_indexed(end.col.0 as u32 + 1), - } -} - -impl Lower for Vec { - type Target = Vec; - - fn lower(self, tcx: TyCtxt) -> Vec { - self.into_iter() - // Only retain real attributes. Doc comments are lowered separately. - .filter(|attr| attr.path != "doc") - .map(|mut attr| { - // Remove the surrounding '#[..]' or '#![..]' of the pretty printed - // attribute. First normalize all inner attribute (#![..]) to outer - // ones (#[..]), then remove the two leading and the one trailing character. - attr.style = ast::AttrStyle::Outer; - let value = pprust::attribute_to_string(&attr); - // This str slicing works correctly, because the leading and trailing characters - // are in the ASCII range and thus exactly one byte each. - let value = value[2..value.len()-1].to_string(); - - Attribute { - value: value, - span: span_from_span(attr.span, tcx.sess.codemap()), - } - }).collect() - } -} - -impl Lower for data::CratePreludeData { - type Target = CratePreludeData; - - fn lower(self, tcx: TyCtxt) -> CratePreludeData { - CratePreludeData { - crate_name: self.crate_name, - crate_root: self.crate_root, - external_crates: self.external_crates, - span: span_from_span(self.span, tcx.sess.codemap()), - } - } -} - -/// Data for enum declarations. -#[derive(Clone, Debug)] -pub struct EnumData { - pub id: DefId, - pub value: String, - pub name: String, - pub qualname: String, - pub span: SpanData, - pub scope: DefId, - pub variants: Vec, - pub visibility: Visibility, - pub docs: String, - pub sig: Option, - pub attributes: Vec, -} - -impl Lower for data::EnumData { - type Target = EnumData; - - fn lower(self, tcx: TyCtxt) -> EnumData { - EnumData { - id: make_def_id(self.id, &tcx.hir), - name: self.name, - value: self.value, - qualname: self.qualname, - span: span_from_span(self.span, tcx.sess.codemap()), - scope: make_def_id(self.scope, &tcx.hir), - variants: self.variants.into_iter().map(|id| make_def_id(id, &tcx.hir)).collect(), - visibility: self.visibility, - docs: self.docs, - sig: self.sig, - attributes: self.attributes.lower(tcx), - } - } -} - -/// Data for extern crates. -#[derive(Debug)] -pub struct ExternCrateData { - pub id: DefId, - pub name: String, - pub crate_num: CrateNum, - pub location: String, - pub span: SpanData, - pub scope: DefId, -} - -impl Lower for data::ExternCrateData { - type Target = ExternCrateData; - - fn lower(self, tcx: TyCtxt) -> ExternCrateData { - ExternCrateData { - id: make_def_id(self.id, &tcx.hir), - name: self.name, - crate_num: self.crate_num, - location: self.location, - span: span_from_span(self.span, tcx.sess.codemap()), - scope: make_def_id(self.scope, &tcx.hir), - } - } -} - -/// Data about a function call. -#[derive(Debug)] -pub struct FunctionCallData { - pub span: SpanData, - pub scope: DefId, - pub ref_id: DefId, -} - -impl Lower for data::FunctionCallData { - type Target = FunctionCallData; - - fn lower(self, tcx: TyCtxt) -> FunctionCallData { - FunctionCallData { - span: span_from_span(self.span, tcx.sess.codemap()), - scope: make_def_id(self.scope, &tcx.hir), - ref_id: self.ref_id, - } - } -} - -/// Data for all kinds of functions and methods. -#[derive(Clone, Debug)] -pub struct FunctionData { - pub id: DefId, - pub name: String, - pub qualname: String, - pub declaration: Option, - pub span: SpanData, - pub scope: DefId, - pub value: String, - pub visibility: Visibility, - pub parent: Option, - pub docs: String, - pub sig: Option, - pub attributes: Vec, -} - -impl Lower for data::FunctionData { - type Target = FunctionData; - - fn lower(self, tcx: TyCtxt) -> FunctionData { - FunctionData { - id: make_def_id(self.id, &tcx.hir), - name: self.name, - qualname: self.qualname, - declaration: self.declaration, - span: span_from_span(self.span, tcx.sess.codemap()), - scope: make_def_id(self.scope, &tcx.hir), - value: self.value, - visibility: self.visibility, - parent: self.parent, - docs: self.docs, - sig: self.sig, - attributes: self.attributes.lower(tcx), - } - } -} - -/// Data about a function call. -#[derive(Debug)] -pub struct FunctionRefData { - pub span: SpanData, - pub scope: DefId, - pub ref_id: DefId, -} - -impl Lower for data::FunctionRefData { - type Target = FunctionRefData; - - fn lower(self, tcx: TyCtxt) -> FunctionRefData { - FunctionRefData { - span: span_from_span(self.span, tcx.sess.codemap()), - scope: make_def_id(self.scope, &tcx.hir), - ref_id: self.ref_id, - } - } -} -#[derive(Debug)] -pub struct ImplData { - pub id: DefId, - pub span: SpanData, - pub scope: DefId, - pub trait_ref: Option, - pub self_ref: Option, -} - -impl Lower for data::ImplData { - type Target = ImplData; - - fn lower(self, tcx: TyCtxt) -> ImplData { - ImplData { - id: make_def_id(self.id, &tcx.hir), - span: span_from_span(self.span, tcx.sess.codemap()), - scope: make_def_id(self.scope, &tcx.hir), - trait_ref: self.trait_ref, - self_ref: self.self_ref, - } - } -} - -#[derive(Debug)] -pub struct InheritanceData { - pub span: SpanData, - pub base_id: DefId, - pub deriv_id: DefId -} - -impl Lower for data::InheritanceData { - type Target = InheritanceData; - - fn lower(self, tcx: TyCtxt) -> InheritanceData { - InheritanceData { - span: span_from_span(self.span, tcx.sess.codemap()), - base_id: self.base_id, - deriv_id: make_def_id(self.deriv_id, &tcx.hir) - } - } -} - -/// Data about a macro declaration. -#[derive(Debug)] -pub struct MacroData { - pub span: SpanData, - pub name: String, - pub qualname: String, - pub docs: String, -} - -impl Lower for data::MacroData { - type Target = MacroData; - - fn lower(self, tcx: TyCtxt) -> MacroData { - MacroData { - span: span_from_span(self.span, tcx.sess.codemap()), - name: self.name, - qualname: self.qualname, - docs: self.docs, - } - } -} - -/// Data about a macro use. -#[derive(Debug)] -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: DefId, -} - -impl Lower for data::MacroUseData { - type Target = MacroUseData; - - fn lower(self, tcx: TyCtxt) -> MacroUseData { - MacroUseData { - span: span_from_span(self.span, tcx.sess.codemap()), - name: self.name, - qualname: self.qualname, - callee_span: span_from_span(self.callee_span, tcx.sess.codemap()), - scope: make_def_id(self.scope, &tcx.hir), - } - } -} - -/// Data about a method call. -#[derive(Debug)] -pub struct MethodCallData { - pub span: SpanData, - pub scope: DefId, - pub ref_id: Option, - pub decl_id: Option, -} - -impl Lower for data::MethodCallData { - type Target = MethodCallData; - - fn lower(self, tcx: TyCtxt) -> MethodCallData { - MethodCallData { - span: span_from_span(self.span, tcx.sess.codemap()), - scope: make_def_id(self.scope, &tcx.hir), - 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)] -pub struct MethodData { - pub id: DefId, - pub name: String, - pub qualname: String, - pub span: SpanData, - pub scope: DefId, - pub value: String, - pub decl_id: Option, - pub visibility: Visibility, - pub parent: Option, - pub docs: String, - pub sig: Option, - pub attributes: Vec, -} - -impl Lower for data::MethodData { - type Target = MethodData; - - fn lower(self, tcx: TyCtxt) -> MethodData { - MethodData { - span: span_from_span(self.span, tcx.sess.codemap()), - name: self.name, - scope: make_def_id(self.scope, &tcx.hir), - id: make_def_id(self.id, &tcx.hir), - qualname: self.qualname, - value: self.value, - decl_id: self.decl_id, - visibility: self.visibility, - parent: self.parent, - docs: self.docs, - sig: self.sig, - attributes: self.attributes.lower(tcx), - } - } -} - -/// Data for modules. -#[derive(Debug)] -pub struct ModData { - pub id: DefId, - pub name: String, - pub qualname: String, - pub span: SpanData, - pub scope: DefId, - pub filename: String, - pub items: Vec, - pub visibility: Visibility, - pub docs: String, - pub sig: Option, - pub attributes: Vec, -} - -impl Lower for data::ModData { - type Target = ModData; - - fn lower(self, tcx: TyCtxt) -> ModData { - ModData { - id: make_def_id(self.id, &tcx.hir), - name: self.name, - qualname: self.qualname, - span: span_from_span(self.span, tcx.sess.codemap()), - scope: make_def_id(self.scope, &tcx.hir), - filename: self.filename, - items: self.items.into_iter().map(|id| make_def_id(id, &tcx.hir)).collect(), - visibility: self.visibility, - docs: self.docs, - sig: self.sig, - attributes: self.attributes.lower(tcx), - } - } -} - -/// Data for a reference to a module. -#[derive(Debug)] -pub struct ModRefData { - pub span: SpanData, - pub scope: DefId, - pub ref_id: Option, - pub qualname: String -} - -impl Lower for data::ModRefData { - type Target = ModRefData; - - fn lower(self, tcx: TyCtxt) -> ModRefData { - ModRefData { - span: span_from_span(self.span, tcx.sess.codemap()), - scope: make_def_id(self.scope, &tcx.hir), - ref_id: self.ref_id, - qualname: self.qualname, - } - } -} - -#[derive(Debug)] -pub struct StructData { - pub span: SpanData, - pub name: String, - pub id: DefId, - pub ctor_id: DefId, - pub qualname: String, - pub scope: DefId, - pub value: String, - pub fields: Vec, - pub visibility: Visibility, - pub docs: String, - pub sig: Option, - pub attributes: Vec, -} - -impl Lower for data::StructData { - type Target = StructData; - - fn lower(self, tcx: TyCtxt) -> StructData { - StructData { - span: span_from_span(self.span, tcx.sess.codemap()), - name: self.name, - id: make_def_id(self.id, &tcx.hir), - ctor_id: make_def_id(self.ctor_id, &tcx.hir), - qualname: self.qualname, - scope: make_def_id(self.scope, &tcx.hir), - value: self.value, - fields: self.fields.into_iter().map(|id| make_def_id(id, &tcx.hir)).collect(), - visibility: self.visibility, - docs: self.docs, - sig: self.sig, - attributes: self.attributes.lower(tcx), - } - } -} - -#[derive(Debug)] -pub struct StructVariantData { - pub span: SpanData, - pub name: String, - pub id: DefId, - pub qualname: String, - pub type_value: String, - pub value: String, - pub scope: DefId, - pub parent: Option, - pub docs: String, - pub sig: Option, - pub attributes: Vec, -} - -impl Lower for data::StructVariantData { - type Target = StructVariantData; - - fn lower(self, tcx: TyCtxt) -> StructVariantData { - StructVariantData { - span: span_from_span(self.span, tcx.sess.codemap()), - name: self.name, - id: make_def_id(self.id, &tcx.hir), - qualname: self.qualname, - type_value: self.type_value, - value: self.value, - scope: make_def_id(self.scope, &tcx.hir), - parent: self.parent, - docs: self.docs, - sig: self.sig, - attributes: self.attributes.lower(tcx), - } - } -} - -#[derive(Debug)] -pub struct TraitData { - pub span: SpanData, - pub name: String, - pub id: DefId, - pub qualname: String, - pub scope: DefId, - pub value: String, - pub items: Vec, - pub visibility: Visibility, - pub docs: String, - pub sig: Option, - pub attributes: Vec, -} - -impl Lower for data::TraitData { - type Target = TraitData; - - fn lower(self, tcx: TyCtxt) -> TraitData { - TraitData { - span: span_from_span(self.span, tcx.sess.codemap()), - name: self.name, - id: make_def_id(self.id, &tcx.hir), - qualname: self.qualname, - scope: make_def_id(self.scope, &tcx.hir), - value: self.value, - items: self.items.into_iter().map(|id| make_def_id(id, &tcx.hir)).collect(), - visibility: self.visibility, - docs: self.docs, - sig: self.sig, - attributes: self.attributes.lower(tcx), - } - } -} - -#[derive(Debug)] -pub struct TupleVariantData { - pub span: SpanData, - pub id: DefId, - pub name: String, - pub qualname: String, - pub type_value: String, - pub value: String, - pub scope: DefId, - pub parent: Option, - pub docs: String, - pub sig: Option, - pub attributes: Vec, -} - -impl Lower for data::TupleVariantData { - type Target = TupleVariantData; - - fn lower(self, tcx: TyCtxt) -> TupleVariantData { - TupleVariantData { - span: span_from_span(self.span, tcx.sess.codemap()), - id: make_def_id(self.id, &tcx.hir), - name: self.name, - qualname: self.qualname, - type_value: self.type_value, - value: self.value, - scope: make_def_id(self.scope, &tcx.hir), - parent: self.parent, - docs: self.docs, - sig: self.sig, - attributes: self.attributes.lower(tcx), - } - } -} - -/// Data for a typedef. -#[derive(Debug)] -pub struct TypeDefData { - pub id: DefId, - pub name: String, - pub span: SpanData, - pub qualname: String, - pub value: String, - pub visibility: Visibility, - pub parent: Option, - pub docs: String, - pub sig: Option, - pub attributes: Vec, -} - -impl Lower for data::TypeDefData { - type Target = TypeDefData; - - fn lower(self, tcx: TyCtxt) -> TypeDefData { - TypeDefData { - id: make_def_id(self.id, &tcx.hir), - name: self.name, - span: span_from_span(self.span, tcx.sess.codemap()), - qualname: self.qualname, - value: self.value, - visibility: self.visibility, - parent: self.parent, - docs: self.docs, - sig: self.sig, - attributes: self.attributes.lower(tcx), - } - } -} - -/// Data for a reference to a type or trait. -#[derive(Clone, Debug)] -pub struct TypeRefData { - pub span: SpanData, - pub scope: DefId, - pub ref_id: Option, - pub qualname: String, -} - -impl Lower for data::TypeRefData { - type Target = TypeRefData; - - fn lower(self, tcx: TyCtxt) -> TypeRefData { - TypeRefData { - span: span_from_span(self.span, tcx.sess.codemap()), - scope: make_def_id(self.scope, &tcx.hir), - ref_id: self.ref_id, - qualname: self.qualname, - } - } -} - -#[derive(Debug)] -pub struct UseData { - pub id: DefId, - pub span: SpanData, - pub name: String, - pub mod_id: Option, - pub scope: DefId, - pub visibility: Visibility, -} - -impl Lower for data::UseData { - type Target = UseData; - - fn lower(self, tcx: TyCtxt) -> UseData { - UseData { - id: make_def_id(self.id, &tcx.hir), - span: span_from_span(self.span, tcx.sess.codemap()), - name: self.name, - mod_id: self.mod_id, - scope: make_def_id(self.scope, &tcx.hir), - visibility: self.visibility, - } - } -} - -#[derive(Debug)] -pub struct UseGlobData { - pub id: DefId, - pub span: SpanData, - pub names: Vec, - pub scope: DefId, - pub visibility: Visibility, -} - -impl Lower for data::UseGlobData { - type Target = UseGlobData; - - fn lower(self, tcx: TyCtxt) -> UseGlobData { - UseGlobData { - id: make_def_id(self.id, &tcx.hir), - span: span_from_span(self.span, tcx.sess.codemap()), - names: self.names, - scope: make_def_id(self.scope, &tcx.hir), - visibility: self.visibility, - } - } -} - -/// Data for local and global variables (consts and statics). -#[derive(Debug)] -pub struct VariableData { - pub id: DefId, - pub name: String, - pub kind: data::VariableKind, - pub qualname: String, - pub span: SpanData, - pub scope: DefId, - pub value: String, - pub type_value: String, - pub parent: Option, - pub visibility: Visibility, - pub docs: String, - pub sig: Option, - pub attributes: Vec, -} - -impl Lower for data::VariableData { - type Target = VariableData; - - fn lower(self, tcx: TyCtxt) -> VariableData { - VariableData { - id: make_def_id(self.id, &tcx.hir), - kind: self.kind, - name: self.name, - qualname: self.qualname, - span: span_from_span(self.span, tcx.sess.codemap()), - scope: make_def_id(self.scope, &tcx.hir), - value: self.value, - type_value: self.type_value, - parent: self.parent, - visibility: self.visibility, - docs: self.docs, - sig: self.sig, - attributes: self.attributes.lower(tcx), - } - } -} - -/// 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)] -pub struct VariableRefData { - pub name: String, - pub span: SpanData, - pub scope: DefId, - pub ref_id: DefId, -} - -impl Lower for data::VariableRefData { - type Target = VariableRefData; - - fn lower(self, tcx: TyCtxt) -> VariableRefData { - VariableRefData { - name: self.name, - span: span_from_span(self.span, tcx.sess.codemap()), - scope: make_def_id(self.scope, &tcx.hir), - ref_id: self.ref_id, - } - } -} diff --git a/src/librustc_save_analysis/json_api_dumper.rs b/src/librustc_save_analysis/json_api_dumper.rs index bddee6460ff..4b2301fd7f8 100644 --- a/src/librustc_save_analysis/json_api_dumper.rs +++ b/src/librustc_save_analysis/json_api_dumper.rs @@ -12,12 +12,9 @@ use rustc_serialize::json::as_json; -use external_data::*; -use data::{VariableKind, Visibility}; -use dump::Dump; -use id_from_def_id; +use Dump; -use rls_data::{Analysis, Import, ImportKind, Def, DefKind, CratePreludeData, Format}; +use rls_data::{Analysis, Import, Def, CratePreludeData, Format, Relation}; // A dumper to dump a restricted set of JSON information, designed for use with @@ -47,306 +44,23 @@ fn drop(&mut self) { } } -macro_rules! impl_fn { - ($fn_name: ident, $data_type: ident, $bucket: ident) => { - fn $fn_name(&mut self, data: $data_type) { - if let Some(datum) = data.into() { - self.result.$bucket.push(datum); - } - } - } -} - impl<'b, W: Write + 'b> Dump for JsonApiDumper<'b, W> { fn crate_prelude(&mut self, data: CratePreludeData) { self.result.prelude = Some(data) } - impl_fn!(use_data, UseData, imports); - impl_fn!(use_glob, UseGlobData, imports); - - impl_fn!(enum_data, EnumData, defs); - impl_fn!(tuple_variant, TupleVariantData, defs); - impl_fn!(struct_variant, StructVariantData, defs); - impl_fn!(struct_data, StructData, defs); - impl_fn!(trait_data, TraitData, defs); - impl_fn!(function, FunctionData, defs); - impl_fn!(method, MethodData, defs); - impl_fn!(macro_data, MacroData, defs); - impl_fn!(mod_data, ModData, defs); - impl_fn!(typedef, TypeDefData, defs); - impl_fn!(variable, VariableData, defs); - - fn impl_data(&mut self, data: ImplData) { - if data.self_ref.is_some() { - self.result.relations.push(data.into()); - } - } - fn inheritance(&mut self, data: InheritanceData) { - self.result.relations.push(data.into()); + fn dump_relation(&mut self, data: Relation) { + self.result.relations.push(data); } -} - -// FIXME methods. The defs have information about possible overriding and the -// refs have decl information (e.g., a trait method where we know the required -// method, but not the supplied method). In both cases, we are currently -// ignoring it. - -impl Into> for UseData { - fn into(self) -> Option { - match self.visibility { - Visibility::Public => Some(Import { - kind: ImportKind::Use, - ref_id: self.mod_id.map(|id| id_from_def_id(id)), - span: self.span, - name: self.name, - value: String::new(), - }), - _ => None, + fn import(&mut self, public: bool, import: Import) { + if public { + self.result.imports.push(import); } } -} -impl Into> for UseGlobData { - fn into(self) -> Option { - match self.visibility { - Visibility::Public => Some(Import { - kind: ImportKind::GlobUse, - ref_id: None, - span: self.span, - name: "*".to_owned(), - value: self.names.join(", "), - }), - _ => None, - } - } -} - -impl Into> for EnumData { - fn into(self) -> Option { - match self.visibility { - Visibility::Public => Some(Def { - kind: DefKind::Enum, - id: id_from_def_id(self.id), - span: self.span, - name: self.name, - qualname: self.qualname, - value: self.value, - parent: None, - children: self.variants.into_iter().map(|id| id_from_def_id(id)).collect(), - decl_id: None, - docs: self.docs, - sig: self.sig, - attributes: vec![], - }), - _ => None, - } - } -} - -impl Into> for TupleVariantData { - fn into(self) -> Option { - Some(Def { - kind: DefKind::Tuple, - id: id_from_def_id(self.id), - span: self.span, - name: self.name, - qualname: self.qualname, - value: self.value, - parent: self.parent.map(|id| id_from_def_id(id)), - children: vec![], - decl_id: None, - docs: self.docs, - sig: self.sig, - attributes: vec![], - }) - } -} -impl Into> for StructVariantData { - fn into(self) -> Option { - Some(Def { - kind: DefKind::Struct, - id: id_from_def_id(self.id), - span: self.span, - name: self.name, - qualname: self.qualname, - value: self.value, - parent: self.parent.map(|id| id_from_def_id(id)), - children: vec![], - decl_id: None, - docs: self.docs, - sig: self.sig, - attributes: vec![], - }) - } -} -impl Into> for StructData { - fn into(self) -> Option { - match self.visibility { - Visibility::Public => Some(Def { - kind: DefKind::Struct, - id: id_from_def_id(self.id), - span: self.span, - name: self.name, - qualname: self.qualname, - value: self.value, - parent: None, - children: self.fields.into_iter().map(|id| id_from_def_id(id)).collect(), - decl_id: None, - docs: self.docs, - sig: self.sig, - attributes: vec![], - }), - _ => None, - } - } -} -impl Into> for TraitData { - fn into(self) -> Option { - match self.visibility { - Visibility::Public => Some(Def { - kind: DefKind::Trait, - id: id_from_def_id(self.id), - span: self.span, - name: self.name, - qualname: self.qualname, - value: self.value, - children: self.items.into_iter().map(|id| id_from_def_id(id)).collect(), - parent: None, - decl_id: None, - docs: self.docs, - sig: self.sig, - attributes: vec![], - }), - _ => None, - } - } -} -impl Into> for FunctionData { - fn into(self) -> Option { - match self.visibility { - Visibility::Public => Some(Def { - kind: DefKind::Function, - id: id_from_def_id(self.id), - span: self.span, - name: self.name, - qualname: self.qualname, - value: self.value, - children: vec![], - parent: self.parent.map(|id| id_from_def_id(id)), - decl_id: None, - docs: self.docs, - sig: self.sig, - attributes: vec![], - }), - _ => None, - } - } -} -impl Into> for MethodData { - fn into(self) -> Option { - match self.visibility { - Visibility::Public => Some(Def { - kind: DefKind::Method, - id: id_from_def_id(self.id), - span: self.span, - name: self.name, - qualname: self.qualname, - value: self.value, - children: vec![], - parent: self.parent.map(|id| id_from_def_id(id)), - decl_id: self.decl_id.map(|id| id_from_def_id(id)), - docs: self.docs, - sig: self.sig, - attributes: vec![], - }), - _ => None, - } - } -} -impl Into> for MacroData { - fn into(self) -> Option { - Some(Def { - kind: DefKind::Macro, - id: id_from_def_id(null_def_id()), - span: self.span, - name: self.name, - qualname: self.qualname, - value: String::new(), - children: vec![], - parent: None, - decl_id: None, - docs: self.docs, - sig: None, - attributes: vec![], - }) - } -} -impl Into> for ModData { - fn into(self) -> Option { - match self.visibility { - Visibility::Public => Some(Def { - kind: DefKind::Mod, - id: id_from_def_id(self.id), - span: self.span, - name: self.name, - qualname: self.qualname, - value: self.filename, - children: self.items.into_iter().map(|id| id_from_def_id(id)).collect(), - parent: None, - decl_id: None, - docs: self.docs, - sig: self.sig.map(|s| s.into()), - attributes: vec![], - }), - _ => None, - } - } -} -impl Into> for TypeDefData { - fn into(self) -> Option { - match self.visibility { - Visibility::Public => Some(Def { - kind: DefKind::Type, - id: id_from_def_id(self.id), - span: self.span, - name: self.name, - qualname: self.qualname, - value: self.value, - children: vec![], - parent: self.parent.map(|id| id_from_def_id(id)), - decl_id: None, - docs: String::new(), - sig: self.sig.map(|s| s.into()), - attributes: vec![], - }), - _ => None, - } - } -} - -impl Into> for VariableData { - fn into(self) -> Option { - match self.visibility { - Visibility::Public => Some(Def { - kind: match self.kind { - VariableKind::Static => DefKind::Static, - VariableKind::Const => DefKind::Const, - VariableKind::Local => { return None } - VariableKind::Field => DefKind::Field, - }, - id: id_from_def_id(self.id), - span: self.span, - name: self.name, - qualname: self.qualname, - value: self.value, - children: vec![], - parent: self.parent.map(|id| id_from_def_id(id)), - decl_id: None, - docs: self.docs, - sig: self.sig.map(|s| s.into()), - attributes: vec![], - }), - _ => None, + fn dump_def(&mut self, public: bool, mut data: Def) { + if public { + data.attributes = vec![]; + self.result.defs.push(data); } } } diff --git a/src/librustc_save_analysis/json_dumper.rs b/src/librustc_save_analysis/json_dumper.rs index 58df612c687..9cd375e9855 100644 --- a/src/librustc_save_analysis/json_dumper.rs +++ b/src/librustc_save_analysis/json_dumper.rs @@ -12,14 +12,11 @@ use rustc_serialize::json::as_json; -use rls_data::{self, Id, Analysis, Import, ImportKind, Def, DefKind, Ref, RefKind, MacroRef, - Relation, RelationKind, CratePreludeData}; +use rls_data::{self, Analysis, Import, Def, DefKind, Ref, RefKind, MacroRef, + Relation, CratePreludeData}; use rls_span::{Column, Row}; -use external_data::*; -use data::VariableKind; -use dump::Dump; -use id_from_def_id; +use Dump; pub struct JsonDumper { result: Analysis, @@ -70,71 +67,35 @@ fn drop(&mut self) { } } -macro_rules! impl_fn { - ($fn_name: ident, $data_type: ident, $bucket: ident) => { - fn $fn_name(&mut self, data: $data_type) { - self.result.$bucket.push(data.into()); - } - } -} - impl<'b, O: DumpOutput + 'b> Dump for JsonDumper { fn crate_prelude(&mut self, data: CratePreludeData) { self.result.prelude = Some(data) } - impl_fn!(extern_crate, ExternCrateData, imports); - impl_fn!(use_data, UseData, imports); - impl_fn!(use_glob, UseGlobData, imports); - - impl_fn!(enum_data, EnumData, defs); - impl_fn!(tuple_variant, TupleVariantData, defs); - impl_fn!(struct_variant, StructVariantData, defs); - impl_fn!(struct_data, StructData, defs); - impl_fn!(trait_data, TraitData, defs); - impl_fn!(function, FunctionData, defs); - impl_fn!(method, MethodData, defs); - impl_fn!(macro_data, MacroData, defs); - impl_fn!(typedef, TypeDefData, defs); - impl_fn!(variable, VariableData, defs); - - impl_fn!(function_ref, FunctionRefData, refs); - impl_fn!(function_call, FunctionCallData, refs); - impl_fn!(method_call, MethodCallData, refs); - impl_fn!(mod_ref, ModRefData, refs); - impl_fn!(type_ref, TypeRefData, refs); - impl_fn!(variable_ref, VariableRefData, refs); + fn macro_use(&mut self, data: MacroRef) { + self.result.macro_refs.push(data); + } - impl_fn!(macro_use, MacroUseData, macro_refs); + fn import(&mut self, _: bool, import: Import) { + self.result.imports.push(import); + } - fn mod_data(&mut self, data: ModData) { - let id: Id = id_from_def_id(data.id); - let mut def = Def { - kind: DefKind::Mod, - id: id, - span: data.span.into(), - name: data.name, - qualname: data.qualname, - value: data.filename, - parent: None, - children: data.items.into_iter().map(|id| id_from_def_id(id)).collect(), - decl_id: None, - docs: data.docs, - sig: data.sig, - attributes: data.attributes.into_iter().map(|a| a.into()).collect(), - }; - if def.span.file_name.to_str().unwrap() != def.value { + fn dump_ref(&mut self, data: Ref) { + self.result.refs.push(data); + } + fn dump_def(&mut self, _: bool, mut data: Def) { + if data.kind == DefKind::Mod && data.span.file_name.to_str().unwrap() != data.value { // 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 // the declaration into a reference to it. let rf = Ref { kind: RefKind::Mod, - span: def.span, - ref_id: id, + span: data.span, + ref_id: data.id, }; self.result.refs.push(rf); - def.span = rls_data::SpanData { - file_name: def.value.clone().into(), + data.span = rls_data::SpanData { + file_name: data.value.clone().into(), byte_start: 0, byte_end: 0, line_start: Row::new_one_indexed(1), @@ -143,330 +104,10 @@ fn mod_data(&mut self, data: ModData) { column_end: Column::new_one_indexed(1), } } - - self.result.defs.push(def); - } - - fn impl_data(&mut self, data: ImplData) { - if data.self_ref.is_some() { - self.result.relations.push(data.into()); - } - } - fn inheritance(&mut self, data: InheritanceData) { - self.result.relations.push(data.into()); - } -} - -// FIXME do we want to change ExternalData to this mode? It will break DXR. -// FIXME methods. The defs have information about possible overriding and the -// refs have decl information (e.g., a trait method where we know the required -// method, but not the supplied method). In both cases, we are currently -// ignoring it. - -impl Into for ExternCrateData { - fn into(self) -> Import { - Import { - kind: ImportKind::ExternCrate, - ref_id: None, - span: self.span, - name: self.name, - value: String::new(), - } - } -} -impl Into for UseData { - fn into(self) -> Import { - Import { - kind: ImportKind::Use, - ref_id: self.mod_id.map(|id| id_from_def_id(id)), - span: self.span, - name: self.name, - value: String::new(), - } - } -} -impl Into for UseGlobData { - fn into(self) -> Import { - Import { - kind: ImportKind::GlobUse, - ref_id: None, - span: self.span, - name: "*".to_owned(), - value: self.names.join(", "), - } - } -} - -impl Into for EnumData { - fn into(self) -> Def { - Def { - kind: DefKind::Enum, - id: id_from_def_id(self.id), - span: self.span, - name: self.name, - qualname: self.qualname, - value: self.value, - parent: None, - children: self.variants.into_iter().map(|id| id_from_def_id(id)).collect(), - decl_id: None, - docs: self.docs, - sig: self.sig, - attributes: self.attributes, - } - } -} - -impl Into for TupleVariantData { - fn into(self) -> Def { - Def { - kind: DefKind::Tuple, - id: id_from_def_id(self.id), - span: self.span, - name: self.name, - qualname: self.qualname, - value: self.value, - parent: None, - children: vec![], - decl_id: None, - docs: self.docs, - sig: self.sig, - attributes: self.attributes, - } - } -} -impl Into for StructVariantData { - fn into(self) -> Def { - Def { - kind: DefKind::Struct, - id: id_from_def_id(self.id), - span: self.span, - name: self.name, - qualname: self.qualname, - value: self.value, - parent: None, - children: vec![], - decl_id: None, - docs: self.docs, - sig: self.sig, - attributes: self.attributes, - } - } -} -impl Into for StructData { - fn into(self) -> Def { - Def { - kind: DefKind::Struct, - id: id_from_def_id(self.id), - span: self.span, - name: self.name, - qualname: self.qualname, - value: self.value, - parent: None, - children: self.fields.into_iter().map(|id| id_from_def_id(id)).collect(), - decl_id: None, - docs: self.docs, - sig: self.sig, - attributes: self.attributes, - } - } -} -impl Into for TraitData { - fn into(self) -> Def { - Def { - kind: DefKind::Trait, - id: id_from_def_id(self.id), - span: self.span, - name: self.name, - qualname: self.qualname, - value: self.value, - parent: None, - children: self.items.into_iter().map(|id| id_from_def_id(id)).collect(), - decl_id: None, - docs: self.docs, - sig: self.sig, - attributes: self.attributes, - } - } -} -impl Into for FunctionData { - fn into(self) -> Def { - Def { - kind: DefKind::Function, - id: id_from_def_id(self.id), - span: self.span, - name: self.name, - qualname: self.qualname, - value: self.value, - parent: None, - children: vec![], - decl_id: None, - docs: self.docs, - sig: self.sig, - attributes: self.attributes, - } - } -} -impl Into for MethodData { - fn into(self) -> Def { - Def { - kind: DefKind::Method, - id: id_from_def_id(self.id), - span: self.span, - name: self.name, - qualname: self.qualname, - value: self.value, - parent: None, - children: vec![], - decl_id: self.decl_id.map(|id| id_from_def_id(id)), - docs: self.docs, - sig: self.sig, - attributes: self.attributes, - } - } -} -impl Into for MacroData { - fn into(self) -> Def { - Def { - kind: DefKind::Macro, - id: id_from_def_id(null_def_id()), - span: self.span, - name: self.name, - qualname: self.qualname, - value: String::new(), - parent: None, - children: vec![], - decl_id: None, - docs: self.docs, - sig: None, - attributes: vec![], - } - } -} -impl Into for TypeDefData { - fn into(self) -> Def { - Def { - kind: DefKind::Type, - id: id_from_def_id(self.id), - span: self.span, - name: self.name, - qualname: self.qualname, - value: self.value, - parent: None, - children: vec![], - decl_id: None, - docs: String::new(), - sig: self.sig, - attributes: self.attributes, - } + self.result.defs.push(data); } -} -impl Into for VariableData { - fn into(self) -> Def { - Def { - kind: match self.kind { - VariableKind::Static => DefKind::Static, - VariableKind::Const => DefKind::Const, - VariableKind::Local => DefKind::Local, - VariableKind::Field => DefKind::Field, - }, - id: id_from_def_id(self.id), - span: self.span, - name: self.name, - qualname: self.qualname, - value: self.type_value, - parent: None, - children: vec![], - decl_id: None, - docs: self.docs, - sig: None, - attributes: self.attributes, - } - } -} -impl Into for FunctionRefData { - fn into(self) -> Ref { - Ref { - kind: RefKind::Function, - span: self.span, - ref_id: id_from_def_id(self.ref_id), - } - } -} -impl Into for FunctionCallData { - fn into(self) -> Ref { - Ref { - kind: RefKind::Function, - span: self.span, - ref_id: id_from_def_id(self.ref_id), - } - } -} -impl Into for MethodCallData { - fn into(self) -> Ref { - Ref { - kind: RefKind::Function, - span: self.span, - ref_id: id_from_def_id(self.ref_id.or(self.decl_id).unwrap_or(null_def_id())), - } - } -} -impl Into for ModRefData { - fn into(self) -> Ref { - Ref { - kind: RefKind::Mod, - span: self.span, - ref_id: id_from_def_id(self.ref_id.unwrap_or(null_def_id())), - } - } -} -impl Into for TypeRefData { - fn into(self) -> Ref { - Ref { - kind: RefKind::Type, - span: self.span, - ref_id: id_from_def_id(self.ref_id.unwrap_or(null_def_id())), - } - } -} -impl Into for VariableRefData { - fn into(self) -> Ref { - Ref { - kind: RefKind::Variable, - span: self.span, - ref_id: id_from_def_id(self.ref_id), - } - } -} - -impl Into for MacroUseData { - fn into(self) -> MacroRef { - MacroRef { - span: self.span, - qualname: self.qualname, - callee_span: self.callee_span.into(), - } - } -} - -impl Into for ImplData { - fn into(self) -> Relation { - Relation { - span: self.span, - kind: RelationKind::Impl, - from: id_from_def_id(self.self_ref.unwrap_or(null_def_id())), - to: id_from_def_id(self.trait_ref.unwrap_or(null_def_id())), - } - } -} - -impl Into for InheritanceData { - fn into(self) -> Relation { - Relation { - span: self.span, - kind: RelationKind::SuperTrait, - from: id_from_def_id(self.base_id), - to: id_from_def_id(self.deriv_id), - } + fn dump_relation(&mut self, data: Relation) { + self.result.relations.push(data); } } diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index be879a01fb8..0b2614ee83c 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -37,17 +37,14 @@ mod json_api_dumper; mod json_dumper; -mod data; -mod dump; mod dump_visitor; -pub mod external_data; #[macro_use] -pub mod span_utils; +mod span_utils; mod sig; use rustc::hir; -use rustc::hir::def::Def; -use rustc::hir::map::Node; +use rustc::hir::def::Def as HirDef; +use rustc::hir::map::{Node, NodeItem}; use rustc::hir::def_id::DefId; use rustc::session::config::CrateType::CrateTypeExecutable; use rustc::session::Session; @@ -61,32 +58,21 @@ use syntax::ast::{self, NodeId, PatKind, Attribute, CRATE_NODE_ID}; use syntax::parse::lexer::comments::strip_doc_comment_decoration; use syntax::parse::token; +use syntax::print::pprust; use syntax::symbol::keywords; use syntax::visit::{self, Visitor}; use syntax::print::pprust::{ty_to_string, arg_to_string}; use syntax::codemap::MacroAttribute; use syntax_pos::*; -pub use self::json_api_dumper::JsonApiDumper; -pub use self::json_dumper::JsonDumper; -pub use self::data::*; -pub use self::external_data::make_def_id; -pub use self::dump::Dump; -pub use self::dump_visitor::DumpVisitor; -use self::span_utils::SpanUtils; - -// FIXME this is legacy code and should be removed -pub mod recorder { - pub use self::Row::*; - - #[derive(Copy, Clone, Debug, Eq, PartialEq)] - pub enum Row { - TypeRef, - ModRef, - VarRef, - FnRef, - } -} +pub use json_api_dumper::JsonApiDumper; +pub use json_dumper::JsonDumper; +use dump_visitor::DumpVisitor; +use span_utils::SpanUtils; + +use rls_data::{Ref, RefKind, SpanData, MacroRef, Def, DefKind, Relation, RelationKind, + ExternalCrateData, Import, CratePreludeData}; + pub struct SaveContext<'l, 'tcx: 'l> { tcx: TyCtxt<'l, 'tcx, 'tcx>, @@ -95,13 +81,49 @@ pub struct SaveContext<'l, 'tcx: 'l> { span_utils: SpanUtils<'tcx>, } +#[derive(Debug)] +pub enum Data { + /// Data about a macro use. + MacroUseData(MacroRef), + RefData(Ref), + DefData(Def), + RelationData(Relation), +} + +pub trait Dump { + fn crate_prelude(&mut self, _: CratePreludeData); + fn macro_use(&mut self, _: MacroRef) {} + fn import(&mut self, _: bool, _: Import); + fn dump_ref(&mut self, _: Ref) {} + fn dump_def(&mut self, _: bool, _: Def); + fn dump_relation(&mut self, data: Relation); +} + macro_rules! option_try( ($e:expr) => (match $e { Some(e) => e, None => return None }) ); impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { + fn span_from_span(&self, span: Span) -> SpanData { + use rls_span::{Row, Column}; + + let cm = self.tcx.sess.codemap(); + let start = cm.lookup_char_pos(span.lo); + let end = cm.lookup_char_pos(span.hi); + + SpanData { + file_name: start.file.name.clone().into(), + byte_start: span.lo.0, + byte_end: span.hi.0, + line_start: Row::new_one_indexed(start.line as u32), + line_end: Row::new_one_indexed(end.line as u32), + column_start: Column::new_one_indexed(start.col.0 as u32 + 1), + column_end: Column::new_one_indexed(end.col.0 as u32 + 1), + } + } + // List external crates used by the current crate. - pub fn get_external_crates(&self) -> Vec { + pub fn get_external_crates(&self) -> Vec { let mut result = Vec::new(); for n in self.tcx.sess.cstore.crates() { @@ -112,10 +134,11 @@ pub fn get_external_crates(&self) -> Vec { continue; } }; - result.push(CrateData { + let lo_loc = self.span_utils.sess.codemap().lookup_char_pos(span.lo); + result.push(ExternalCrateData { name: self.tcx.sess.cstore.crate_name(n).to_string(), - number: n.as_u32(), - span: span, + num: n.as_u32(), + file_name: SpanUtils::make_path_string(&lo_loc.file.name), }); } @@ -128,39 +151,43 @@ pub fn get_extern_item_data(&self, item: &ast::ForeignItem) -> Option { ast::ForeignItemKind::Fn(ref decl, ref generics) => { let sub_span = self.span_utils.sub_span_after_keyword(item.span, keywords::Fn); filter!(self.span_utils, sub_span, item.span, None); - Some(Data::FunctionData(FunctionData { - id: item.id, + + Some(Data::DefData(Def { + kind: DefKind::Function, + id: id_from_node_id(item.id, self), + span: self.span_from_span(sub_span.unwrap()), name: item.ident.to_string(), - qualname: qualname, - declaration: None, - span: sub_span.unwrap(), - scope: self.enclosing_scope(item.id), + qualname, value: make_signature(decl, generics), - visibility: From::from(&item.vis), parent: None, + children: vec![], + decl_id: None, docs: docs_for_attrs(&item.attrs), sig: sig::foreign_item_signature(item, self), - attributes: item.attrs.clone(), + attributes: lower_attributes(item.attrs.clone(), self), })) } ast::ForeignItemKind::Static(ref ty, m) => { let keyword = if m { keywords::Mut } else { keywords::Static }; let sub_span = self.span_utils.sub_span_after_keyword(item.span, keyword); filter!(self.span_utils, sub_span, item.span, None); - Some(Data::VariableData(VariableData { - id: item.id, - kind: VariableKind::Static, + + let id = ::id_from_node_id(item.id, self); + let span = self.span_from_span(sub_span.unwrap()); + + Some(Data::DefData(Def { + kind: DefKind::Static, + id, + span, name: item.ident.to_string(), - qualname: qualname, - span: sub_span.unwrap(), - scope: self.enclosing_scope(item.id), + qualname, + value: ty_to_string(ty), parent: None, - value: String::new(), - type_value: ty_to_string(ty), - visibility: From::from(&item.vis), + children: vec![], + decl_id: None, docs: docs_for_attrs(&item.attrs), sig: sig::foreign_item_signature(item, self), - attributes: item.attrs.clone(), + attributes: lower_attributes(item.attrs.clone(), self), })) } } @@ -172,70 +199,71 @@ pub fn get_item_data(&self, item: &ast::Item) -> Option { let qualname = format!("::{}", self.tcx.node_path_str(item.id)); let sub_span = self.span_utils.sub_span_after_keyword(item.span, keywords::Fn); filter!(self.span_utils, sub_span, item.span, None); - - - Some(Data::FunctionData(FunctionData { - id: item.id, + Some(Data::DefData(Def { + kind: DefKind::Function, + id: id_from_node_id(item.id, self), + span: self.span_from_span(sub_span.unwrap()), name: item.ident.to_string(), - qualname: qualname, - declaration: None, - span: sub_span.unwrap(), - scope: self.enclosing_scope(item.id), + qualname, value: make_signature(decl, generics), - visibility: From::from(&item.vis), parent: None, + children: vec![], + decl_id: None, docs: docs_for_attrs(&item.attrs), sig: sig::item_signature(item, self), - attributes: item.attrs.clone(), + attributes: lower_attributes(item.attrs.clone(), self), })) } - ast::ItemKind::Static(ref typ, mt, ref expr) => { + ast::ItemKind::Static(ref typ, mt, _) => { let qualname = format!("::{}", self.tcx.node_path_str(item.id)); - // If the variable is immutable, save the initialising expression. - let (value, keyword) = match mt { - ast::Mutability::Mutable => (String::from(""), keywords::Mut), - ast::Mutability::Immutable => { - (self.span_utils.snippet(expr.span), keywords::Static) - }, + let keyword = match mt { + ast::Mutability::Mutable => keywords::Mut, + ast::Mutability::Immutable => keywords::Static, }; let sub_span = self.span_utils.sub_span_after_keyword(item.span, keyword); filter!(self.span_utils, sub_span, item.span, None); - Some(Data::VariableData(VariableData { - id: item.id, - kind: VariableKind::Static, + + let id = id_from_node_id(item.id, self); + let span = self.span_from_span(sub_span.unwrap()); + + Some(Data::DefData(Def { + kind: DefKind::Static, + id, + span, name: item.ident.to_string(), - qualname: qualname, - span: sub_span.unwrap(), - scope: self.enclosing_scope(item.id), + qualname, + value: ty_to_string(&typ), parent: None, - value: value, - type_value: ty_to_string(&typ), - visibility: From::from(&item.vis), + children: vec![], + decl_id: None, docs: docs_for_attrs(&item.attrs), sig: sig::item_signature(item, self), - attributes: item.attrs.clone(), + attributes: lower_attributes(item.attrs.clone(), self), })) } - ast::ItemKind::Const(ref typ, ref expr) => { + ast::ItemKind::Const(ref typ, _) => { let qualname = format!("::{}", self.tcx.node_path_str(item.id)); let sub_span = self.span_utils.sub_span_after_keyword(item.span, keywords::Const); filter!(self.span_utils, sub_span, item.span, None); - Some(Data::VariableData(VariableData { - id: item.id, - kind: VariableKind::Const, + + let id = id_from_node_id(item.id, self); + let span = self.span_from_span(sub_span.unwrap()); + + Some(Data::DefData(Def { + kind: DefKind::Const, + id, + span, name: item.ident.to_string(), - qualname: qualname, - span: sub_span.unwrap(), - scope: self.enclosing_scope(item.id), + qualname, + value: ty_to_string(typ), parent: None, - value: self.span_utils.snippet(expr.span), - type_value: ty_to_string(&typ), - visibility: From::from(&item.vis), + children: vec![], + decl_id: None, docs: docs_for_attrs(&item.attrs), sig: sig::item_signature(item, self), - attributes: item.attrs.clone(), + attributes: lower_attributes(item.attrs.clone(), self), })) } ast::ItemKind::Mod(ref m) => { @@ -247,18 +275,19 @@ pub fn get_item_data(&self, item: &ast::Item) -> Option { let sub_span = self.span_utils.sub_span_after_keyword(item.span, keywords::Mod); filter!(self.span_utils, sub_span, item.span, None); - Some(Data::ModData(ModData { - id: item.id, + Some(Data::DefData(Def { + kind: DefKind::Mod, + id: id_from_node_id(item.id, self), name: item.ident.to_string(), - qualname: qualname, - span: sub_span.unwrap(), - scope: self.enclosing_scope(item.id), - filename: filename, - items: m.items.iter().map(|i| i.id).collect(), - visibility: From::from(&item.vis), + qualname, + span: self.span_from_span(sub_span.unwrap()), + value: filename, + parent: None, + children: m.items.iter().map(|i| id_from_node_id(i.id, self)).collect(), + decl_id: None, docs: docs_for_attrs(&item.attrs), sig: sig::item_signature(item, self), - attributes: item.attrs.clone(), + attributes: lower_attributes(item.attrs.clone(), self), })) } ast::ItemKind::Enum(ref def, _) => { @@ -270,61 +299,47 @@ pub fn get_item_data(&self, item: &ast::Item) -> Option { .map(|v| v.node.name.to_string()) .collect::>() .join(", "); - let val = format!("{}::{{{}}}", name, variants_str); - Some(Data::EnumData(EnumData { - id: item.id, - name: name, - value: val, - span: sub_span.unwrap(), - qualname: qualname, - scope: self.enclosing_scope(item.id), - variants: def.variants.iter().map(|v| v.node.data.id()).collect(), - visibility: From::from(&item.vis), + let value = format!("{}::{{{}}}", name, variants_str); + Some(Data::DefData(Def { + kind: DefKind::Enum, + id: id_from_node_id(item.id, self), + span: self.span_from_span(sub_span.unwrap()), + name, + qualname, + value, + parent: None, + children: def.variants + .iter() + .map(|v| id_from_node_id(v.node.data.id(), self)) + .collect(), + decl_id: None, docs: docs_for_attrs(&item.attrs), sig: sig::item_signature(item, self), - attributes: item.attrs.clone(), + attributes: lower_attributes(item.attrs.to_owned(), self), })) } ast::ItemKind::Impl(.., ref trait_ref, ref typ, _) => { - let mut type_data = None; - let sub_span; - - let parent = self.enclosing_scope(item.id); - - match typ.node { + if let ast::TyKind::Path(None, ref path) = typ.node { // Common case impl for a struct or something basic. - ast::TyKind::Path(None, ref path) => { - if generated_code(path.span) { - return None; - } - sub_span = self.span_utils.sub_span_for_type_name(path.span); - type_data = self.lookup_ref_id(typ.id).map(|id| { - TypeRefData { - span: sub_span.unwrap(), - scope: parent, - ref_id: Some(id), - qualname: String::new() // FIXME: generate the real qualname - } - }); - } - _ => { - // Less useful case, impl for a compound type. - let span = typ.span; - sub_span = self.span_utils.sub_span_for_type_name(span).or(Some(span)); + if generated_code(path.span) { + return None; } + let sub_span = self.span_utils.sub_span_for_type_name(path.span); + filter!(self.span_utils, sub_span, typ.span, None); + + 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()), + 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()), + })) + } else { + None } - - let trait_data = trait_ref.as_ref() - .and_then(|tr| self.get_trait_ref_data(tr, parent)); - - filter!(self.span_utils, sub_span, typ.span, None); - Some(Data::ImplData(ImplData2 { - id: item.id, - span: sub_span.unwrap(), - scope: parent, - trait_ref: trait_data, - self_ref: type_data, - })) } _ => { // FIXME @@ -336,7 +351,7 @@ pub fn get_item_data(&self, item: &ast::Item) -> Option { pub fn get_field_data(&self, field: &ast::StructField, scope: NodeId) - -> Option { + -> Option { if let Some(ident) = field.ident { let name = ident.to_string(); let qualname = format!("::{}::{}", self.tcx.node_path_str(scope), ident); @@ -345,20 +360,23 @@ pub fn get_field_data(&self, let def_id = self.tcx.hir.local_def_id(field.id); let typ = self.tcx.type_of(def_id).to_string(); - Some(VariableData { - id: field.id, - kind: VariableKind::Field, - name: name, - qualname: qualname, - span: sub_span.unwrap(), - scope: scope, - parent: Some(make_def_id(scope, &self.tcx.hir)), - value: "".to_owned(), - type_value: typ, - visibility: From::from(&field.vis), + + let id = id_from_node_id(field.id, self); + let span = self.span_from_span(sub_span.unwrap()); + + Some(Def { + kind: DefKind::Field, + id, + span, + name, + qualname, + value: typ, + parent: Some(id_from_node_id(scope, self)), + children: vec![], + decl_id: None, docs: docs_for_attrs(&field.attrs), sig: sig::field_signature(field, self), - attributes: field.attrs.clone(), + attributes: lower_attributes(field.attrs.clone(), self), }) } else { None @@ -371,10 +389,10 @@ pub fn get_method_data(&self, id: ast::NodeId, name: ast::Name, span: Span) - -> Option { + -> Option { // The qualname for a method is the trait name or name of the struct in an impl in // which the method is declared in, followed by the method's name. - let (qualname, parent_scope, decl_id, vis, docs, attributes) = + let (qualname, parent_scope, decl_id, docs, attributes) = match self.tcx.impl_of_method(self.tcx.hir.local_def_id(id)) { Some(impl_id) => match self.tcx.hir.get_if_local(impl_id) { Some(Node::NodeItem(item)) => { @@ -383,7 +401,7 @@ pub fn get_method_data(&self, let mut result = String::from("<"); result.push_str(&self.tcx.hir.node_to_pretty_string(ty.id)); - let trait_id = self.tcx.trait_id_of_impl(impl_id); + let mut trait_id = self.tcx.trait_id_of_impl(impl_id); let mut decl_id = None; if let Some(def_id) = trait_id { result.push_str(" as "); @@ -391,11 +409,16 @@ pub fn get_method_data(&self, self.tcx.associated_items(def_id) .find(|item| item.name == name) .map(|item| decl_id = Some(item.def_id)); + } else { + if let Some(NodeItem(item)) = self.tcx.hir.find(id) { + if let hir::ItemImpl(_, _, _, _, _, ref ty, _) = item.node { + trait_id = self.lookup_ref_id(ty.id); + } + } } result.push_str(">"); (result, trait_id, decl_id, - From::from(&item.vis), docs_for_attrs(&item.attrs), item.attrs.to_vec()) } @@ -421,7 +444,6 @@ pub fn get_method_data(&self, Some(Node::NodeItem(item)) => { (format!("::{}", self.tcx.item_path_str(def_id)), Some(def_id), None, - From::from(&item.vis), docs_for_attrs(&item.attrs), item.attrs.to_vec()) } @@ -449,27 +471,26 @@ pub fn get_method_data(&self, let sub_span = self.span_utils.sub_span_after_keyword(span, keywords::Fn); filter!(self.span_utils, sub_span, span, None); - Some(FunctionData { - id: id, + Some(Def { + kind: DefKind::Method, + id: id_from_node_id(id, self), + span: self.span_from_span(sub_span.unwrap()), name: name.to_string(), - qualname: qualname, - declaration: decl_id, - span: sub_span.unwrap(), - scope: self.enclosing_scope(id), + qualname, // FIXME you get better data here by using the visitor. value: String::new(), - visibility: vis, - parent: parent_scope, - docs: docs, + parent: parent_scope.map(|id| id_from_def_id(id)), + children: vec![], + decl_id: decl_id.map(|id| id_from_def_id(id)), + docs, sig: None, - attributes: attributes, + attributes: lower_attributes(attributes, self), }) } pub fn get_trait_ref_data(&self, - trait_ref: &ast::TraitRef, - parent: NodeId) - -> Option { + trait_ref: &ast::TraitRef) + -> Option { self.lookup_ref_id(trait_ref.ref_id).and_then(|def_id| { let span = trait_ref.path.span; if generated_code(span) { @@ -477,11 +498,11 @@ pub fn get_trait_ref_data(&self, } let sub_span = self.span_utils.sub_span_for_type_name(span).or(Some(span)); filter!(self.span_utils, sub_span, span, None); - Some(TypeRefData { - span: sub_span.unwrap(), - scope: parent, - ref_id: Some(def_id), - qualname: String::new() // FIXME: generate the real qualname + let span = self.span_from_span(sub_span.unwrap()); + Some(Ref { + kind: RefKind::Type, + span, + ref_id: id_from_def_id(def_id), }) }) } @@ -507,11 +528,11 @@ pub fn get_expr_data(&self, expr: &ast::Expr) -> Option { let f = def.struct_variant().field_named(ident.node.name); let sub_span = self.span_utils.span_for_last_ident(expr.span); filter!(self.span_utils, sub_span, expr.span, None); - return Some(Data::VariableRefData(VariableRefData { - name: ident.node.to_string(), - span: sub_span.unwrap(), - scope: self.enclosing_scope(expr.id), - ref_id: f.did, + let span = self.span_from_span(sub_span.unwrap()); + return Some(Data::RefData(Ref { + kind: RefKind::Variable, + span, + ref_id: id_from_def_id(f.did), })); } _ => { @@ -525,11 +546,11 @@ pub fn get_expr_data(&self, expr: &ast::Expr) -> Option { ty::TyAdt(def, _) if !def.is_enum() => { let sub_span = self.span_utils.span_for_last_ident(path.span); filter!(self.span_utils, sub_span, path.span, None); - Some(Data::TypeRefData(TypeRefData { - span: sub_span.unwrap(), - scope: self.enclosing_scope(expr.id), - ref_id: Some(def.did), - qualname: String::new() // FIXME: generate the real qualname + let span = self.span_from_span(sub_span.unwrap()); + Some(Data::RefData(Ref { + kind: RefKind::Type, + span, + ref_id: id_from_def_id(def.did), })) } _ => { @@ -548,16 +569,15 @@ pub fn get_expr_data(&self, expr: &ast::Expr) -> Option { }; let sub_span = self.span_utils.sub_span_for_meth_name(expr.span); filter!(self.span_utils, sub_span, expr.span, None); - let parent = self.enclosing_scope(expr.id); - Some(Data::MethodCallData(MethodCallData { - span: sub_span.unwrap(), - scope: parent, - ref_id: def_id, - decl_id: decl_id, + let span = self.span_from_span(sub_span.unwrap()); + Some(Data::RefData(Ref { + kind: RefKind::Function, + span, + ref_id: def_id.or(decl_id).map(|id| id_from_def_id(id)).unwrap_or(null_id()), })) } ast::ExprKind::Path(_, ref path) => { - self.get_path_data(expr.id, path) + self.get_path_data(expr.id, path).map(|d| Data::RefData(d)) } _ => { // FIXME @@ -566,7 +586,7 @@ pub fn get_expr_data(&self, expr: &ast::Expr) -> Option { } } - pub fn get_path_def(&self, id: NodeId) -> Def { + pub fn get_path_def(&self, id: NodeId) -> HirDef { match self.tcx.hir.get(id) { Node::NodeTraitRef(tr) => tr.path.def, @@ -582,7 +602,7 @@ pub fn get_path_def(&self, id: NodeId) -> Def { } Node::NodeLocal(&hir::Pat { node: hir::PatKind::Binding(_, def_id, ..), .. }) => { - Def::Local(def_id) + HirDef::Local(def_id) } Node::NodeTy(ty) => { @@ -595,58 +615,58 @@ pub fn get_path_def(&self, id: NodeId) -> Def { for item in self.tcx.associated_items(proj.trait_ref.def_id) { if item.kind == ty::AssociatedKind::Type { if item.name == proj.item_name(self.tcx) { - return Def::AssociatedTy(item.def_id); + return HirDef::AssociatedTy(item.def_id); } } } } - Def::Err + HirDef::Err } } } else { - Def::Err + HirDef::Err } } - _ => Def::Err + _ => HirDef::Err } } - pub fn get_path_data(&self, id: NodeId, path: &ast::Path) -> Option { + pub fn get_path_data(&self, id: NodeId, path: &ast::Path) -> Option { let def = self.get_path_def(id); let sub_span = self.span_utils.span_for_last_ident(path.span); filter!(self.span_utils, sub_span, path.span, None); match def { - Def::Upvar(..) | - Def::Local(..) | - Def::Static(..) | - Def::Const(..) | - Def::AssociatedConst(..) | - Def::StructCtor(..) | - Def::VariantCtor(..) => { - Some(Data::VariableRefData(VariableRefData { - name: self.span_utils.snippet(sub_span.unwrap()), - span: sub_span.unwrap(), - scope: self.enclosing_scope(id), - ref_id: def.def_id(), - })) + HirDef::Upvar(..) | + HirDef::Local(..) | + HirDef::Static(..) | + HirDef::Const(..) | + HirDef::AssociatedConst(..) | + HirDef::StructCtor(..) | + HirDef::VariantCtor(..) => { + let span = self.span_from_span(sub_span.unwrap()); + Some(Ref { + kind: RefKind::Variable, + span, + ref_id: id_from_def_id(def.def_id()), + }) } - Def::Struct(def_id) | - Def::Variant(def_id, ..) | - Def::Union(def_id) | - Def::Enum(def_id) | - Def::TyAlias(def_id) | - Def::AssociatedTy(def_id) | - Def::Trait(def_id) | - Def::TyParam(def_id) => { - Some(Data::TypeRefData(TypeRefData { - span: sub_span.unwrap(), - ref_id: Some(def_id), - scope: self.enclosing_scope(id), - qualname: String::new() // FIXME: generate the real qualname - })) + HirDef::Struct(def_id) | + HirDef::Variant(def_id, ..) | + HirDef::Union(def_id) | + HirDef::Enum(def_id) | + HirDef::TyAlias(def_id) | + HirDef::AssociatedTy(def_id) | + HirDef::Trait(def_id) | + HirDef::TyParam(def_id) => { + let span = self.span_from_span(sub_span.unwrap()); + Some(Ref { + kind: RefKind::Type, + span, + ref_id: id_from_def_id(def_id), + }) } - Def::Method(decl_id) => { + HirDef::Method(decl_id) => { let sub_span = self.span_utils.sub_span_for_meth_name(path.span); filter!(self.span_utils, sub_span, path.span, None); let def_id = if decl_id.is_local() { @@ -657,60 +677,60 @@ pub fn get_path_data(&self, id: NodeId, path: &ast::Path) -> Option { } else { None }; - Some(Data::MethodCallData(MethodCallData { - span: sub_span.unwrap(), - scope: self.enclosing_scope(id), - ref_id: def_id, - decl_id: Some(decl_id), - })) + let span = self.span_from_span(sub_span.unwrap()); + Some(Ref { + kind: RefKind::Function, + span, + ref_id: id_from_def_id(def_id.unwrap_or(decl_id)), + }) } - Def::Fn(def_id) => { - Some(Data::FunctionCallData(FunctionCallData { - ref_id: def_id, - span: sub_span.unwrap(), - scope: self.enclosing_scope(id), - })) + HirDef::Fn(def_id) => { + let span = self.span_from_span(sub_span.unwrap()); + Some(Ref { + kind: RefKind::Function, + span, + ref_id: id_from_def_id(def_id), + }) } - Def::Mod(def_id) => { - Some(Data::ModRefData(ModRefData { - ref_id: Some(def_id), - span: sub_span.unwrap(), - scope: self.enclosing_scope(id), - qualname: String::new() // FIXME: generate the real qualname - })) + HirDef::Mod(def_id) => { + let span = self.span_from_span(sub_span.unwrap()); + Some(Ref { + kind: RefKind::Mod, + span, + ref_id: id_from_def_id(def_id), + }) } - Def::PrimTy(..) | - Def::SelfTy(..) | - Def::Label(..) | - Def::Macro(..) | - Def::GlobalAsm(..) | - Def::Err => None, + HirDef::PrimTy(..) | + HirDef::SelfTy(..) | + HirDef::Label(..) | + HirDef::Macro(..) | + HirDef::GlobalAsm(..) | + HirDef::Err => None, } } pub fn get_field_ref_data(&self, field_ref: &ast::Field, - variant: &ty::VariantDef, - parent: NodeId) - -> Option { + variant: &ty::VariantDef) + -> Option { let f = variant.field_named(field_ref.ident.node.name); // We don't really need a sub-span here, but no harm done let sub_span = self.span_utils.span_for_last_ident(field_ref.ident.span); filter!(self.span_utils, sub_span, field_ref.ident.span, None); - Some(VariableRefData { - name: field_ref.ident.node.to_string(), - span: sub_span.unwrap(), - scope: parent, - ref_id: f.did, + let span = self.span_from_span(sub_span.unwrap()); + Some(Ref { + kind: RefKind::Variable, + span, + ref_id: id_from_def_id(f.did), }) } - /// Attempt to return MacroUseData for any AST node. + /// Attempt to return MacroRef for any AST node. /// /// For a given piece of AST defined by the supplied Span and NodeId, /// returns None if the node is not macro-generated or the span is malformed, - /// else uses the expansion callsite and callee to return some MacroUseData. - pub fn get_macro_use_data(&self, span: Span, id: NodeId) -> Option { + /// else uses the expansion callsite and callee to return some MacroRef. + pub fn get_macro_use_data(&self, span: Span) -> Option { if !generated_code(span) { return None; } @@ -718,6 +738,7 @@ pub fn get_macro_use_data(&self, span: Span, id: NodeId) -> Option // nested expansions and ensure we only generate data for source-visible // macro uses. let callsite = span.source_callsite(); + let callsite_span = self.span_from_span(callsite); let callee = option_try!(span.source_callee()); let callee_span = option_try!(callee.span); @@ -731,34 +752,25 @@ pub fn get_macro_use_data(&self, span: Span, id: NodeId) -> Option // when read in, and no longer correspond to the source. if let Some(mac) = self.tcx.sess.imported_macro_spans.borrow().get(&callee_span) { let &(ref mac_name, mac_span) = mac; - return Some(MacroUseData { - span: callsite, - name: mac_name.clone(), - callee_span: mac_span, - scope: self.enclosing_scope(id), - imported: true, - qualname: String::new()// FIXME: generate the real qualname - }); + let mac_span = self.span_from_span(mac_span); + return Some(MacroRef { + span: callsite_span, + qualname: mac_name.clone(), // FIXME: generate the real qualname + callee_span: mac_span, + }); } - Some(MacroUseData { - span: callsite, - name: callee.name().to_string(), - callee_span: callee_span, - scope: self.enclosing_scope(id), - imported: false, - qualname: String::new() // FIXME: generate the real qualname + let callee_span = self.span_from_span(callee_span); + Some(MacroRef { + span: callsite_span, + qualname: callee.name().to_string(), // FIXME: generate the real qualname + callee_span, }) } - pub fn get_data_for_id(&self, _id: &NodeId) -> Data { - // FIXME - bug!(); - } - fn lookup_ref_id(&self, ref_id: NodeId) -> Option { match self.get_path_def(ref_id) { - Def::PrimTy(_) | Def::SelfTy(..) | Def::Err => None, + HirDef::PrimTy(_) | HirDef::SelfTy(..) | HirDef::Err => None, def => Some(def.def_id()), } } @@ -800,7 +812,7 @@ fn make_signature(decl: &ast::FnDecl, generics: &ast::Generics) -> String { // An AST visitor for collecting paths from patterns. struct PathCollector { // The Row field identifies the kind of pattern. - collected_paths: Vec<(NodeId, ast::Path, ast::Mutability, recorder::Row)>, + collected_paths: Vec<(NodeId, ast::Path, ast::Mutability)>, } impl PathCollector { @@ -814,12 +826,12 @@ fn visit_pat(&mut self, p: &ast::Pat) { match p.node { PatKind::Struct(ref path, ..) => { self.collected_paths.push((p.id, path.clone(), - ast::Mutability::Mutable, recorder::TypeRef)); + ast::Mutability::Mutable)); } PatKind::TupleStruct(ref path, ..) | PatKind::Path(_, ref path) => { self.collected_paths.push((p.id, path.clone(), - ast::Mutability::Mutable, recorder::VarRef)); + ast::Mutability::Mutable)); } PatKind::Ident(bm, ref path1, _) => { debug!("PathCollector, visit ident in pat {}: {:?} {:?}", @@ -835,7 +847,7 @@ fn visit_pat(&mut self, p: &ast::Pat) { }; // collect path for either visit_local or visit_arm let path = ast::Path::from_ident(path1.span, path1.node); - self.collected_paths.push((p.id, path, immut, recorder::VarRef)); + self.collected_paths.push((p.id, path, immut)); } _ => {} } @@ -1032,6 +1044,34 @@ fn id_from_def_id(id: DefId) -> rls_data::Id { } fn id_from_node_id(id: NodeId, scx: &SaveContext) -> rls_data::Id { - let def_id = scx.tcx.hir.local_def_id(id); - id_from_def_id(def_id) + let def_id = scx.tcx.hir.opt_local_def_id(id); + def_id.map(|id| id_from_def_id(id)).unwrap_or_else(null_id) +} + +fn null_id() -> rls_data::Id { + rls_data::Id { + krate: u32::max_value(), + index: u32::max_value(), + } +} + +fn lower_attributes(attrs: Vec, scx: &SaveContext) -> Vec { + attrs.into_iter() + // Only retain real attributes. Doc comments are lowered separately. + .filter(|attr| attr.path != "doc") + .map(|mut attr| { + // Remove the surrounding '#[..]' or '#![..]' of the pretty printed + // attribute. First normalize all inner attribute (#![..]) to outer + // ones (#[..]), then remove the two leading and the one trailing character. + attr.style = ast::AttrStyle::Outer; + let value = pprust::attribute_to_string(&attr); + // This str slicing works correctly, because the leading and trailing characters + // are in the ASCII range and thus exactly one byte each. + let value = value[2..value.len()-1].to_string(); + + rls_data::Attribute { + value: value, + span: scx.span_from_span(attr.span), + } + }).collect() } diff --git a/src/librustc_save_analysis/span_utils.rs b/src/librustc_save_analysis/span_utils.rs index af3efb48090..77cde33e962 100644 --- a/src/librustc_save_analysis/span_utils.rs +++ b/src/librustc_save_analysis/span_utils.rs @@ -20,7 +20,6 @@ use syntax::parse::lexer::{self, StringReader}; use syntax::parse::token::{self, Token}; use syntax::symbol::keywords; -use syntax::tokenstream::TokenTree; use syntax_pos::*; #[derive(Clone)] @@ -277,45 +276,6 @@ pub fn spans_with_brackets(&self, span: Span, nesting: isize, limit: isize) -> V } } - /// `span` must be the span for an item such as a function or struct. This - /// function returns the program text from the start of the span until the - /// end of the 'signature' part, that is up to, but not including an opening - /// brace or semicolon. - pub fn signature_string_for_span(&self, span: Span) -> String { - let mut toks = self.retokenise_span(span); - toks.real_token(); - let mut toks = toks.parse_all_token_trees().unwrap().trees(); - let mut prev = toks.next().unwrap(); - - let first_span = prev.span(); - let mut angle_count = 0; - for tok in toks { - if let TokenTree::Token(_, ref tok) = prev { - angle_count += match *tok { - token::Eof => { break; } - token::Lt => 1, - token::Gt => -1, - token::BinOp(token::Shl) => 2, - token::BinOp(token::Shr) => -2, - _ => 0, - }; - } - if angle_count > 0 { - prev = tok; - continue; - } - if let TokenTree::Token(_, token::Semi) = tok { - return self.snippet(first_span.to(prev.span())); - } else if let TokenTree::Delimited(_, ref d) = tok { - if d.delim == token::Brace { - return self.snippet(first_span.to(prev.span())); - } - } - prev = tok; - } - self.snippet(span) - } - pub fn sub_span_before_token(&self, span: Span, tok: Token) -> Option { let mut toks = self.retokenise_span(span); let mut prev = toks.real_token(); @@ -385,57 +345,44 @@ pub fn spans_for_ty_params(&self, span: Span, number: isize) -> Vec { self.spans_with_brackets(span, 1, number) } - pub fn report_span_err(&self, kind: &str, span: Span) { - let loc = self.sess.codemap().lookup_char_pos(span.lo); - info!("({}) Could not find sub_span in `{}` in {}, line {}", - kind, - self.snippet(span), - loc.file.name, - loc.line); - self.err_count.set(self.err_count.get() + 1); - if self.err_count.get() > 1000 { - bug!("span errors reached 1000, giving up"); - } - } - - // Return the name for a macro definition (identifier after first `!`) - pub fn span_for_macro_def_name(&self, span: Span) -> Option { - let mut toks = self.retokenise_span(span); - loop { - let ts = toks.real_token(); - if ts.tok == token::Eof { - return None; - } - if ts.tok == token::Not { - let ts = toks.real_token(); - if ts.tok.is_ident() { - return Some(ts.sp); - } else { - return None; - } - } - } - } - - // Return the name for a macro use (identifier before first `!`). - pub fn span_for_macro_use_name(&self, span:Span) -> Option { - let mut toks = self.retokenise_span(span); - let mut prev = toks.real_token(); - loop { - if prev.tok == token::Eof { - return None; - } - let ts = toks.real_token(); - if ts.tok == token::Not { - if prev.tok.is_ident() { - return Some(prev.sp); - } else { - return None; - } - } - prev = ts; - } - } + // // Return the name for a macro definition (identifier after first `!`) + // pub fn span_for_macro_def_name(&self, span: Span) -> Option { + // let mut toks = self.retokenise_span(span); + // loop { + // let ts = toks.real_token(); + // if ts.tok == token::Eof { + // return None; + // } + // if ts.tok == token::Not { + // let ts = toks.real_token(); + // if ts.tok.is_ident() { + // return Some(ts.sp); + // } else { + // return None; + // } + // } + // } + // } + + // // Return the name for a macro use (identifier before first `!`). + // pub fn span_for_macro_use_name(&self, span:Span) -> Option { + // let mut toks = self.retokenise_span(span); + // let mut prev = toks.real_token(); + // loop { + // if prev.tok == token::Eof { + // return None; + // } + // let ts = toks.real_token(); + // if ts.tok == token::Not { + // if prev.tok.is_ident() { + // return Some(prev.sp); + // } else { + // return None; + // } + // } + // prev = ts; + // } + // } /// Return true if the span is generated code, and /// it is not a subspan of the root callsite. -- 2.44.0