use MFile
This commit is contained in:
parent
4161466918
commit
289391e163
@ -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 @@ fn type_for_field(def_id: DefId, field: Name) -> Cancelable<Ty> {
|
||||
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;
|
||||
}
|
||||
|
@ -57,11 +57,18 @@ macro_rules! ctry {
|
||||
|
||||
/// 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 fn module(self, db: &impl HirDatabase) -> Cancelable<Module> {
|
||||
|
||||
#[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 @@ fn init(&mut self, source_file: SourceFile) {
|
||||
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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
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 @@ pub(crate) fn new_inline(
|
||||
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 {
|
||||
|
@ -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 @@ fn populate_module(&mut self, module_id: ModuleId, input: &InputModuleItems) ->
|
||||
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 @@ fn populate_module(&mut self, module_id: ModuleId, input: &InputModuleItems) ->
|
||||
source_root_id: self.source_root,
|
||||
module_id,
|
||||
source_item_id: SourceItemId {
|
||||
file_id,
|
||||
mfile_id: file_id.into(),
|
||||
item_id: Some(item.id),
|
||||
},
|
||||
};
|
||||
|
@ -5,13 +5,13 @@
|
||||
|
||||
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();
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user