Use arena instead of vec

This commit is contained in:
Edwin Cheng 2021-01-02 22:48:22 +08:00
parent fe5340d970
commit 3545289603

View file

@ -4,6 +4,7 @@
//! this moment, this is horribly incomplete and handles only `$crate`. //! this moment, this is horribly incomplete and handles only `$crate`.
use std::sync::Arc; use std::sync::Arc;
use arena::{Arena, Idx};
use base_db::CrateId; use base_db::CrateId;
use either::Either; use either::Either;
use mbe::Origin; use mbe::Origin;
@ -46,7 +47,7 @@ impl Hygiene {
let frames = self.frames.as_ref()?; let frames = self.frames.as_ref()?;
let mut token = path.syntax().first_token()?; let mut token = path.syntax().first_token()?;
let mut current = frames.0.first(); let mut current = frames.first();
while let Some((frame, data)) = while let Some((frame, data)) =
current.and_then(|it| Some((it, it.expansion.as_ref()?.map_token_up(&token)?))) current.and_then(|it| Some((it, it.expansion.as_ref()?.map_token_up(&token)?)))
@ -55,18 +56,15 @@ impl Hygiene {
if origin == Origin::Def { if origin == Origin::Def {
return if frame.local_inner { frame.krate } else { None }; return if frame.local_inner { frame.krate } else { None };
} }
current = frames.get(frame.call_site?); current = Some(&frames.0[frame.call_site?]);
token = mapped.value; token = mapped.value;
} }
None None
} }
} }
#[derive(Clone, Debug, Copy)] #[derive(Default, Debug)]
struct HygieneFrameId(usize); struct HygieneFrames(Arena<HygieneFrame>);
#[derive(Clone, Debug, Default)]
struct HygieneFrames(Vec<HygieneFrame>);
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
struct HygieneFrame { struct HygieneFrame {
@ -76,8 +74,8 @@ struct HygieneFrame {
local_inner: bool, local_inner: bool,
krate: Option<CrateId>, krate: Option<CrateId>,
call_site: Option<HygieneFrameId>, call_site: Option<Idx<HygieneFrame>>,
def_site: Option<HygieneFrameId>, def_site: Option<Idx<HygieneFrame>>,
} }
impl HygieneFrames { impl HygieneFrames {
@ -87,7 +85,7 @@ impl HygieneFrames {
frames frames
} }
fn add(&mut self, db: &dyn AstDatabase, file_id: HirFileId) -> Option<HygieneFrameId> { fn add(&mut self, db: &dyn AstDatabase, file_id: HirFileId) -> Option<Idx<HygieneFrame>> {
let (krate, local_inner) = match file_id.0 { let (krate, local_inner) = match file_id.0 {
HirFileIdRepr::FileId(_) => (None, false), HirFileIdRepr::FileId(_) => (None, false),
HirFileIdRepr::MacroFile(macro_file) => match macro_file.macro_call_id { HirFileIdRepr::MacroFile(macro_file) => match macro_file.macro_call_id {
@ -108,24 +106,20 @@ impl HygieneFrames {
let expansion = file_id.expansion_info(db); let expansion = file_id.expansion_info(db);
let expansion = match expansion { let expansion = match expansion {
None => { None => {
let idx = self.0.len(); return Some(self.0.alloc(HygieneFrame {
self.0.push(HygieneFrame {
expansion: None, expansion: None,
local_inner, local_inner,
krate, krate,
call_site: None, call_site: None,
def_site: None, def_site: None,
}); }));
return Some(HygieneFrameId(idx));
} }
Some(it) => it, Some(it) => it,
}; };
let def_site = expansion.def.clone(); let def_site = expansion.def.clone();
let call_site = expansion.arg.file_id; let call_site = expansion.arg.file_id;
let idx = self.0.alloc(HygieneFrame {
let idx = self.0.len();
self.0.push(HygieneFrame {
expansion: Some(expansion), expansion: Some(expansion),
local_inner, local_inner,
krate, krate,
@ -136,16 +130,16 @@ impl HygieneFrames {
self.0[idx].call_site = self.add(db, call_site); self.0[idx].call_site = self.add(db, call_site);
self.0[idx].def_site = def_site.and_then(|it| self.add(db, it.file_id)); self.0[idx].def_site = def_site.and_then(|it| self.add(db, it.file_id));
Some(HygieneFrameId(idx)) Some(idx)
} }
fn get(&self, id: HygieneFrameId) -> Option<&HygieneFrame> { fn first(&self) -> Option<&HygieneFrame> {
self.0.get(id.0) self.0.iter().next().map(|it| it.1)
} }
fn root_crate(&self, name_ref: &ast::NameRef) -> Option<CrateId> { fn root_crate(&self, name_ref: &ast::NameRef) -> Option<CrateId> {
let mut token = name_ref.syntax().first_token()?; let mut token = name_ref.syntax().first_token()?;
let first = self.0.first()?; let first = self.first()?;
let mut result = first.krate; let mut result = first.krate;
let mut current = Some(first); let mut current = Some(first);
@ -164,7 +158,7 @@ impl HygieneFrames {
Some(it) => it, Some(it) => it,
}; };
current = self.get(site); current = Some(&self.0[site]);
token = mapped.value; token = mapped.value;
} }