+++ /dev/null
-// 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! 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<ExternalCrateData>,
- 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<NodeId>,
- pub visibility: Visibility,
- pub docs: String,
- pub sig: Option<Signature>,
- pub attributes: Vec<Attribute>,
-}
-
-/// 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<DefId>,
- pub span: Span,
- pub scope: NodeId,
- pub value: String,
- pub visibility: Visibility,
- pub parent: Option<DefId>,
- pub docs: String,
- pub sig: Option<Signature>,
- pub attributes: Vec<Attribute>,
-}
-
-/// 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<DefId>,
- pub self_ref: Option<DefId>,
-}
-
-#[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<TypeRefData>,
- pub self_ref: Option<TypeRefData>,
-}
-
-#[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<DefId>,
- pub decl_id: Option<DefId>,
-}
-
-/// 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<DefId>,
- pub parent: Option<DefId>,
- pub visibility: Visibility,
- pub docs: String,
- pub sig: Option<Signature>,
- pub attributes: Vec<Attribute>,
-}
-
-/// 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<NodeId>,
- pub visibility: Visibility,
- pub docs: String,
- pub sig: Option<Signature>,
- pub attributes: Vec<Attribute>,
-}
-
-/// Data for a reference to a module.
-#[derive(Debug)]
-pub struct ModRefData {
- pub span: Span,
- pub scope: NodeId,
- pub ref_id: Option<DefId>,
- 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<NodeId>,
- pub visibility: Visibility,
- pub docs: String,
- pub sig: Option<Signature>,
- pub attributes: Vec<Attribute>,
-}
-
-#[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<DefId>,
- pub docs: String,
- pub sig: Option<Signature>,
- pub attributes: Vec<Attribute>,
-}
-
-#[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<NodeId>,
- pub visibility: Visibility,
- pub docs: String,
- pub sig: Option<Signature>,
- pub attributes: Vec<Attribute>,
-}
-
-#[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<DefId>,
- pub docs: String,
- pub sig: Option<Signature>,
- pub attributes: Vec<Attribute>,
-}
-
-/// 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<DefId>,
- pub docs: String,
- pub sig: Option<Signature>,
- pub attributes: Vec<Attribute>,
-}
-
-/// 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<DefId>,
- pub qualname: String,
-}
-
-#[derive(Debug)]
-pub struct UseData {
- pub id: NodeId,
- pub span: Span,
- pub name: String,
- pub mod_id: Option<DefId>,
- pub scope: NodeId,
- pub visibility: Visibility,
-}
-
-#[derive(Debug)]
-pub struct UseGlobData {
- pub id: NodeId,
- pub span: Span,
- pub names: Vec<String>,
- 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<DefId>,
- pub value: String,
- pub type_value: String,
- pub visibility: Visibility,
- pub docs: String,
- pub sig: Option<Signature>,
- pub attributes: Vec<Attribute>,
-}
-
-#[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,
-}
+++ /dev/null
-// 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use 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) {}
-}
// 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
//! 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};
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) => {
// 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<Span>,
- mac_uses: HashSet<Span>,
+ // mac_defs: HashSet<Span>,
}
impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
dumper: dumper,
span: span_utils.clone(),
cur_scope: CRATE_NODE_ID,
- mac_defs: HashSet::new(),
- mac_uses: HashSet::new(),
+ // mac_defs: HashSet::new(),
}
}
}
}
+ 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| {
}
});
- // 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("<no source>".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.
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(),
+ });
}
}
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(),
+ });
}
}
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<DefId> {
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()),
}
}
ref_id: NodeId,
span: Span,
sub_span: Option<Span>,
- 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);
// 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![],
+ });
}
}
}
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() {
});
}
- // 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
}
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);
}
}
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);
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 {
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);
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
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()
.unwrap_or(i.to_string()))
.collect::<Vec<_>>()
.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() {
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();
.unwrap_or(i.to_string()))
.collect::<Vec<_>>()
.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::<Vec<_>>()
- .join(", "));
- val.push(')');
+ value.push('(');
+ value.push_str(&fields.iter()
+ .map(|f| ty_to_string(&f.ty))
+ .collect::<Vec<_>>()
+ .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),
+ });
}
}
}
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,
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));
}
}
}
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
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),
+ });
}
}
}
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<recorder::Row>) {
+ 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;
}
};
- match path_data {
- Data::VariableRefData(vrd) => {
- // 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),
_ => {}
}
}
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)
fn process_method_call(&mut self, ex: &'l ast::Expr, args: &'l [P<ast::Expr>]) {
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);
}
}
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);
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(),
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![],
+ });
}
}
}
/// 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,
&ty,
expr.as_ref().map(|e| &**e),
trait_id,
- Visibility::Public,
+ ast::Visibility::Public,
&trait_item.attrs);
}
ast::TraitItemKind::Method(ref sig, ref body) => {
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) => {
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 {
}
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,
&ty,
Some(expr),
impl_id,
- From::from(&impl_item.vis),
+ impl_item.vis.clone(),
&impl_item.attrs);
}
ast::ImplItemKind::Method(ref sig, ref body) => {
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) => {
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 {
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,
};
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);
}
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);
}
}
}
}
}
- 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) =>
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);
}
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) {
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),
+ });
}
}
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);
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);
}
}
}
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(..) => {}
}
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);
}
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()
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);
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 {
}
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);
+++ /dev/null
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use 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<ast::Attribute> {
- type Target = Vec<Attribute>;
-
- fn lower(self, tcx: TyCtxt) -> Vec<Attribute> {
- 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<DefId>,
- pub visibility: Visibility,
- pub docs: String,
- pub sig: Option<Signature>,
- pub attributes: Vec<Attribute>,
-}
-
-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<DefId>,
- pub span: SpanData,
- pub scope: DefId,
- pub value: String,
- pub visibility: Visibility,
- pub parent: Option<DefId>,
- pub docs: String,
- pub sig: Option<Signature>,
- pub attributes: Vec<Attribute>,
-}
-
-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<DefId>,
- pub self_ref: Option<DefId>,
-}
-
-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<DefId>,
- pub decl_id: Option<DefId>,
-}
-
-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<DefId>,
- pub visibility: Visibility,
- pub parent: Option<DefId>,
- pub docs: String,
- pub sig: Option<Signature>,
- pub attributes: Vec<Attribute>,
-}
-
-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<DefId>,
- pub visibility: Visibility,
- pub docs: String,
- pub sig: Option<Signature>,
- pub attributes: Vec<Attribute>,
-}
-
-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<DefId>,
- 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<DefId>,
- pub visibility: Visibility,
- pub docs: String,
- pub sig: Option<Signature>,
- pub attributes: Vec<Attribute>,
-}
-
-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<DefId>,
- pub docs: String,
- pub sig: Option<Signature>,
- pub attributes: Vec<Attribute>,
-}
-
-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<DefId>,
- pub visibility: Visibility,
- pub docs: String,
- pub sig: Option<Signature>,
- pub attributes: Vec<Attribute>,
-}
-
-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<DefId>,
- pub docs: String,
- pub sig: Option<Signature>,
- pub attributes: Vec<Attribute>,
-}
-
-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<DefId>,
- pub docs: String,
- pub sig: Option<Signature>,
- pub attributes: Vec<Attribute>,
-}
-
-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<DefId>,
- 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<DefId>,
- 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<String>,
- 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<DefId>,
- pub visibility: Visibility,
- pub docs: String,
- pub sig: Option<Signature>,
- pub attributes: Vec<Attribute>,
-}
-
-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,
- }
- }
-}
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
}
}
-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<Option<Import>> for UseData {
- fn into(self) -> Option<Import> {
- 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<Option<Import>> for UseGlobData {
- fn into(self) -> Option<Import> {
- 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<Option<Def>> for EnumData {
- fn into(self) -> Option<Def> {
- 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<Option<Def>> for TupleVariantData {
- fn into(self) -> Option<Def> {
- 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<Option<Def>> for StructVariantData {
- fn into(self) -> Option<Def> {
- 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<Option<Def>> for StructData {
- fn into(self) -> Option<Def> {
- 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<Option<Def>> for TraitData {
- fn into(self) -> Option<Def> {
- 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<Option<Def>> for FunctionData {
- fn into(self) -> Option<Def> {
- 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<Option<Def>> for MethodData {
- fn into(self) -> Option<Def> {
- 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<Option<Def>> for MacroData {
- fn into(self) -> Option<Def> {
- 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<Option<Def>> for ModData {
- fn into(self) -> Option<Def> {
- 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<Option<Def>> for TypeDefData {
- fn into(self) -> Option<Def> {
- 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<Option<Def>> for VariableData {
- fn into(self) -> Option<Def> {
- 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);
}
}
}
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<O: DumpOutput> {
result: Analysis,
}
}
-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<O> {
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),
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<Import> for ExternCrateData {
- fn into(self) -> Import {
- Import {
- kind: ImportKind::ExternCrate,
- ref_id: None,
- span: self.span,
- name: self.name,
- value: String::new(),
- }
- }
-}
-impl Into<Import> 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<Import> 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<Def> 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<Def> 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<Def> 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<Def> 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<Def> 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<Def> 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<Def> 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<Def> 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<Def> 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<Def> 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<Ref> for FunctionRefData {
- fn into(self) -> Ref {
- Ref {
- kind: RefKind::Function,
- span: self.span,
- ref_id: id_from_def_id(self.ref_id),
- }
- }
-}
-impl Into<Ref> for FunctionCallData {
- fn into(self) -> Ref {
- Ref {
- kind: RefKind::Function,
- span: self.span,
- ref_id: id_from_def_id(self.ref_id),
- }
- }
-}
-impl Into<Ref> 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<Ref> 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<Ref> 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<Ref> for VariableRefData {
- fn into(self) -> Ref {
- Ref {
- kind: RefKind::Variable,
- span: self.span,
- ref_id: id_from_def_id(self.ref_id),
- }
- }
-}
-
-impl Into<MacroRef> for MacroUseData {
- fn into(self) -> MacroRef {
- MacroRef {
- span: self.span,
- qualname: self.qualname,
- callee_span: self.callee_span.into(),
- }
- }
-}
-
-impl Into<Relation> 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<Relation> 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);
}
}
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;
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>,
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<CrateData> {
+ pub fn get_external_crates(&self) -> Vec<ExternalCrateData> {
let mut result = Vec::new();
for n in self.tcx.sess.cstore.crates() {
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),
});
}
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),
}))
}
}
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("<mutable>"), 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) => {
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, _) => {
.map(|v| v.node.name.to_string())
.collect::<Vec<_>>()
.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
pub fn get_field_data(&self,
field: &ast::StructField,
scope: NodeId)
- -> Option<VariableData> {
+ -> Option<Def> {
if let Some(ident) = field.ident {
let name = ident.to_string();
let qualname = format!("::{}::{}", self.tcx.node_path_str(scope), ident);
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
id: ast::NodeId,
name: ast::Name,
span: Span)
- -> Option<FunctionData> {
+ -> Option<Def> {
// 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)) => {
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 ");
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())
}
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())
}
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<TypeRefData> {
+ trait_ref: &ast::TraitRef)
+ -> Option<Ref> {
self.lookup_ref_id(trait_ref.ref_id).and_then(|def_id| {
let span = trait_ref.path.span;
if generated_code(span) {
}
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),
})
})
}
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),
}));
}
_ => {
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),
}))
}
_ => {
};
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
}
}
- 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,
}
Node::NodeLocal(&hir::Pat { node: hir::PatKind::Binding(_, def_id, ..), .. }) => {
- Def::Local(def_id)
+ HirDef::Local(def_id)
}
Node::NodeTy(ty) => {
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<Data> {
+ pub fn get_path_data(&self, id: NodeId, path: &ast::Path) -> Option<Ref> {
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() {
} 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<VariableRefData> {
+ variant: &ty::VariantDef)
+ -> Option<Ref> {
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<MacroUseData> {
+ /// else uses the expansion callsite and callee to return some MacroRef.
+ pub fn get_macro_use_data(&self, span: Span) -> Option<MacroRef> {
if !generated_code(span) {
return None;
}
// 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);
// 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<DefId> {
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()),
}
}
// 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 {
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 {}: {:?} {:?}",
};
// 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));
}
_ => {}
}
}
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<Attribute>, scx: &SaveContext) -> Vec<rls_data::Attribute> {
+ 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()
}
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)]
}
}
- /// `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<Span> {
let mut toks = self.retokenise_span(span);
let mut prev = toks.real_token();
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<Span> {
- 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<Span> {
- 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<Span> {
+ // 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<Span> {
+ // 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.