}
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())
})
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)
}
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},
#[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>;
}
}
- 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,
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,
type_ref::TypeRef,
ids::LocationCtx,
resolve::Resolver,
- ty::Ty, generics::GenericParams
+ ty::Ty, generics::GenericParams,
};
use crate::code_model_api::{Module, ModuleSource};
}
}
let resolution = Resolution { def, import: Some(import_id) };
- self.update(module_id, None, &[(name, resolution)]);
+ self.update(module_id, Some(import_id), &[(name, resolution)]);
}
}
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;
use crate::{
PersistentHirDatabase, Name, AsName, Path, HirFileId,
ids::{SourceFileItemId, SourceFileItems},
+ nameres::lower::ImportSourceMap,
};
#[derive(Debug, Default, PartialEq, Eq)]
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] {
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
struct RawItemsCollector {
raw_items: RawItems,
source_file_items: Arc<SourceFileItems>,
+ source_map: ImportSourceMap,
}
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))
})
}
-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);
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))
}
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)
- }
- })
- }
-}
/// 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
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);
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);
}
}
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,
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))
}
[
Diagnostic {
message: "unresolved module",
- range: [4; 7),
+ range: [0; 8),
fix: Some(
SourceChange {
label: "create module",