remove lower module
This commit is contained in:
parent
c7259a899c
commit
b2a6c17362
@ -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())
|
||||
})
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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>;
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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};
|
||||
|
@ -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;
|
||||
|
@ -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))
|
||||
})
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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",
|
||||
|
Loading…
x
Reference in New Issue
Block a user