remove lower module

This commit is contained in:
Aleksey Kladov 2019-03-14 13:14:54 +03:00
parent c7259a899c
commit b2a6c17362
12 changed files with 48 additions and 264 deletions

View File

@ -186,11 +186,11 @@ impl Module {
}
pub fn declarations(self, db: &impl HirDatabase) -> Vec<ModuleDef> {
let lowered_module = db.lower_module(self);
lowered_module
.declarations
.values()
.cloned()
let def_map = db.crate_def_map(self.krate);
def_map[self.module_id]
.scope
.entries()
.filter_map(|(_name, res)| if res.import.is_none() { Some(res.def) } else { None })
.flat_map(|per_ns| {
per_ns.take_types().into_iter().chain(per_ns.take_values().into_iter())
})

View File

@ -76,8 +76,8 @@ impl Module {
db: &impl HirDatabase,
import: ImportId,
) -> TreeArc<ast::PathSegment> {
let (_, source_map) = db.lower_module_with_source_map(*self);
let (_, source) = self.definition_source(db);
let (file_id, source) = self.definition_source(db);
let (_, source_map) = db.raw_items_with_source_map(file_id.original_file(db));
source_map.get(&source, import)
}

View File

@ -10,7 +10,7 @@ use crate::{
Struct, Enum, StructField,
Const, ConstSignature, Static,
macros::MacroExpansion,
nameres::{Namespace, lower::{LoweredModule, ImportSourceMap}, crate_def_map::{RawItems, CrateDefMap}},
nameres::{Namespace, lower::{ImportSourceMap}, crate_def_map::{RawItems, CrateDefMap}},
ty::{InferenceResult, Ty, method_resolution::CrateImplBlocks, TypableDef, CallableDef, FnSig},
adt::{StructData, EnumData},
impl_block::{ModuleImplBlocks, ImplSourceMap},
@ -38,18 +38,12 @@ pub trait PersistentHirDatabase: SourceDatabase + AsRef<HirInterner> {
#[salsa::invoke(crate::ids::SourceFileItems::file_item_query)]
fn file_item(&self, source_item_id: SourceItemId) -> TreeArc<SyntaxNode>;
#[salsa::invoke(crate::nameres::lower::LoweredModule::lower_module_with_source_map_query)]
fn lower_module_with_source_map(
&self,
module: Module,
) -> (Arc<LoweredModule>, Arc<ImportSourceMap>);
#[salsa::invoke(crate::nameres::lower::LoweredModule::lower_module_query)]
fn lower_module(&self, module: Module) -> Arc<LoweredModule>;
#[salsa::invoke(RawItems::raw_items_query)]
fn raw_items(&self, file_id: FileId) -> Arc<RawItems>;
#[salsa::invoke(RawItems::raw_items_with_source_map_query)]
fn raw_items_with_source_map(&self, file_id: FileId) -> (Arc<RawItems>, Arc<ImportSourceMap>);
#[salsa::invoke(CrateDefMap::crate_def_map_query)]
fn crate_def_map(&self, krate: Crate) -> Arc<CrateDefMap>;

View File

@ -83,13 +83,6 @@ impl HirFileId {
}
}
pub(crate) fn as_macro_call_id(self) -> Option<MacroCallId> {
match self.0 {
HirFileIdRepr::Macro(it) => Some(it),
_ => None,
}
}
pub(crate) fn hir_parse(
db: &impl PersistentHirDatabase,
file_id: HirFileId,

View File

@ -4,7 +4,8 @@ use rustc_hash::FxHashMap;
use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap};
use ra_syntax::{
AstPtr, SourceFile, TreeArc,
ast::{self, AstNode}};
ast::{self, AstNode}
};
use crate::{
Const, TypeAlias, Function, HirFileId,
@ -13,7 +14,7 @@ use crate::{
type_ref::TypeRef,
ids::LocationCtx,
resolve::Resolver,
ty::Ty, generics::GenericParams
ty::Ty, generics::GenericParams,
};
use crate::code_model_api::{Module, ModuleSource};

View File

@ -224,7 +224,7 @@ where
}
}
let resolution = Resolution { def, import: Some(import_id) };
self.update(module_id, None, &[(name, resolution)]);
self.update(module_id, Some(import_id), &[(name, resolution)]);
}
}
@ -262,6 +262,13 @@ where
existing.import = import.or(res.import);
changed = true;
}
if existing.def.is_none()
&& res.def.is_none()
&& existing.import.is_none()
&& res.import.is_some()
{
existing.import = res.import;
}
}
if !changed {
return;

View File

@ -14,6 +14,7 @@ use ra_syntax::{
use crate::{
PersistentHirDatabase, Name, AsName, Path, HirFileId,
ids::{SourceFileItemId, SourceFileItems},
nameres::lower::ImportSourceMap,
};
#[derive(Debug, Default, PartialEq, Eq)]
@ -31,13 +32,21 @@ impl RawItems {
db: &impl PersistentHirDatabase,
file_id: FileId,
) -> Arc<RawItems> {
db.raw_items_with_source_map(file_id).0
}
pub(crate) fn raw_items_with_source_map_query(
db: &impl PersistentHirDatabase,
file_id: FileId,
) -> (Arc<RawItems>, Arc<ImportSourceMap>) {
let mut collector = RawItemsCollector {
raw_items: RawItems::default(),
source_file_items: db.file_items(file_id.into()),
source_map: ImportSourceMap::default(),
};
let source_file = db.parse(file_id);
collector.process_module(None, &*source_file);
Arc::new(collector.raw_items)
(Arc::new(collector.raw_items), Arc::new(collector.source_map))
}
pub(crate) fn items(&self) -> &[RawItem] {
@ -51,6 +60,7 @@ impl RawItems {
let mut collector = RawItemsCollector {
raw_items: RawItems::default(),
source_file_items: Arc::new(source_file_items),
source_map: ImportSourceMap::default(),
};
collector.process_module(None, &*source_file);
collector.raw_items
@ -144,6 +154,7 @@ pub(crate) struct MacroData {
struct RawItemsCollector {
raw_items: RawItems,
source_file_items: Arc<SourceFileItems>,
source_map: ImportSourceMap,
}
impl RawItemsCollector {
@ -227,6 +238,9 @@ impl RawItemsCollector {
is_prelude,
is_extern_crate: false,
});
if let Some(segment) = segment {
self.source_map.insert(import, segment)
}
self.push_item(current_module, RawItem::Import(import))
})
}

View File

@ -1,18 +1,10 @@
use std::sync::Arc;
use ra_syntax::{
AstNode, SourceFile, TreeArc, AstPtr,
ast::{self, ModuleItemOwner, NameOwner, AttrsOwner},
ast,
};
use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap};
use rustc_hash::FxHashMap;
use ra_arena::{RawId, impl_arena_id, map::ArenaMap};
use crate::{
SourceItemId, Path, ModuleSource, Name,
HirFileId, MacroCallLoc, AsName, PerNs, Function,
ModuleDef, Module, Struct, Enum, Const, Static, Trait, TypeAlias,
ids::LocationCtx, PersistentHirDatabase,
};
use crate::{Path, ModuleSource, Name};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct ImportId(RawId);
@ -27,25 +19,13 @@ pub struct ImportData {
pub(super) is_extern_crate: bool,
}
/// A set of items and imports declared inside a module, without relation to
/// other modules.
///
/// This sits in-between raw syntax and name resolution and allows us to avoid
/// recomputing name res: if two instance of `InputModuleItems` are the same, we
/// can avoid redoing name resolution.
#[derive(Debug, Default, PartialEq, Eq)]
pub struct LoweredModule {
pub(crate) declarations: FxHashMap<Name, PerNs<ModuleDef>>,
pub(super) imports: Arena<ImportId, ImportData>,
}
#[derive(Debug, Default, PartialEq, Eq)]
pub struct ImportSourceMap {
map: ArenaMap<ImportId, AstPtr<ast::PathSegment>>,
}
impl ImportSourceMap {
fn insert(&mut self, import: ImportId, segment: &ast::PathSegment) {
pub(crate) fn insert(&mut self, import: ImportId, segment: &ast::PathSegment) {
self.map.insert(import, AstPtr::new(segment))
}
@ -58,165 +38,3 @@ impl ImportSourceMap {
self.map[import].to_node(file).to_owned()
}
}
impl LoweredModule {
pub(crate) fn lower_module_query(
db: &impl PersistentHirDatabase,
module: Module,
) -> Arc<LoweredModule> {
db.lower_module_with_source_map(module).0
}
pub(crate) fn lower_module_with_source_map_query(
db: &impl PersistentHirDatabase,
module: Module,
) -> (Arc<LoweredModule>, Arc<ImportSourceMap>) {
let (file_id, source) = module.definition_source(db);
let file_id: HirFileId = file_id.into();
let mut source_map = ImportSourceMap::default();
let mut res = LoweredModule::default();
match source {
ModuleSource::SourceFile(it) => {
res.fill(&mut source_map, db, module, file_id, &mut it.items_with_macros())
}
ModuleSource::Module(it) => {
if let Some(item_list) = it.item_list() {
res.fill(
&mut source_map,
db,
module,
file_id,
&mut item_list.items_with_macros(),
)
}
}
};
(Arc::new(res), Arc::new(source_map))
}
fn fill(
&mut self,
source_map: &mut ImportSourceMap,
db: &impl PersistentHirDatabase,
module: Module,
file_id: HirFileId,
items: &mut Iterator<Item = ast::ItemOrMacro>,
) {
let file_items = db.file_items(file_id);
for item in items {
match item {
ast::ItemOrMacro::Item(it) => {
self.add_def_id(source_map, db, module, file_id, it);
}
ast::ItemOrMacro::Macro(macro_call) => {
let item_id = file_items.id_of_unchecked(macro_call.syntax());
let loc =
MacroCallLoc { module, source_item_id: SourceItemId { file_id, item_id } };
let id = loc.id(db);
let file_id = HirFileId::from(id);
//FIXME: expand recursively
for item in db.hir_parse(file_id).items() {
self.add_def_id(source_map, db, module, file_id, item);
}
}
}
}
}
fn add_def_id(
&mut self,
source_map: &mut ImportSourceMap,
db: &impl PersistentHirDatabase,
module: Module,
file_id: HirFileId,
item: &ast::ModuleItem,
) {
let ctx = LocationCtx::new(db, module, file_id);
match item.kind() {
ast::ModuleItemKind::StructDef(it) => {
if let Some(name) = it.name() {
let s = Struct { id: ctx.to_def(it) };
let s: ModuleDef = s.into();
self.declarations.insert(name.as_name(), PerNs::both(s, s));
}
}
ast::ModuleItemKind::EnumDef(it) => {
if let Some(name) = it.name() {
let e = Enum { id: ctx.to_def(it) };
let e: ModuleDef = e.into();
self.declarations.insert(name.as_name(), PerNs::types(e));
}
}
ast::ModuleItemKind::FnDef(it) => {
if let Some(name) = it.name() {
let func = Function { id: ctx.to_def(it) };
self.declarations.insert(name.as_name(), PerNs::values(func.into()));
}
}
ast::ModuleItemKind::TraitDef(it) => {
if let Some(name) = it.name() {
let t = Trait { id: ctx.to_def(it) };
self.declarations.insert(name.as_name(), PerNs::types(t.into()));
}
}
ast::ModuleItemKind::TypeAliasDef(it) => {
if let Some(name) = it.name() {
let t = TypeAlias { id: ctx.to_def(it) };
self.declarations.insert(name.as_name(), PerNs::types(t.into()));
}
}
ast::ModuleItemKind::ImplBlock(_) => {
// impls don't define items
}
ast::ModuleItemKind::UseItem(it) => {
self.add_use_item(source_map, it);
}
ast::ModuleItemKind::ExternCrateItem(it) => {
if let Some(name_ref) = it.name_ref() {
let path = Path::from_name_ref(name_ref);
let alias = it.alias().and_then(|a| a.name()).map(AsName::as_name);
self.imports.alloc(ImportData {
path,
alias,
is_glob: false,
is_prelude: false,
is_extern_crate: true,
});
}
}
ast::ModuleItemKind::ConstDef(it) => {
if let Some(name) = it.name() {
let c = Const { id: ctx.to_def(it) };
self.declarations.insert(name.as_name(), PerNs::values(c.into()));
}
}
ast::ModuleItemKind::StaticDef(it) => {
if let Some(name) = it.name() {
let s = Static { id: ctx.to_def(it) };
self.declarations.insert(name.as_name(), PerNs::values(s.into()));
}
}
ast::ModuleItemKind::Module(_) => {
// modules are handled separately directly by name res
}
};
}
fn add_use_item(&mut self, source_map: &mut ImportSourceMap, item: &ast::UseItem) {
let is_prelude =
item.attrs().any(|attr| attr.as_atom().map(|s| s == "prelude_import").unwrap_or(false));
Path::expand_use_item(item, |path, segment, alias| {
let import = self.imports.alloc(ImportData {
path,
alias,
is_glob: segment.is_none(),
is_prelude,
is_extern_crate: false,
});
if let Some(segment) = segment {
source_map.insert(import, segment)
}
})
}
}

View File

@ -7,13 +7,13 @@
/// purely for "IDE needs".
use ra_db::{FileId, FilePosition};
use ra_syntax::{
SmolStr, TextRange, SyntaxNode,
SyntaxNode,
ast::{self, AstNode, NameOwner},
algo::{find_node_at_offset, find_leaf_at_offset},
};
use crate::{
HirDatabase, Function, ModuleDef, Struct, Enum,
HirDatabase, Function, Struct, Enum,
AsName, Module, HirFileId, Crate, Trait, Resolver,
ids::{LocationCtx, SourceFileItemId},
expr
@ -152,44 +152,6 @@ pub fn trait_from_module(
Trait { id: ctx.to_def(trait_def) }
}
pub fn macro_symbols(db: &impl HirDatabase, file_id: FileId) -> Vec<(SmolStr, TextRange)> {
let module = match module_from_file_id(db, file_id) {
Some(it) => it,
None => return Vec::new(),
};
let items = db.lower_module(module);
let mut res = Vec::new();
for macro_call_id in items
.declarations
.iter()
.filter_map(|(_, it)| it.clone().take_types())
.filter_map(|it| match it {
ModuleDef::Trait(it) => Some(it),
_ => None,
})
.filter_map(|it| it.source(db).0.as_macro_call_id())
{
if let Some(exp) = db.expand_macro_invocation(macro_call_id) {
let loc = macro_call_id.loc(db);
let syntax = db.file_item(loc.source_item_id);
let macro_call = ast::MacroCall::cast(&syntax).unwrap();
let off = macro_call.token_tree().unwrap().syntax().range().start();
let file = exp.file();
for trait_def in file.syntax().descendants().filter_map(ast::TraitDef::cast) {
if let Some(name) = trait_def.name() {
let dst_range = name.syntax().range();
if let Some(src_range) = exp.map_range_back(dst_range) {
res.push((name.text().clone(), src_range + off))
}
}
}
}
}
res
}
pub fn resolver_for_position(db: &impl HirDatabase, position: FilePosition) -> Resolver {
let file_id = position.file_id;
let file = db.parse(file_id);

View File

@ -223,7 +223,7 @@ impl RootDatabase {
self.query(hir::db::FileItemsQuery).sweep(sweep);
self.query(hir::db::FileItemQuery).sweep(sweep);
self.query(hir::db::LowerModuleWithSourceMapQuery).sweep(sweep);
self.query(hir::db::RawItemsWithSourceMapQuery).sweep(sweep);
self.query(hir::db::BodyWithSourceMapQuery).sweep(sweep);
}
}

View File

@ -30,7 +30,7 @@ use std::{
use fst::{self, Streamer};
use ra_syntax::{
SyntaxNode, SyntaxNodePtr, SourceFile, SmolStr, TreeArc, AstNode,
algo::{visit::{visitor, Visitor}, find_covering_node},
algo::{visit::{visitor, Visitor}},
SyntaxKind::{self, *},
ast::{self, NameOwner},
WalkEvent,
@ -66,14 +66,9 @@ fn file_symbols(db: &impl SymbolsDatabase, file_id: FileId) -> Arc<SymbolIndex>
db.check_canceled();
let source_file = db.parse(file_id);
let mut symbols = source_file_to_file_symbols(&source_file, file_id);
let symbols = source_file_to_file_symbols(&source_file, file_id);
for (name, text_range) in hir::source_binder::macro_symbols(db, file_id) {
let node = find_covering_node(source_file.syntax(), text_range);
let ptr = SyntaxNodePtr::new(node);
// TODO: Should we get container name for macro symbols?
symbols.push(FileSymbol { file_id, name, ptr, name_range: None, container_name: None })
}
// TODO: add macros here
Arc::new(SymbolIndex::new(symbols))
}

View File

@ -7,7 +7,7 @@ source: "crates\\ra_ide_api\\tests\\test\\main.rs"
[
Diagnostic {
message: "unresolved module",
range: [4; 7),
range: [0; 8),
fix: Some(
SourceChange {
label: "create module",