syntax: use an index in CodeMap instead of Gc for ExpnInfo.

This commit is contained in:
Eduard Burtescu 2014-09-17 19:01:33 +03:00
parent 49dd8e8c36
commit 07f4fda598
9 changed files with 123 additions and 113 deletions

View file

@ -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)]