syntax: use an index in CodeMap instead of Gc for ExpnInfo.
This commit is contained in:
parent
49dd8e8c36
commit
07f4fda598
9 changed files with 123 additions and 113 deletions
|
@ -25,7 +25,6 @@ source code snippets, etc.
|
|||
|
||||
use serialize::{Encodable, Decodable, Encoder, Decoder};
|
||||
use std::cell::RefCell;
|
||||
use std::gc::Gc;
|
||||
use std::rc::Rc;
|
||||
|
||||
pub trait Pos {
|
||||
|
@ -93,10 +92,10 @@ pub struct Span {
|
|||
pub hi: BytePos,
|
||||
/// Information about where the macro came from, if this piece of
|
||||
/// code was created by a macro expansion.
|
||||
pub expn_info: Option<Gc<ExpnInfo>>
|
||||
pub expn_id: ExpnId
|
||||
}
|
||||
|
||||
pub static DUMMY_SP: Span = Span { lo: BytePos(0), hi: BytePos(0), expn_info: None };
|
||||
pub static DUMMY_SP: Span = Span { lo: BytePos(0), hi: BytePos(0), expn_id: NO_EXPANSION };
|
||||
|
||||
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
|
||||
pub struct Spanned<T> {
|
||||
|
@ -140,17 +139,19 @@ pub fn dummy_spanned<T>(t: T) -> Spanned<T> {
|
|||
|
||||
/* assuming that we're not in macro expansion */
|
||||
pub fn mk_sp(lo: BytePos, hi: BytePos) -> Span {
|
||||
Span {lo: lo, hi: hi, expn_info: None}
|
||||
Span {lo: lo, hi: hi, expn_id: NO_EXPANSION}
|
||||
}
|
||||
|
||||
/// Return the span itself if it doesn't come from a macro expansion,
|
||||
/// otherwise return the call site span up to the `enclosing_sp` by
|
||||
/// following the `expn_info` chain.
|
||||
pub fn original_sp(sp: Span, enclosing_sp: Span) -> Span {
|
||||
match (sp.expn_info, enclosing_sp.expn_info) {
|
||||
pub fn original_sp(cm: &CodeMap, sp: Span, enclosing_sp: Span) -> Span {
|
||||
let call_site1 = cm.with_expn_info(sp.expn_id, |ei| ei.map(|ei| ei.call_site));
|
||||
let call_site2 = cm.with_expn_info(enclosing_sp.expn_id, |ei| ei.map(|ei| ei.call_site));
|
||||
match (call_site1, call_site2) {
|
||||
(None, _) => sp,
|
||||
(Some(expn1), Some(expn2)) if expn1.call_site == expn2.call_site => sp,
|
||||
(Some(expn1), _) => original_sp(expn1.call_site, enclosing_sp),
|
||||
(Some(call_site1), Some(call_site2)) if call_site1 == call_site2 => sp,
|
||||
(Some(call_site1), _) => original_sp(cm, call_site1, enclosing_sp),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -222,6 +223,11 @@ pub struct ExpnInfo {
|
|||
pub callee: NameAndSpan
|
||||
}
|
||||
|
||||
#[deriving(PartialEq, Eq, Clone, Show, Hash)]
|
||||
pub struct ExpnId(u32);
|
||||
|
||||
pub static NO_EXPANSION: ExpnId = ExpnId(-1);
|
||||
|
||||
pub type FileName = String;
|
||||
|
||||
pub struct FileLines {
|
||||
|
@ -299,13 +305,15 @@ impl FileMap {
|
|||
}
|
||||
|
||||
pub struct CodeMap {
|
||||
pub files: RefCell<Vec<Rc<FileMap>>>
|
||||
pub files: RefCell<Vec<Rc<FileMap>>>,
|
||||
expansions: RefCell<Vec<ExpnInfo>>
|
||||
}
|
||||
|
||||
impl CodeMap {
|
||||
pub fn new() -> CodeMap {
|
||||
CodeMap {
|
||||
files: RefCell::new(Vec::new()),
|
||||
expansions: RefCell::new(Vec::new()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -527,6 +535,19 @@ impl CodeMap {
|
|||
col: chpos - linechpos
|
||||
}
|
||||
}
|
||||
|
||||
pub fn record_expansion(&self, expn_info: ExpnInfo) -> ExpnId {
|
||||
let mut expansions = self.expansions.borrow_mut();
|
||||
expansions.push(expn_info);
|
||||
ExpnId(expansions.len().to_u32().expect("too many ExpnInfo's!") - 1)
|
||||
}
|
||||
|
||||
pub fn with_expn_info<T>(&self, id: ExpnId, f: |Option<&ExpnInfo>| -> T) -> T {
|
||||
match id {
|
||||
NO_EXPANSION => f(None),
|
||||
ExpnId(i) => f(Some(&(*self.expansions.borrow())[i as uint]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue