Changed macro spans in CSVs to point to the macro name, bugfixed nested spans
This commit is contained in:
parent
50df6b9dc5
commit
b361b7f1a5
3 changed files with 51 additions and 8 deletions
|
@ -847,13 +847,17 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
|
||||||
if !self.mac_defs.contains(&data.callee_span)
|
if !self.mac_defs.contains(&data.callee_span)
|
||||||
&& !data.imported {
|
&& !data.imported {
|
||||||
self.mac_defs.insert(data.callee_span);
|
self.mac_defs.insert(data.callee_span);
|
||||||
self.fmt.macro_str(data.callee_span, data.callee_span,
|
if let Some(sub_span) = self.span.span_for_macro_def_name(data.callee_span) {
|
||||||
data.name.clone(), qualname.clone());
|
self.fmt.macro_str(data.callee_span, sub_span,
|
||||||
|
data.name.clone(), qualname.clone());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if !self.mac_uses.contains(&data.span) {
|
if !self.mac_uses.contains(&data.span) {
|
||||||
self.mac_uses.insert(data.span);
|
self.mac_uses.insert(data.span);
|
||||||
self.fmt.macro_use_str(data.span, data.span, data.name,
|
if let Some(sub_span) = self.span.span_for_macro_use_name(data.span) {
|
||||||
qualname, data.scope);
|
self.fmt.macro_use_str(data.span, sub_span, data.name,
|
||||||
|
qualname, data.scope);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -378,8 +378,8 @@ impl<'a> SpanUtils<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Given a macro_rules definition span, return the span of the macro's name.
|
// Return the name for a macro definition (identifier after first `!`)
|
||||||
pub fn span_for_macro_name(&self, span: Span) -> Option<Span> {
|
pub fn span_for_macro_def_name(&self, span: Span) -> Option<Span> {
|
||||||
let mut toks = self.retokenise_span(span);
|
let mut toks = self.retokenise_span(span);
|
||||||
loop {
|
loop {
|
||||||
let ts = toks.real_token();
|
let ts = toks.real_token();
|
||||||
|
@ -397,6 +397,26 @@ impl<'a> SpanUtils<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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 self.make_sub_span(span, Some(prev.sp));
|
||||||
|
} else {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prev = ts;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Return true if the span is generated code, and
|
/// Return true if the span is generated code, and
|
||||||
/// it is not a subspan of the root callsite.
|
/// it is not a subspan of the root callsite.
|
||||||
///
|
///
|
||||||
|
|
|
@ -1052,9 +1052,18 @@ impl CodeMap {
|
||||||
/// the macro callsite that expanded to it.
|
/// the macro callsite that expanded to it.
|
||||||
pub fn source_callsite(&self, sp: Span) -> Span {
|
pub fn source_callsite(&self, sp: Span) -> Span {
|
||||||
let mut span = sp;
|
let mut span = sp;
|
||||||
|
// Special case - if a macro is parsed as an argument to another macro, the source
|
||||||
|
// callsite is the first callsite, which is also source-equivalent to the span.
|
||||||
|
let mut first = true;
|
||||||
while span.expn_id != NO_EXPANSION && span.expn_id != COMMAND_LINE_EXPN {
|
while span.expn_id != NO_EXPANSION && span.expn_id != COMMAND_LINE_EXPN {
|
||||||
if let Some(callsite) = self.with_expn_info(span.expn_id,
|
if let Some(callsite) = self.with_expn_info(span.expn_id,
|
||||||
|ei| ei.map(|ei| ei.call_site.clone())) {
|
|ei| ei.map(|ei| ei.call_site.clone())) {
|
||||||
|
if first && span.source_equal(&callsite) {
|
||||||
|
if self.lookup_char_pos(span.lo).file.is_real_file() {
|
||||||
|
return Span { expn_id: NO_EXPANSION, .. span };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
first = false;
|
||||||
span = callsite;
|
span = callsite;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -1071,10 +1080,20 @@ impl CodeMap {
|
||||||
/// corresponding to the source callsite.
|
/// corresponding to the source callsite.
|
||||||
pub fn source_callee(&self, sp: Span) -> Option<NameAndSpan> {
|
pub fn source_callee(&self, sp: Span) -> Option<NameAndSpan> {
|
||||||
let mut span = sp;
|
let mut span = sp;
|
||||||
|
// Special case - if a macro is parsed as an argument to another macro, the source
|
||||||
|
// callsite is source-equivalent to the span, and the source callee is the first callee.
|
||||||
|
let mut first = true;
|
||||||
while let Some(callsite) = self.with_expn_info(span.expn_id,
|
while let Some(callsite) = self.with_expn_info(span.expn_id,
|
||||||
|ei| ei.map(|ei| ei.call_site.clone())) {
|
|ei| ei.map(|ei| ei.call_site.clone())) {
|
||||||
|
if first && span.source_equal(&callsite) {
|
||||||
|
if self.lookup_char_pos(span.lo).file.is_real_file() {
|
||||||
|
return self.with_expn_info(span.expn_id,
|
||||||
|
|ei| ei.map(|ei| ei.callee.clone()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
first = false;
|
||||||
if let Some(_) = self.with_expn_info(callsite.expn_id,
|
if let Some(_) = self.with_expn_info(callsite.expn_id,
|
||||||
|ei| ei.map(|ei| ei.call_site.clone())) {
|
|ei| ei.map(|ei| ei.call_site.clone())) {
|
||||||
span = callsite;
|
span = callsite;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue