提交 8a2857e6 编写于 作者: N Nick Cameron

Remove intermediate forms and some other refactoring

上级 9a471606
// 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,
}
// 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) {}
}
此差异已折叠。
......@@ -12,12 +12,9 @@
use rustc_serialize::json::as_json;
use external_data::*;
use data::{VariableKind, Visibility};
use dump::Dump;
use id_from_def_id;
use Dump;
use rls_data::{Analysis, Import, ImportKind, Def, DefKind, CratePreludeData, Format};
use rls_data::{Analysis, Import, Def, CratePreludeData, Format, Relation};
// A dumper to dump a restricted set of JSON information, designed for use with
......@@ -47,306 +44,23 @@ fn drop(&mut self) {
}
}
macro_rules! impl_fn {
($fn_name: ident, $data_type: ident, $bucket: ident) => {
fn $fn_name(&mut self, data: $data_type) {
if let Some(datum) = data.into() {
self.result.$bucket.push(datum);
}
}
}
}
impl<'b, W: Write + 'b> Dump for JsonApiDumper<'b, W> {
fn crate_prelude(&mut self, data: CratePreludeData) {
self.result.prelude = Some(data)
}
impl_fn!(use_data, UseData, imports);
impl_fn!(use_glob, UseGlobData, imports);
impl_fn!(enum_data, EnumData, defs);
impl_fn!(tuple_variant, TupleVariantData, defs);
impl_fn!(struct_variant, StructVariantData, defs);
impl_fn!(struct_data, StructData, defs);
impl_fn!(trait_data, TraitData, defs);
impl_fn!(function, FunctionData, defs);
impl_fn!(method, MethodData, defs);
impl_fn!(macro_data, MacroData, defs);
impl_fn!(mod_data, ModData, defs);
impl_fn!(typedef, TypeDefData, defs);
impl_fn!(variable, VariableData, defs);
fn impl_data(&mut self, data: ImplData) {
if data.self_ref.is_some() {
self.result.relations.push(data.into());
}
}
fn inheritance(&mut self, data: InheritanceData) {
self.result.relations.push(data.into());
fn dump_relation(&mut self, data: Relation) {
self.result.relations.push(data);
}
}
// FIXME methods. The defs have information about possible overriding and the
// refs have decl information (e.g., a trait method where we know the required
// method, but not the supplied method). In both cases, we are currently
// ignoring it.
impl Into<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);
}
}
}
......@@ -12,14 +12,11 @@
use rustc_serialize::json::as_json;
use rls_data::{self, Id, Analysis, Import, ImportKind, Def, DefKind, Ref, RefKind, MacroRef,
Relation, RelationKind, CratePreludeData};
use rls_data::{self, Analysis, Import, Def, DefKind, Ref, RefKind, MacroRef,
Relation, CratePreludeData};
use rls_span::{Column, Row};
use external_data::*;
use data::VariableKind;
use dump::Dump;
use id_from_def_id;
use Dump;
pub struct JsonDumper<O: DumpOutput> {
result: Analysis,
......@@ -70,71 +67,35 @@ fn drop(&mut self) {
}
}
macro_rules! impl_fn {
($fn_name: ident, $data_type: ident, $bucket: ident) => {
fn $fn_name(&mut self, data: $data_type) {
self.result.$bucket.push(data.into());
}
}
}
impl<'b, O: DumpOutput + 'b> Dump for JsonDumper<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),
......@@ -143,330 +104,10 @@ fn mod_data(&mut self, data: ModData) {
column_end: Column::new_one_indexed(1),
}
}
self.result.defs.push(def);
}
fn impl_data(&mut self, data: ImplData) {
if data.self_ref.is_some() {
self.result.relations.push(data.into());
}
}
fn inheritance(&mut self, data: InheritanceData) {
self.result.relations.push(data.into());
}
}
// FIXME do we want to change ExternalData to this mode? It will break DXR.
// FIXME methods. The defs have information about possible overriding and the
// refs have decl information (e.g., a trait method where we know the required
// method, but not the supplied method). In both cases, we are currently
// ignoring it.
impl Into<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);
}
}
此差异已折叠。
......@@ -20,7 +20,6 @@
use syntax::parse::lexer::{self, StringReader};
use syntax::parse::token::{self, Token};
use syntax::symbol::keywords;
use syntax::tokenstream::TokenTree;
use syntax_pos::*;
#[derive(Clone)]
......@@ -277,45 +276,6 @@ pub fn spans_with_brackets(&self, span: Span, nesting: isize, limit: isize) -> V
}
}
/// `span` must be the span for an item such as a function or struct. This
/// function returns the program text from the start of the span until the
/// end of the 'signature' part, that is up to, but not including an opening
/// brace or semicolon.
pub fn signature_string_for_span(&self, span: Span) -> String {
let mut toks = self.retokenise_span(span);
toks.real_token();
let mut toks = toks.parse_all_token_trees().unwrap().trees();
let mut prev = toks.next().unwrap();
let first_span = prev.span();
let mut angle_count = 0;
for tok in toks {
if let TokenTree::Token(_, ref tok) = prev {
angle_count += match *tok {
token::Eof => { break; }
token::Lt => 1,
token::Gt => -1,
token::BinOp(token::Shl) => 2,
token::BinOp(token::Shr) => -2,
_ => 0,
};
}
if angle_count > 0 {
prev = tok;
continue;
}
if let TokenTree::Token(_, token::Semi) = tok {
return self.snippet(first_span.to(prev.span()));
} else if let TokenTree::Delimited(_, ref d) = tok {
if d.delim == token::Brace {
return self.snippet(first_span.to(prev.span()));
}
}
prev = tok;
}
self.snippet(span)
}
pub fn sub_span_before_token(&self, span: Span, tok: Token) -> Option<Span> {
let mut toks = self.retokenise_span(span);
let mut prev = toks.real_token();
......@@ -385,57 +345,44 @@ pub fn spans_for_ty_params(&self, span: Span, number: isize) -> Vec<Span> {
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.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册