use MFile

This commit is contained in:
Aleksey Kladov 2019-01-01 20:59:00 +03:00
parent 4161466918
commit 289391e163
7 changed files with 62 additions and 30 deletions

View File

@ -1,10 +1,10 @@
use std::sync::Arc;
use ra_syntax::SyntaxNode;
use ra_syntax::{SyntaxNode, SourceFileNode};
use ra_db::{SourceRootId, LocationIntener, SyntaxDatabase, FileId, Cancelable};
use crate::{
DefLoc, DefId, Name,
DefLoc, DefId, Name, MFileId,
SourceFileItems, SourceItemId,
query_definitions,
FnScopes,
@ -21,6 +21,10 @@ pub trait HirDatabase: SyntaxDatabase
+ AsRef<LocationIntener<DefLoc, DefId>>
+ AsRef<LocationIntener<MacroCallLoc, MacroCallId>>
{
fn m_source_file(mfile_id: MFileId) -> SourceFileNode {
type MSourceFileQuery;
use fn crate::query_definitions::m_source_file;
}
fn expand_macro_invocation(invoc: MacroCallId) -> Option<Arc<MacroExpansion>> {
type ExpandMacroCallQuery;
use fn crate::macros::expand_macro_invocation;
@ -56,7 +60,7 @@ pub trait HirDatabase: SyntaxDatabase
use fn crate::ty::type_for_field;
}
fn file_items(file_id: FileId) -> Arc<SourceFileItems> {
fn file_items(mfile_id: MFileId) -> Arc<SourceFileItems> {
type SourceFileItemsQuery;
use fn query_definitions::file_items;
}

View File

@ -57,11 +57,18 @@ pub use self::function::FnSignatureInfo;
/// An `MFileId` is like a `FileId`, but it can also refer to code generated by
/// macros.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum MFileId {
File(FileId),
Macro(MacroCallId),
}
impl From<FileId> for MFileId {
fn from(file_id: FileId) -> MFileId {
MFileId::File(file_id)
}
}
/// Def's are a core concept of hir. A `Def` is an Item (function, module, etc)
/// in a specific module.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@ -163,7 +170,7 @@ pub(crate) type SourceFileItemId = Id<SyntaxNode>;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct SourceItemId {
file_id: FileId,
mfile_id: MFileId,
/// None for the whole file.
item_id: Option<SourceFileItemId>,
}
@ -171,14 +178,14 @@ pub struct SourceItemId {
/// Maps item's `SyntaxNode`s to `SourceFileItemId` and back.
#[derive(Debug, PartialEq, Eq)]
pub struct SourceFileItems {
file_id: FileId,
mfile_id: MFileId,
arena: Arena<SyntaxNode>,
}
impl SourceFileItems {
fn new(file_id: FileId, source_file: SourceFile) -> SourceFileItems {
fn new(mfile_id: MFileId, source_file: SourceFile) -> SourceFileItems {
let mut res = SourceFileItems {
file_id,
mfile_id,
arena: Arena::default(),
};
res.init(source_file);
@ -198,11 +205,11 @@ impl SourceFileItems {
fn alloc(&mut self, item: SyntaxNode) -> SourceFileItemId {
self.arena.alloc(item)
}
pub fn id_of(&self, file_id: FileId, item: SyntaxNodeRef) -> SourceFileItemId {
pub fn id_of(&self, mfile_id: MFileId, item: SyntaxNodeRef) -> SourceFileItemId {
assert_eq!(
self.file_id, file_id,
self.mfile_id, mfile_id,
"SourceFileItems: wrong file, expected {:?}, got {:?}",
self.file_id, file_id
self.mfile_id, mfile_id
);
self.id_of_unchecked(item)
}

View File

@ -147,7 +147,9 @@ pub struct MacroExpansion {
}
impl MacroExpansion {
pub fn file(&self) -> SourceFileNode {
//FIXME: does not really make sense, macro expansion is not neccessary a
//whole file.
pub(crate) fn file(&self) -> SourceFileNode {
SourceFileNode::parse(&self.text)
}

View File

@ -15,6 +15,7 @@ use relative_path::RelativePathBuf;
use crate::{
Def, DefKind, DefLoc, DefId,
Name, Path, PathKind, HirDatabase, SourceItemId, SourceFileItemId, Crate,
MFileId,
arena::{Arena, Id},
};
@ -292,7 +293,10 @@ pub struct ModuleData {
impl ModuleSource {
// precondition: item_id **must** point to module
fn new(file_id: FileId, item_id: Option<SourceFileItemId>) -> ModuleSource {
let source_item_id = SourceItemId { file_id, item_id };
let source_item_id = SourceItemId {
mfile_id: file_id.into(),
item_id,
};
ModuleSource(source_item_id)
}
@ -306,13 +310,16 @@ impl ModuleSource {
m: ast::Module,
) -> ModuleSource {
assert!(!m.has_semi());
let file_items = db.file_items(file_id);
let item_id = file_items.id_of(file_id, m.syntax());
let file_items = db.file_items(file_id.into());
let item_id = file_items.id_of(file_id.into(), m.syntax());
ModuleSource::new(file_id, Some(item_id))
}
pub fn file_id(self) -> FileId {
self.0.file_id
match self.0.mfile_id {
MFileId::File(file_id) => file_id,
MFileId::Macro(_) => unreachable!(),
}
}
pub(crate) fn resolve(self, db: &impl HirDatabase) -> ModuleSourceNode {

View File

@ -98,7 +98,7 @@ pub struct NamedImport {
impl NamedImport {
pub fn range(&self, db: &impl HirDatabase, file_id: FileId) -> TextRange {
let source_item_id = SourceItemId {
file_id,
mfile_id: file_id.into(),
item_id: Some(self.file_item_id),
};
let syntax = db.file_item(source_item_id);
@ -360,7 +360,7 @@ where
source_root_id: self.source_root,
module_id,
source_item_id: SourceItemId {
file_id,
mfile_id: file_id.into(),
item_id: Some(item.id),
},
};
@ -376,7 +376,7 @@ where
source_root_id: self.source_root,
module_id,
source_item_id: SourceItemId {
file_id,
mfile_id: file_id.into(),
item_id: Some(item.id),
},
};

View File

@ -5,13 +5,13 @@ use std::{
use rustc_hash::FxHashMap;
use ra_syntax::{
AstNode, SyntaxNode,
AstNode, SyntaxNode, SourceFileNode,
ast::{self, NameOwner, ModuleItemOwner}
};
use ra_db::{SourceRootId, FileId, Cancelable,};
use crate::{
SourceFileItems, SourceItemId, DefKind, Function, DefId, Name, AsName,
SourceFileItems, SourceItemId, DefKind, Function, DefId, Name, AsName, MFileId,
db::HirDatabase,
function::FnScopes,
module::{
@ -47,17 +47,29 @@ pub(super) fn enum_data(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Arc<
Ok(Arc::new(EnumData::new(enum_def.borrowed())))
}
pub(super) fn file_items(db: &impl HirDatabase, file_id: FileId) -> Arc<SourceFileItems> {
let source_file = db.source_file(file_id);
pub(super) fn m_source_file(db: &impl HirDatabase, mfile_id: MFileId) -> SourceFileNode {
match mfile_id {
MFileId::File(file_id) => db.source_file(file_id),
MFileId::Macro(m) => {
if let Some(exp) = db.expand_macro_invocation(m) {
return exp.file();
}
SourceFileNode::parse("")
}
}
}
pub(super) fn file_items(db: &impl HirDatabase, mfile_id: MFileId) -> Arc<SourceFileItems> {
let source_file = db.m_source_file(mfile_id);
let source_file = source_file.borrowed();
let res = SourceFileItems::new(file_id, source_file);
let res = SourceFileItems::new(mfile_id, source_file);
Arc::new(res)
}
pub(super) fn file_item(db: &impl HirDatabase, source_item_id: SourceItemId) -> SyntaxNode {
match source_item_id.item_id {
Some(id) => db.file_items(source_item_id.file_id)[id].clone(),
None => db.source_file(source_item_id.file_id).syntax().owned(),
Some(id) => db.file_items(source_item_id.mfile_id)[id].clone(),
None => db.m_source_file(source_item_id.mfile_id).syntax().owned(),
}
}
@ -116,7 +128,7 @@ pub(super) fn input_module_items(
) -> Cancelable<Arc<InputModuleItems>> {
let module_tree = db.module_tree(source_root)?;
let source = module_id.source(&module_tree);
let file_items = db.file_items(source.file_id());
let file_items = db.file_items(source.file_id().into());
let res = match source.resolve(db) {
ModuleSourceNode::SourceFile(it) => {
let items = it.borrowed().items();

View File

@ -102,11 +102,11 @@ pub fn function_from_module(
module: &Module,
fn_def: ast::FnDef,
) -> Function {
let file_id = module.source().file_id();
let file_items = db.file_items(file_id);
let item_id = file_items.id_of(file_id, fn_def.syntax());
let mfile_id = module.source().file_id().into();
let file_items = db.file_items(mfile_id);
let item_id = file_items.id_of(mfile_id, fn_def.syntax());
let source_item_id = SourceItemId {
file_id,
mfile_id,
item_id: Some(item_id),
};
let def_loc = DefLoc {