2014-02-05 17:31:33 +13:00
|
|
|
// 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.
|
|
|
|
|
2014-11-06 00:05:53 -08:00
|
|
|
pub use self::Row::*;
|
|
|
|
|
2014-11-15 20:30:33 -05:00
|
|
|
use super::escape;
|
|
|
|
use super::span_utils::SpanUtils;
|
2014-02-05 17:31:33 +13:00
|
|
|
|
2015-02-26 21:00:43 -08:00
|
|
|
use std::io::Write;
|
2014-02-05 17:31:33 +13:00
|
|
|
|
|
|
|
use syntax::ast;
|
|
|
|
use syntax::ast::{NodeId,DefId};
|
|
|
|
use syntax::codemap::*;
|
|
|
|
|
2015-01-14 22:24:09 +13:00
|
|
|
const ZERO_DEF_ID: DefId = DefId { node: 0, krate: 0 };
|
|
|
|
|
2014-02-05 17:31:33 +13:00
|
|
|
pub struct Recorder {
|
|
|
|
// output file
|
2015-02-26 21:00:43 -08:00
|
|
|
pub out: Box<Write+'static>,
|
2014-02-05 17:31:33 +13:00
|
|
|
pub dump_spans: bool,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Recorder {
|
|
|
|
pub fn record(&mut self, info: &str) {
|
|
|
|
match write!(self.out, "{}", info) {
|
|
|
|
Err(_) => error!("Error writing output '{}'", info),
|
|
|
|
_ => (),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn dump_span(&mut self,
|
|
|
|
su: SpanUtils,
|
|
|
|
kind: &str,
|
|
|
|
span: Span,
|
|
|
|
_sub_span: Option<Span>) {
|
|
|
|
assert!(self.dump_spans);
|
|
|
|
let result = format!("span,kind,{},{},text,\"{}\"\n",
|
|
|
|
kind, su.extent_str(span), escape(su.snippet(span)));
|
2015-02-18 14:48:57 -05:00
|
|
|
self.record(&result[..]);
|
2014-02-05 17:31:33 +13:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct FmtStrs<'a> {
|
|
|
|
pub recorder: Box<Recorder>,
|
|
|
|
span: SpanUtils<'a>,
|
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! s { ($e:expr) => { format!("{}", $e) }}
|
|
|
|
macro_rules! svec {
|
|
|
|
($($e:expr),*) => ({
|
|
|
|
// leading _ to allow empty construction without a warning.
|
|
|
|
let mut _temp = ::std::vec::Vec::new();
|
|
|
|
$(_temp.push(s!($e));)*
|
|
|
|
_temp
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2015-05-11 08:35:08 +12:00
|
|
|
// FIXME recorder should operate on super::Data, rather than lots of ad hoc
|
|
|
|
// data.
|
|
|
|
|
2015-03-30 09:38:44 -04:00
|
|
|
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
2014-02-05 17:31:33 +13:00
|
|
|
pub enum Row {
|
|
|
|
Variable,
|
|
|
|
Enum,
|
|
|
|
Variant,
|
|
|
|
VariantStruct,
|
|
|
|
Function,
|
|
|
|
MethodDecl,
|
|
|
|
Struct,
|
|
|
|
Trait,
|
|
|
|
Impl,
|
|
|
|
Module,
|
|
|
|
UseAlias,
|
2014-11-23 22:29:41 +13:00
|
|
|
UseGlob,
|
2014-02-05 17:31:33 +13:00
|
|
|
ExternCrate,
|
|
|
|
Inheritance,
|
|
|
|
MethodCall,
|
|
|
|
Typedef,
|
|
|
|
ExternalCrate,
|
|
|
|
Crate,
|
|
|
|
FnCall,
|
|
|
|
ModRef,
|
|
|
|
VarRef,
|
|
|
|
TypeRef,
|
|
|
|
FnRef,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> FmtStrs<'a> {
|
2015-01-16 22:57:53 +13:00
|
|
|
pub fn new(rec: Box<Recorder>, span: SpanUtils<'a>) -> FmtStrs<'a> {
|
2014-02-05 17:31:33 +13:00
|
|
|
FmtStrs {
|
|
|
|
recorder: rec,
|
|
|
|
span: span,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// A map from kind of item to a tuple of
|
|
|
|
// a string representation of the name
|
|
|
|
// a vector of field names
|
|
|
|
// whether this kind requires a span
|
|
|
|
// whether dump_spans should dump for this kind
|
|
|
|
fn lookup_row(r: Row) -> (&'static str, Vec<&'static str>, bool, bool) {
|
|
|
|
match r {
|
|
|
|
Variable => ("variable",
|
|
|
|
vec!("id","name","qualname","value","type","scopeid"),
|
|
|
|
true, true),
|
2014-11-23 14:57:26 +13:00
|
|
|
Enum => ("enum", vec!("id","qualname","scopeid","value"), true, true),
|
2014-11-23 14:39:59 +13:00
|
|
|
Variant => ("variant",
|
|
|
|
vec!("id","name","qualname","type","value","scopeid"),
|
|
|
|
true, true),
|
2014-02-05 17:31:33 +13:00
|
|
|
VariantStruct => ("variant_struct",
|
2014-11-23 14:39:59 +13:00
|
|
|
vec!("id","ctor_id","qualname","type","value","scopeid"),
|
|
|
|
true, true),
|
|
|
|
Function => ("function",
|
|
|
|
vec!("id","qualname","declid","declidcrate","scopeid"),
|
2014-02-05 17:31:33 +13:00
|
|
|
true, true),
|
|
|
|
MethodDecl => ("method_decl", vec!("id","qualname","scopeid"), true, true),
|
2014-11-23 14:57:26 +13:00
|
|
|
Struct => ("struct", vec!("id","ctor_id","qualname","scopeid","value"), true, true),
|
|
|
|
Trait => ("trait", vec!("id","qualname","scopeid","value"), true, true),
|
2015-01-14 22:24:09 +13:00
|
|
|
Impl => ("impl",
|
|
|
|
vec!("id","refid","refidcrate","traitid","traitidcrate","scopeid"),
|
|
|
|
true, true),
|
2014-02-05 17:31:33 +13:00
|
|
|
Module => ("module", vec!("id","qualname","scopeid","def_file"), true, false),
|
|
|
|
UseAlias => ("use_alias",
|
|
|
|
vec!("id","refid","refidcrate","name","scopeid"),
|
|
|
|
true, true),
|
2014-11-23 22:29:41 +13:00
|
|
|
UseGlob => ("use_glob", vec!("id","value","scopeid"), true, true),
|
2014-02-05 17:31:33 +13:00
|
|
|
ExternCrate => ("extern_crate",
|
|
|
|
vec!("id","name","location","crate","scopeid"),
|
|
|
|
true, true),
|
|
|
|
Inheritance => ("inheritance",
|
|
|
|
vec!("base","basecrate","derived","derivedcrate"),
|
|
|
|
true, false),
|
|
|
|
MethodCall => ("method_call",
|
|
|
|
vec!("refid","refidcrate","declid","declidcrate","scopeid"),
|
2014-11-23 14:39:59 +13:00
|
|
|
true, true),
|
2014-02-05 17:31:33 +13:00
|
|
|
Typedef => ("typedef", vec!("id","qualname","value"), true, true),
|
|
|
|
ExternalCrate => ("external_crate", vec!("name","crate","file_name"), false, false),
|
|
|
|
Crate => ("crate", vec!("name"), true, false),
|
|
|
|
FnCall => ("fn_call", vec!("refid","refidcrate","qualname","scopeid"), true, true),
|
|
|
|
ModRef => ("mod_ref", vec!("refid","refidcrate","qualname","scopeid"), true, true),
|
|
|
|
VarRef => ("var_ref", vec!("refid","refidcrate","qualname","scopeid"), true, true),
|
|
|
|
TypeRef => ("type_ref",
|
|
|
|
vec!("refid","refidcrate","qualname","scopeid"),
|
|
|
|
true, true),
|
|
|
|
FnRef => ("fn_ref", vec!("refid","refidcrate","qualname","scopeid"), true, true)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn make_values_str(&self,
|
|
|
|
kind: &'static str,
|
|
|
|
fields: &Vec<&'static str>,
|
|
|
|
values: Vec<String>,
|
|
|
|
span: Span) -> Option<String> {
|
|
|
|
if values.len() != fields.len() {
|
2015-01-07 11:58:31 -05:00
|
|
|
self.span.sess.span_bug(span, &format!(
|
2014-02-05 17:31:33 +13:00
|
|
|
"Mismatch between length of fields for '{}', expected '{}', found '{}'",
|
2015-02-20 14:08:14 -05:00
|
|
|
kind, fields.len(), values.len()));
|
2014-02-05 17:31:33 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
let values = values.iter().map(|s| {
|
2014-11-23 14:57:26 +13:00
|
|
|
// Never take more than 1020 chars
|
2014-02-05 17:31:33 +13:00
|
|
|
if s.len() > 1020 {
|
2015-01-12 16:59:18 -05:00
|
|
|
&s[..1020]
|
2014-02-05 17:31:33 +13:00
|
|
|
} else {
|
2015-02-18 14:48:57 -05:00
|
|
|
&s[..]
|
2014-02-05 17:31:33 +13:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
let pairs = fields.iter().zip(values);
|
2015-06-08 16:55:35 +02:00
|
|
|
let strs = pairs.map(|(f, v)| format!(",{},\"{}\"", f, escape(String::from(v))));
|
2014-10-14 23:05:01 -07:00
|
|
|
Some(strs.fold(String::new(), |mut s, ss| {
|
2015-02-18 14:48:57 -05:00
|
|
|
s.push_str(&ss[..]);
|
2014-10-14 23:05:01 -07:00
|
|
|
s
|
|
|
|
}))
|
2014-02-05 17:31:33 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn record_without_span(&mut self,
|
|
|
|
kind: Row,
|
|
|
|
values: Vec<String>,
|
|
|
|
span: Span) {
|
|
|
|
let (label, ref fields, needs_span, dump_spans) = FmtStrs::lookup_row(kind);
|
|
|
|
|
|
|
|
if needs_span {
|
2015-01-07 11:58:31 -05:00
|
|
|
self.span.sess.span_bug(span, &format!(
|
2014-02-05 17:31:33 +13:00
|
|
|
"Called record_without_span for '{}' which does requires a span",
|
2015-02-20 14:08:14 -05:00
|
|
|
label));
|
2014-02-05 17:31:33 +13:00
|
|
|
}
|
|
|
|
assert!(!dump_spans);
|
|
|
|
|
|
|
|
if self.recorder.dump_spans {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
let values_str = match self.make_values_str(label, fields, values, span) {
|
|
|
|
Some(vs) => vs,
|
|
|
|
None => return,
|
|
|
|
};
|
|
|
|
|
2015-06-08 16:55:35 +02:00
|
|
|
let mut result = String::from(label);
|
2015-02-18 14:48:57 -05:00
|
|
|
result.push_str(&values_str[..]);
|
2014-10-14 23:05:01 -07:00
|
|
|
result.push_str("\n");
|
2015-02-18 14:48:57 -05:00
|
|
|
self.recorder.record(&result[..]);
|
2014-02-05 17:31:33 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn record_with_span(&mut self,
|
|
|
|
kind: Row,
|
|
|
|
span: Span,
|
|
|
|
sub_span: Span,
|
|
|
|
values: Vec<String>) {
|
|
|
|
let (label, ref fields, needs_span, dump_spans) = FmtStrs::lookup_row(kind);
|
|
|
|
|
|
|
|
if self.recorder.dump_spans {
|
|
|
|
if dump_spans {
|
librustc: Make `Copy` opt-in.
This change makes the compiler no longer infer whether types (structures
and enumerations) implement the `Copy` trait (and thus are implicitly
copyable). Rather, you must implement `Copy` yourself via `impl Copy for
MyType {}`.
A new warning has been added, `missing_copy_implementations`, to warn
you if a non-generic public type has been added that could have
implemented `Copy` but didn't.
For convenience, you may *temporarily* opt out of this behavior by using
`#![feature(opt_out_copy)]`. Note though that this feature gate will never be
accepted and will be removed by the time that 1.0 is released, so you should
transition your code away from using it.
This breaks code like:
#[deriving(Show)]
struct Point2D {
x: int,
y: int,
}
fn main() {
let mypoint = Point2D {
x: 1,
y: 1,
};
let otherpoint = mypoint;
println!("{}{}", mypoint, otherpoint);
}
Change this code to:
#[deriving(Show)]
struct Point2D {
x: int,
y: int,
}
impl Copy for Point2D {}
fn main() {
let mypoint = Point2D {
x: 1,
y: 1,
};
let otherpoint = mypoint;
println!("{}{}", mypoint, otherpoint);
}
This is the backwards-incompatible part of #13231.
Part of RFC #3.
[breaking-change]
2014-12-05 17:01:33 -08:00
|
|
|
self.recorder.dump_span(self.span.clone(),
|
|
|
|
label,
|
|
|
|
span,
|
|
|
|
Some(sub_span));
|
2014-02-05 17:31:33 +13:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if !needs_span {
|
|
|
|
self.span.sess.span_bug(span,
|
2015-02-01 21:53:25 -05:00
|
|
|
&format!("Called record_with_span for '{}' \
|
|
|
|
which does not require a span", label));
|
2014-02-05 17:31:33 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
let values_str = match self.make_values_str(label, fields, values, span) {
|
|
|
|
Some(vs) => vs,
|
|
|
|
None => return,
|
|
|
|
};
|
|
|
|
let result = format!("{},{}{}\n", label, self.span.extent_str(sub_span), values_str);
|
2015-02-18 14:48:57 -05:00
|
|
|
self.recorder.record(&result[..]);
|
2014-02-05 17:31:33 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn check_and_record(&mut self,
|
|
|
|
kind: Row,
|
|
|
|
span: Span,
|
|
|
|
sub_span: Option<Span>,
|
|
|
|
values: Vec<String>) {
|
|
|
|
match sub_span {
|
|
|
|
Some(sub_span) => self.record_with_span(kind, span, sub_span, values),
|
|
|
|
None => {
|
|
|
|
let (label, _, _, _) = FmtStrs::lookup_row(kind);
|
|
|
|
self.span.report_span_err(label, span);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn variable_str(&mut self,
|
|
|
|
span: Span,
|
|
|
|
sub_span: Option<Span>,
|
|
|
|
id: NodeId,
|
|
|
|
name: &str,
|
|
|
|
value: &str,
|
|
|
|
typ: &str) {
|
|
|
|
// Getting a fully qualified name for a variable is hard because in
|
|
|
|
// the local case they can be overridden in one block and there is no nice way
|
|
|
|
// to refer to such a scope in english, so we just hack it by appending the
|
|
|
|
// variable def's node id
|
2015-06-08 16:55:35 +02:00
|
|
|
let mut qualname = String::from(name);
|
2014-10-14 23:05:01 -07:00
|
|
|
qualname.push_str("$");
|
2015-02-20 14:08:14 -05:00
|
|
|
qualname.push_str(&id.to_string());
|
2014-02-05 17:31:33 +13:00
|
|
|
self.check_and_record(Variable,
|
|
|
|
span,
|
|
|
|
sub_span,
|
2015-01-25 10:58:43 +00:00
|
|
|
svec!(id, name, qualname, value, typ, 0));
|
2014-02-05 17:31:33 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
// formal parameters
|
|
|
|
pub fn formal_str(&mut self,
|
|
|
|
span: Span,
|
|
|
|
sub_span: Option<Span>,
|
|
|
|
id: NodeId,
|
|
|
|
fn_name: &str,
|
|
|
|
name: &str,
|
|
|
|
typ: &str) {
|
2015-06-08 16:55:35 +02:00
|
|
|
let mut qualname = String::from(fn_name);
|
2014-10-14 23:05:01 -07:00
|
|
|
qualname.push_str("::");
|
|
|
|
qualname.push_str(name);
|
2014-02-05 17:31:33 +13:00
|
|
|
self.check_and_record(Variable,
|
|
|
|
span,
|
|
|
|
sub_span,
|
2015-01-25 10:58:43 +00:00
|
|
|
svec!(id, name, qualname, "", typ, 0));
|
2014-02-05 17:31:33 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
// value is the initialising expression of the static if it is not mut, otherwise "".
|
|
|
|
pub fn static_str(&mut self,
|
|
|
|
span: Span,
|
|
|
|
sub_span: Option<Span>,
|
|
|
|
id: NodeId,
|
|
|
|
name: &str,
|
|
|
|
qualname: &str,
|
|
|
|
value: &str,
|
|
|
|
typ: &str,
|
|
|
|
scope_id: NodeId) {
|
|
|
|
self.check_and_record(Variable,
|
|
|
|
span,
|
|
|
|
sub_span,
|
|
|
|
svec!(id, name, qualname, value, typ, scope_id));
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn field_str(&mut self,
|
|
|
|
span: Span,
|
|
|
|
sub_span: Option<Span>,
|
|
|
|
id: NodeId,
|
|
|
|
name: &str,
|
|
|
|
qualname: &str,
|
|
|
|
typ: &str,
|
|
|
|
scope_id: NodeId) {
|
|
|
|
self.check_and_record(Variable,
|
|
|
|
span,
|
|
|
|
sub_span,
|
|
|
|
svec!(id, name, qualname, "", typ, scope_id));
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn enum_str(&mut self,
|
|
|
|
span: Span,
|
|
|
|
sub_span: Option<Span>,
|
|
|
|
id: NodeId,
|
|
|
|
name: &str,
|
2014-11-23 14:57:26 +13:00
|
|
|
scope_id: NodeId,
|
|
|
|
value: &str) {
|
2014-02-05 17:31:33 +13:00
|
|
|
self.check_and_record(Enum,
|
|
|
|
span,
|
|
|
|
sub_span,
|
2014-11-23 14:57:26 +13:00
|
|
|
svec!(id, name, scope_id, value));
|
2014-02-05 17:31:33 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn tuple_variant_str(&mut self,
|
|
|
|
span: Span,
|
|
|
|
sub_span: Option<Span>,
|
|
|
|
id: NodeId,
|
|
|
|
name: &str,
|
|
|
|
qualname: &str,
|
2014-11-23 14:39:59 +13:00
|
|
|
typ: &str,
|
2014-02-05 17:31:33 +13:00
|
|
|
val: &str,
|
|
|
|
scope_id: NodeId) {
|
|
|
|
self.check_and_record(Variant,
|
|
|
|
span,
|
|
|
|
sub_span,
|
2014-11-23 14:39:59 +13:00
|
|
|
svec!(id, name, qualname, typ, val, scope_id));
|
2014-02-05 17:31:33 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn struct_variant_str(&mut self,
|
|
|
|
span: Span,
|
|
|
|
sub_span: Option<Span>,
|
|
|
|
id: NodeId,
|
|
|
|
ctor_id: NodeId,
|
|
|
|
name: &str,
|
2014-11-23 14:39:59 +13:00
|
|
|
typ: &str,
|
2014-02-05 17:31:33 +13:00
|
|
|
val: &str,
|
|
|
|
scope_id: NodeId) {
|
|
|
|
self.check_and_record(VariantStruct,
|
|
|
|
span,
|
|
|
|
sub_span,
|
2014-11-23 14:39:59 +13:00
|
|
|
svec!(id, ctor_id, name, typ, val, scope_id));
|
2014-02-05 17:31:33 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn fn_str(&mut self,
|
|
|
|
span: Span,
|
|
|
|
sub_span: Option<Span>,
|
|
|
|
id: NodeId,
|
|
|
|
name: &str,
|
|
|
|
scope_id: NodeId) {
|
|
|
|
self.check_and_record(Function,
|
|
|
|
span,
|
|
|
|
sub_span,
|
|
|
|
svec!(id, name, "", "", scope_id));
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn method_str(&mut self,
|
|
|
|
span: Span,
|
|
|
|
sub_span: Option<Span>,
|
|
|
|
id: NodeId,
|
|
|
|
name: &str,
|
|
|
|
decl_id: Option<DefId>,
|
|
|
|
scope_id: NodeId) {
|
|
|
|
let values = match decl_id {
|
|
|
|
Some(decl_id) => svec!(id, name, decl_id.node, decl_id.krate, scope_id),
|
|
|
|
None => svec!(id, name, "", "", scope_id)
|
|
|
|
};
|
|
|
|
self.check_and_record(Function,
|
|
|
|
span,
|
|
|
|
sub_span,
|
|
|
|
values);
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn method_decl_str(&mut self,
|
|
|
|
span: Span,
|
|
|
|
sub_span: Option<Span>,
|
|
|
|
id: NodeId,
|
|
|
|
name: &str,
|
|
|
|
scope_id: NodeId) {
|
|
|
|
self.check_and_record(MethodDecl,
|
|
|
|
span,
|
|
|
|
sub_span,
|
|
|
|
svec!(id, name, scope_id));
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn struct_str(&mut self,
|
|
|
|
span: Span,
|
|
|
|
sub_span: Option<Span>,
|
|
|
|
id: NodeId,
|
|
|
|
ctor_id: NodeId,
|
|
|
|
name: &str,
|
2014-11-23 14:57:26 +13:00
|
|
|
scope_id: NodeId,
|
|
|
|
value: &str) {
|
2014-02-05 17:31:33 +13:00
|
|
|
self.check_and_record(Struct,
|
|
|
|
span,
|
|
|
|
sub_span,
|
2014-11-23 14:57:26 +13:00
|
|
|
svec!(id, ctor_id, name, scope_id, value));
|
2014-02-05 17:31:33 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn trait_str(&mut self,
|
|
|
|
span: Span,
|
|
|
|
sub_span: Option<Span>,
|
|
|
|
id: NodeId,
|
|
|
|
name: &str,
|
2014-11-23 14:57:26 +13:00
|
|
|
scope_id: NodeId,
|
|
|
|
value: &str) {
|
2014-02-05 17:31:33 +13:00
|
|
|
self.check_and_record(Trait,
|
|
|
|
span,
|
|
|
|
sub_span,
|
2014-11-23 14:57:26 +13:00
|
|
|
svec!(id, name, scope_id, value));
|
2014-02-05 17:31:33 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn impl_str(&mut self,
|
|
|
|
span: Span,
|
|
|
|
sub_span: Option<Span>,
|
|
|
|
id: NodeId,
|
2015-01-14 22:24:09 +13:00
|
|
|
ref_id: Option<DefId>,
|
|
|
|
trait_id: Option<DefId>,
|
2014-02-05 17:31:33 +13:00
|
|
|
scope_id: NodeId) {
|
2015-01-14 22:24:09 +13:00
|
|
|
let ref_id = ref_id.unwrap_or(ZERO_DEF_ID);
|
|
|
|
let trait_id = trait_id.unwrap_or(ZERO_DEF_ID);
|
2014-02-05 17:31:33 +13:00
|
|
|
self.check_and_record(Impl,
|
|
|
|
span,
|
|
|
|
sub_span,
|
2015-01-14 22:24:09 +13:00
|
|
|
svec!(id,
|
|
|
|
ref_id.node,
|
|
|
|
ref_id.krate,
|
|
|
|
trait_id.node,
|
|
|
|
trait_id.krate,
|
|
|
|
scope_id));
|
2014-02-05 17:31:33 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn mod_str(&mut self,
|
|
|
|
span: Span,
|
|
|
|
sub_span: Option<Span>,
|
|
|
|
id: NodeId,
|
|
|
|
name: &str,
|
|
|
|
parent: NodeId,
|
|
|
|
filename: &str) {
|
|
|
|
self.check_and_record(Module,
|
|
|
|
span,
|
|
|
|
sub_span,
|
|
|
|
svec!(id, name, parent, filename));
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn use_alias_str(&mut self,
|
|
|
|
span: Span,
|
|
|
|
sub_span: Option<Span>,
|
|
|
|
id: NodeId,
|
|
|
|
mod_id: Option<DefId>,
|
|
|
|
name: &str,
|
|
|
|
parent: NodeId) {
|
|
|
|
let (mod_node, mod_crate) = match mod_id {
|
|
|
|
Some(mod_id) => (mod_id.node, mod_id.krate),
|
|
|
|
None => (0, 0)
|
|
|
|
};
|
|
|
|
self.check_and_record(UseAlias,
|
|
|
|
span,
|
|
|
|
sub_span,
|
|
|
|
svec!(id, mod_node, mod_crate, name, parent));
|
|
|
|
}
|
|
|
|
|
2014-11-23 22:29:41 +13:00
|
|
|
pub fn use_glob_str(&mut self,
|
|
|
|
span: Span,
|
|
|
|
sub_span: Option<Span>,
|
|
|
|
id: NodeId,
|
|
|
|
values: &str,
|
|
|
|
parent: NodeId) {
|
|
|
|
self.check_and_record(UseGlob,
|
|
|
|
span,
|
|
|
|
sub_span,
|
|
|
|
svec!(id, values, parent));
|
|
|
|
}
|
|
|
|
|
2014-02-05 17:31:33 +13:00
|
|
|
pub fn extern_crate_str(&mut self,
|
2015-01-19 14:04:46 +13:00
|
|
|
span: Span,
|
|
|
|
sub_span: Option<Span>,
|
|
|
|
id: NodeId,
|
|
|
|
cnum: ast::CrateNum,
|
|
|
|
name: &str,
|
|
|
|
loc: &str,
|
|
|
|
parent: NodeId) {
|
2014-02-05 17:31:33 +13:00
|
|
|
self.check_and_record(ExternCrate,
|
|
|
|
span,
|
|
|
|
sub_span,
|
|
|
|
svec!(id, name, loc, cnum, parent));
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn inherit_str(&mut self,
|
|
|
|
span: Span,
|
|
|
|
sub_span: Option<Span>,
|
|
|
|
base_id: DefId,
|
|
|
|
deriv_id: NodeId) {
|
|
|
|
self.check_and_record(Inheritance,
|
|
|
|
span,
|
|
|
|
sub_span,
|
2014-04-21 17:58:52 -04:00
|
|
|
svec!(base_id.node,
|
|
|
|
base_id.krate,
|
|
|
|
deriv_id,
|
2015-01-25 10:58:43 +00:00
|
|
|
0));
|
2014-02-05 17:31:33 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn fn_call_str(&mut self,
|
|
|
|
span: Span,
|
|
|
|
sub_span: Option<Span>,
|
|
|
|
id: DefId,
|
|
|
|
scope_id:NodeId) {
|
|
|
|
self.check_and_record(FnCall,
|
|
|
|
span,
|
|
|
|
sub_span,
|
|
|
|
svec!(id.node, id.krate, "", scope_id));
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn meth_call_str(&mut self,
|
|
|
|
span: Span,
|
|
|
|
sub_span: Option<Span>,
|
|
|
|
defid: Option<DefId>,
|
|
|
|
declid: Option<DefId>,
|
|
|
|
scope_id: NodeId) {
|
|
|
|
let (dfn, dfk) = match defid {
|
|
|
|
Some(defid) => (defid.node, defid.krate),
|
|
|
|
None => (0, 0)
|
|
|
|
};
|
|
|
|
let (dcn, dck) = match declid {
|
|
|
|
Some(declid) => (s!(declid.node), s!(declid.krate)),
|
2014-07-16 22:37:28 +02:00
|
|
|
None => ("".to_string(), "".to_string())
|
2014-02-05 17:31:33 +13:00
|
|
|
};
|
|
|
|
self.check_and_record(MethodCall,
|
|
|
|
span,
|
|
|
|
sub_span,
|
|
|
|
svec!(dfn, dfk, dcn, dck, scope_id));
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn sub_mod_ref_str(&mut self,
|
|
|
|
span: Span,
|
|
|
|
sub_span: Span,
|
|
|
|
qualname: &str,
|
|
|
|
parent:NodeId) {
|
|
|
|
self.record_with_span(ModRef,
|
|
|
|
span,
|
|
|
|
sub_span,
|
2015-01-25 10:58:43 +00:00
|
|
|
svec!(0, 0, qualname, parent));
|
2014-02-05 17:31:33 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn typedef_str(&mut self,
|
|
|
|
span: Span,
|
|
|
|
sub_span: Option<Span>,
|
|
|
|
id: NodeId,
|
|
|
|
qualname: &str,
|
|
|
|
value: &str) {
|
|
|
|
self.check_and_record(Typedef,
|
|
|
|
span,
|
|
|
|
sub_span,
|
|
|
|
svec!(id, qualname, value));
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn crate_str(&mut self,
|
|
|
|
span: Span,
|
|
|
|
name: &str) {
|
|
|
|
self.record_with_span(Crate,
|
|
|
|
span,
|
|
|
|
span,
|
|
|
|
svec!(name));
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn external_crate_str(&mut self,
|
|
|
|
span: Span,
|
|
|
|
name: &str,
|
|
|
|
num: ast::CrateNum) {
|
|
|
|
let lo_loc = self.span.sess.codemap().lookup_char_pos(span.lo);
|
|
|
|
self.record_without_span(ExternalCrate,
|
|
|
|
svec!(name, num, lo_loc.file.name),
|
|
|
|
span);
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn sub_type_ref_str(&mut self,
|
|
|
|
span: Span,
|
|
|
|
sub_span: Span,
|
|
|
|
qualname: &str) {
|
|
|
|
self.record_with_span(TypeRef,
|
|
|
|
span,
|
|
|
|
sub_span,
|
2015-01-25 10:58:43 +00:00
|
|
|
svec!(0, 0, qualname, 0));
|
2014-02-05 17:31:33 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
// A slightly generic function for a reference to an item of any kind.
|
|
|
|
pub fn ref_str(&mut self,
|
|
|
|
kind: Row,
|
|
|
|
span: Span,
|
|
|
|
sub_span: Option<Span>,
|
|
|
|
id: DefId,
|
|
|
|
scope_id: NodeId) {
|
|
|
|
self.check_and_record(kind,
|
|
|
|
span,
|
|
|
|
sub_span,
|
|
|
|
svec!(id.node, id.krate, "", scope_id));
|
|
|
|
}
|
|
|
|
}
|