Merge #245
245: File items r=matklad a=matklad Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
0bc6f5802f
7 changed files with 175 additions and 87 deletions
|
@ -46,9 +46,12 @@ pub(super) fn completions(
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|(_name, res)| {
|
.filter(|(_name, res)| {
|
||||||
// Don't expose this item
|
// Don't expose this item
|
||||||
match res.import_name {
|
match res.import {
|
||||||
None => true,
|
None => true,
|
||||||
Some(ptr) => !ptr.range().is_subrange(&name_ref.syntax().range()),
|
Some(import) => {
|
||||||
|
let range = import.range(db, module.source().file_id());
|
||||||
|
!range.is_subrange(&name_ref.syntax().range())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.map(|(name, _res)| CompletionItem {
|
.map(|(name, _res)| CompletionItem {
|
||||||
|
|
|
@ -7,10 +7,7 @@ use salsa::{self, Database};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
db,
|
db,
|
||||||
descriptors::{
|
descriptors,
|
||||||
DescriptorDatabase, FnScopesQuery, FnSyntaxQuery, ModuleTreeQuery,
|
|
||||||
SubmodulesQuery, ItemMapQuery, InputModuleItemsQuery,
|
|
||||||
},
|
|
||||||
symbol_index::SymbolIndex,
|
symbol_index::SymbolIndex,
|
||||||
syntax_ptr::SyntaxPtr,
|
syntax_ptr::SyntaxPtr,
|
||||||
loc2id::{IdMaps, IdDatabase},
|
loc2id::{IdMaps, IdDatabase},
|
||||||
|
@ -125,13 +122,15 @@ salsa::database_storage! {
|
||||||
fn file_symbols() for FileSymbolsQuery;
|
fn file_symbols() for FileSymbolsQuery;
|
||||||
fn resolve_syntax_ptr() for ResolveSyntaxPtrQuery;
|
fn resolve_syntax_ptr() for ResolveSyntaxPtrQuery;
|
||||||
}
|
}
|
||||||
impl DescriptorDatabase {
|
impl descriptors::DescriptorDatabase {
|
||||||
fn module_tree() for ModuleTreeQuery;
|
fn module_tree() for descriptors::ModuleTreeQuery;
|
||||||
fn fn_scopes() for FnScopesQuery;
|
fn fn_scopes() for descriptors::FnScopesQuery;
|
||||||
fn _input_module_items() for InputModuleItemsQuery;
|
fn _file_items() for descriptors::FileItemsQuery;
|
||||||
fn _item_map() for ItemMapQuery;
|
fn _file_item() for descriptors::FileItemQuery;
|
||||||
fn _fn_syntax() for FnSyntaxQuery;
|
fn _input_module_items() for descriptors::InputModuleItemsQuery;
|
||||||
fn _submodules() for SubmodulesQuery;
|
fn _item_map() for descriptors::ItemMapQuery;
|
||||||
|
fn _fn_syntax() for descriptors::FnSyntaxQuery;
|
||||||
|
fn _submodules() for descriptors::SubmodulesQuery;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,13 +6,14 @@ use std::sync::Arc;
|
||||||
|
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
ast::{self, FnDefNode, AstNode},
|
ast::{self, FnDefNode, AstNode},
|
||||||
TextRange,
|
TextRange, SyntaxNode,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
FileId,
|
||||||
db::SyntaxDatabase,
|
db::SyntaxDatabase,
|
||||||
descriptors::function::{resolve_local_name, FnId, FnScopes},
|
descriptors::function::{resolve_local_name, FnId, FnScopes},
|
||||||
descriptors::module::{ModuleId, ModuleTree, ModuleSource, nameres::{ItemMap, InputModuleItems}},
|
descriptors::module::{ModuleId, ModuleTree, ModuleSource, nameres::{ItemMap, InputModuleItems, FileItems}},
|
||||||
input::SourceRootId,
|
input::SourceRootId,
|
||||||
loc2id::IdDatabase,
|
loc2id::IdDatabase,
|
||||||
syntax_ptr::LocalSyntaxPtr,
|
syntax_ptr::LocalSyntaxPtr,
|
||||||
|
@ -20,6 +21,7 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) use self::path::{Path, PathKind};
|
pub(crate) use self::path::{Path, PathKind};
|
||||||
|
pub(crate) use self::module::nameres::FileItemId;
|
||||||
|
|
||||||
salsa::query_group! {
|
salsa::query_group! {
|
||||||
pub(crate) trait DescriptorDatabase: SyntaxDatabase + IdDatabase {
|
pub(crate) trait DescriptorDatabase: SyntaxDatabase + IdDatabase {
|
||||||
|
@ -28,6 +30,18 @@ salsa::query_group! {
|
||||||
use fn function::imp::fn_scopes;
|
use fn function::imp::fn_scopes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn _file_items(file_id: FileId) -> Arc<FileItems> {
|
||||||
|
type FileItemsQuery;
|
||||||
|
storage volatile;
|
||||||
|
use fn module::nameres::file_items;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _file_item(file_id: FileId, file_item_id: FileItemId) -> SyntaxNode {
|
||||||
|
type FileItemQuery;
|
||||||
|
storage volatile;
|
||||||
|
use fn module::nameres::file_item;
|
||||||
|
}
|
||||||
|
|
||||||
fn _input_module_items(source_root_id: SourceRootId, module_id: ModuleId) -> Cancelable<Arc<InputModuleItems>> {
|
fn _input_module_items(source_root_id: SourceRootId, module_id: ModuleId) -> Cancelable<Arc<InputModuleItems>> {
|
||||||
type InputModuleItemsQuery;
|
type InputModuleItemsQuery;
|
||||||
use fn module::nameres::input_module_items;
|
use fn module::nameres::input_module_items;
|
||||||
|
|
|
@ -17,27 +17,83 @@
|
||||||
use std::{
|
use std::{
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
time::Instant,
|
time::Instant,
|
||||||
|
ops::Index,
|
||||||
};
|
};
|
||||||
|
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
|
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
|
SyntaxNode, SyntaxNodeRef, TextRange,
|
||||||
SmolStr, SyntaxKind::{self, *},
|
SmolStr, SyntaxKind::{self, *},
|
||||||
ast::{self, ModuleItemOwner}
|
ast::{self, ModuleItemOwner, AstNode}
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Cancelable,
|
Cancelable, FileId,
|
||||||
loc2id::{DefId, DefLoc},
|
loc2id::{DefId, DefLoc},
|
||||||
descriptors::{
|
descriptors::{
|
||||||
Path, PathKind,
|
Path, PathKind,
|
||||||
DescriptorDatabase,
|
DescriptorDatabase,
|
||||||
module::{ModuleId, ModuleTree, ModuleSourceNode},
|
module::{ModuleId, ModuleTree, ModuleSourceNode},
|
||||||
},
|
},
|
||||||
syntax_ptr::{LocalSyntaxPtr},
|
|
||||||
input::SourceRootId,
|
input::SourceRootId,
|
||||||
|
arena::{Arena, Id}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Identifier of item within a specific file. This is stable over reparses, so
|
||||||
|
/// it's OK to use it as a salsa key/value.
|
||||||
|
pub(crate) type FileItemId = Id<SyntaxNode>;
|
||||||
|
|
||||||
|
/// Maps item's `SyntaxNode`s to `FileItemId` and back.
|
||||||
|
#[derive(Debug, PartialEq, Eq, Default)]
|
||||||
|
pub(crate) struct FileItems {
|
||||||
|
arena: Arena<SyntaxNode>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FileItems {
|
||||||
|
fn alloc(&mut self, item: SyntaxNode) -> FileItemId {
|
||||||
|
self.arena.alloc(item)
|
||||||
|
}
|
||||||
|
fn id_of(&self, item: SyntaxNodeRef) -> FileItemId {
|
||||||
|
let (id, _item) = self
|
||||||
|
.arena
|
||||||
|
.iter()
|
||||||
|
.find(|(_id, i)| i.borrowed() == item)
|
||||||
|
.unwrap();
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Index<FileItemId> for FileItems {
|
||||||
|
type Output = SyntaxNode;
|
||||||
|
fn index(&self, idx: FileItemId) -> &SyntaxNode {
|
||||||
|
&self.arena[idx]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn file_items(db: &impl DescriptorDatabase, file_id: FileId) -> Arc<FileItems> {
|
||||||
|
let source_file = db.file_syntax(file_id);
|
||||||
|
let source_file = source_file.borrowed();
|
||||||
|
let mut res = FileItems::default();
|
||||||
|
source_file
|
||||||
|
.syntax()
|
||||||
|
.descendants()
|
||||||
|
.filter_map(ast::ModuleItem::cast)
|
||||||
|
.map(|it| it.syntax().owned())
|
||||||
|
.for_each(|it| {
|
||||||
|
res.alloc(it);
|
||||||
|
});
|
||||||
|
Arc::new(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn file_item(
|
||||||
|
db: &impl DescriptorDatabase,
|
||||||
|
file_id: FileId,
|
||||||
|
file_item_id: FileItemId,
|
||||||
|
) -> SyntaxNode {
|
||||||
|
db._file_items(file_id)[file_item_id].clone()
|
||||||
|
}
|
||||||
|
|
||||||
/// Item map is the result of the name resolution. Item map contains, for each
|
/// Item map is the result of the name resolution. Item map contains, for each
|
||||||
/// module, the set of visible items.
|
/// module, the set of visible items.
|
||||||
#[derive(Default, Debug, PartialEq, Eq)]
|
#[derive(Default, Debug, PartialEq, Eq)]
|
||||||
|
@ -62,17 +118,44 @@ pub(crate) struct InputModuleItems {
|
||||||
imports: Vec<Import>,
|
imports: Vec<Import>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
|
struct ModuleItem {
|
||||||
|
id: FileItemId,
|
||||||
|
name: SmolStr,
|
||||||
|
kind: SyntaxKind,
|
||||||
|
vis: Vis,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
|
enum Vis {
|
||||||
|
// Priv,
|
||||||
|
Other,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
struct Import {
|
struct Import {
|
||||||
path: Path,
|
path: Path,
|
||||||
kind: ImportKind,
|
kind: ImportKind,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
pub(crate) struct NamedImport {
|
||||||
|
file_item_id: FileItemId,
|
||||||
|
relative_range: TextRange,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NamedImport {
|
||||||
|
pub(crate) fn range(&self, db: &impl DescriptorDatabase, file_id: FileId) -> TextRange {
|
||||||
|
let syntax = db._file_item(file_id, self.file_item_id);
|
||||||
|
let offset = syntax.borrowed().range().start();
|
||||||
|
self.relative_range + offset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
enum ImportKind {
|
enum ImportKind {
|
||||||
Glob,
|
Glob,
|
||||||
// TODO: make offset independent
|
Named(NamedImport),
|
||||||
Named(LocalSyntaxPtr),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn input_module_items(
|
pub(crate) fn input_module_items(
|
||||||
|
@ -82,10 +165,11 @@ pub(crate) fn input_module_items(
|
||||||
) -> Cancelable<Arc<InputModuleItems>> {
|
) -> Cancelable<Arc<InputModuleItems>> {
|
||||||
let module_tree = db._module_tree(source_root)?;
|
let module_tree = db._module_tree(source_root)?;
|
||||||
let source = module_id.source(&module_tree);
|
let source = module_id.source(&module_tree);
|
||||||
|
let file_items = db._file_items(source.file_id());
|
||||||
let res = match source.resolve(db) {
|
let res = match source.resolve(db) {
|
||||||
ModuleSourceNode::SourceFile(it) => {
|
ModuleSourceNode::SourceFile(it) => {
|
||||||
let items = it.borrowed().items();
|
let items = it.borrowed().items();
|
||||||
InputModuleItems::new(items)
|
InputModuleItems::new(&file_items, items)
|
||||||
}
|
}
|
||||||
ModuleSourceNode::Module(it) => {
|
ModuleSourceNode::Module(it) => {
|
||||||
let items = it
|
let items = it
|
||||||
|
@ -93,7 +177,7 @@ pub(crate) fn input_module_items(
|
||||||
.item_list()
|
.item_list()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flat_map(|it| it.items());
|
.flat_map(|it| it.items());
|
||||||
InputModuleItems::new(items)
|
InputModuleItems::new(&file_items, items)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Ok(Arc::new(res))
|
Ok(Arc::new(res))
|
||||||
|
@ -112,7 +196,6 @@ pub(crate) fn item_map(
|
||||||
Ok((id, items))
|
Ok((id, items))
|
||||||
})
|
})
|
||||||
.collect::<Cancelable<FxHashMap<_, _>>>()?;
|
.collect::<Cancelable<FxHashMap<_, _>>>()?;
|
||||||
|
|
||||||
let mut resolver = Resolver {
|
let mut resolver = Resolver {
|
||||||
db: db,
|
db: db,
|
||||||
input: &input,
|
input: &input,
|
||||||
|
@ -134,8 +217,7 @@ pub(crate) struct Resolution {
|
||||||
/// None for unresolved
|
/// None for unresolved
|
||||||
pub(crate) def_id: Option<DefId>,
|
pub(crate) def_id: Option<DefId>,
|
||||||
/// ident by whitch this is imported into local scope.
|
/// ident by whitch this is imported into local scope.
|
||||||
/// TODO: make this offset-independent.
|
pub(crate) import: Option<NamedImport>,
|
||||||
pub(crate) import_name: Option<LocalSyntaxPtr>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
// #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
@ -150,55 +232,49 @@ pub(crate) struct Resolution {
|
||||||
// values: Option<T>,
|
// values: Option<T>,
|
||||||
// }
|
// }
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
|
||||||
struct ModuleItem {
|
|
||||||
ptr: LocalSyntaxPtr,
|
|
||||||
name: SmolStr,
|
|
||||||
kind: SyntaxKind,
|
|
||||||
vis: Vis,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
|
||||||
enum Vis {
|
|
||||||
// Priv,
|
|
||||||
Other,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl InputModuleItems {
|
impl InputModuleItems {
|
||||||
fn new<'a>(items: impl Iterator<Item = ast::ModuleItem<'a>>) -> InputModuleItems {
|
fn new<'a>(
|
||||||
|
file_items: &FileItems,
|
||||||
|
items: impl Iterator<Item = ast::ModuleItem<'a>>,
|
||||||
|
) -> InputModuleItems {
|
||||||
let mut res = InputModuleItems::default();
|
let mut res = InputModuleItems::default();
|
||||||
for item in items {
|
for item in items {
|
||||||
res.add_item(item);
|
res.add_item(file_items, item);
|
||||||
}
|
}
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_item(&mut self, item: ast::ModuleItem) -> Option<()> {
|
fn add_item(&mut self, file_items: &FileItems, item: ast::ModuleItem) -> Option<()> {
|
||||||
match item {
|
match item {
|
||||||
ast::ModuleItem::StructDef(it) => self.items.push(ModuleItem::new(it)?),
|
ast::ModuleItem::StructDef(it) => self.items.push(ModuleItem::new(file_items, it)?),
|
||||||
ast::ModuleItem::EnumDef(it) => self.items.push(ModuleItem::new(it)?),
|
ast::ModuleItem::EnumDef(it) => self.items.push(ModuleItem::new(file_items, it)?),
|
||||||
ast::ModuleItem::FnDef(it) => self.items.push(ModuleItem::new(it)?),
|
ast::ModuleItem::FnDef(it) => self.items.push(ModuleItem::new(file_items, it)?),
|
||||||
ast::ModuleItem::TraitDef(it) => self.items.push(ModuleItem::new(it)?),
|
ast::ModuleItem::TraitDef(it) => self.items.push(ModuleItem::new(file_items, it)?),
|
||||||
ast::ModuleItem::TypeDef(it) => self.items.push(ModuleItem::new(it)?),
|
ast::ModuleItem::TypeDef(it) => self.items.push(ModuleItem::new(file_items, it)?),
|
||||||
ast::ModuleItem::ImplItem(_) => {
|
ast::ModuleItem::ImplItem(_) => {
|
||||||
// impls don't define items
|
// impls don't define items
|
||||||
}
|
}
|
||||||
ast::ModuleItem::UseItem(it) => self.add_use_item(it),
|
ast::ModuleItem::UseItem(it) => self.add_use_item(file_items, it),
|
||||||
ast::ModuleItem::ExternCrateItem(_) => {
|
ast::ModuleItem::ExternCrateItem(_) => {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
ast::ModuleItem::ConstDef(it) => self.items.push(ModuleItem::new(it)?),
|
ast::ModuleItem::ConstDef(it) => self.items.push(ModuleItem::new(file_items, it)?),
|
||||||
ast::ModuleItem::StaticDef(it) => self.items.push(ModuleItem::new(it)?),
|
ast::ModuleItem::StaticDef(it) => self.items.push(ModuleItem::new(file_items, it)?),
|
||||||
ast::ModuleItem::Module(it) => self.items.push(ModuleItem::new(it)?),
|
ast::ModuleItem::Module(it) => self.items.push(ModuleItem::new(file_items, it)?),
|
||||||
}
|
}
|
||||||
Some(())
|
Some(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_use_item(&mut self, item: ast::UseItem) {
|
fn add_use_item(&mut self, file_items: &FileItems, item: ast::UseItem) {
|
||||||
Path::expand_use_item(item, |path, ptr| {
|
let file_item_id = file_items.id_of(item.syntax());
|
||||||
let kind = match ptr {
|
let start_offset = item.syntax().range().start();
|
||||||
|
Path::expand_use_item(item, |path, range| {
|
||||||
|
let kind = match range {
|
||||||
None => ImportKind::Glob,
|
None => ImportKind::Glob,
|
||||||
Some(ptr) => ImportKind::Named(ptr),
|
Some(range) => ImportKind::Named(NamedImport {
|
||||||
|
file_item_id,
|
||||||
|
relative_range: range - start_offset,
|
||||||
|
}),
|
||||||
};
|
};
|
||||||
self.imports.push(Import { kind, path })
|
self.imports.push(Import { kind, path })
|
||||||
})
|
})
|
||||||
|
@ -206,13 +282,13 @@ impl InputModuleItems {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ModuleItem {
|
impl ModuleItem {
|
||||||
fn new<'a>(item: impl ast::NameOwner<'a>) -> Option<ModuleItem> {
|
fn new<'a>(file_items: &FileItems, item: impl ast::NameOwner<'a>) -> Option<ModuleItem> {
|
||||||
let name = item.name()?.text();
|
let name = item.name()?.text();
|
||||||
let ptr = LocalSyntaxPtr::new(item.syntax());
|
|
||||||
let kind = item.syntax().kind();
|
let kind = item.syntax().kind();
|
||||||
let vis = Vis::Other;
|
let vis = Vis::Other;
|
||||||
|
let id = file_items.id_of(item.syntax());
|
||||||
let res = ModuleItem {
|
let res = ModuleItem {
|
||||||
ptr,
|
id,
|
||||||
name,
|
name,
|
||||||
kind,
|
kind,
|
||||||
vis,
|
vis,
|
||||||
|
@ -252,12 +328,12 @@ where
|
||||||
|
|
||||||
for import in input.imports.iter() {
|
for import in input.imports.iter() {
|
||||||
if let Some(name) = import.path.segments.iter().last() {
|
if let Some(name) = import.path.segments.iter().last() {
|
||||||
if let ImportKind::Named(ptr) = import.kind {
|
if let ImportKind::Named(import) = import.kind {
|
||||||
module_items.items.insert(
|
module_items.items.insert(
|
||||||
name.clone(),
|
name.clone(),
|
||||||
Resolution {
|
Resolution {
|
||||||
def_id: None,
|
def_id: None,
|
||||||
import_name: Some(ptr),
|
import: Some(import),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -269,12 +345,14 @@ where
|
||||||
// handle submodules separatelly
|
// handle submodules separatelly
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let ptr = item.ptr.into_global(file_id);
|
let def_loc = DefLoc::Item {
|
||||||
let def_loc = DefLoc::Item { ptr };
|
file_id,
|
||||||
|
id: item.id,
|
||||||
|
};
|
||||||
let def_id = self.db.id_maps().def_id(def_loc);
|
let def_id = self.db.id_maps().def_id(def_loc);
|
||||||
let resolution = Resolution {
|
let resolution = Resolution {
|
||||||
def_id: Some(def_id),
|
def_id: Some(def_id),
|
||||||
import_name: None,
|
import: None,
|
||||||
};
|
};
|
||||||
module_items.items.insert(item.name.clone(), resolution);
|
module_items.items.insert(item.name.clone(), resolution);
|
||||||
}
|
}
|
||||||
|
@ -287,7 +365,7 @@ where
|
||||||
let def_id = self.db.id_maps().def_id(def_loc);
|
let def_id = self.db.id_maps().def_id(def_loc);
|
||||||
let resolution = Resolution {
|
let resolution = Resolution {
|
||||||
def_id: Some(def_id),
|
def_id: Some(def_id),
|
||||||
import_name: None,
|
import: None,
|
||||||
};
|
};
|
||||||
module_items.items.insert(name, resolution);
|
module_items.items.insert(name, resolution);
|
||||||
}
|
}
|
||||||
|
@ -341,7 +419,7 @@ where
|
||||||
self.update(module_id, |items| {
|
self.update(module_id, |items| {
|
||||||
let res = Resolution {
|
let res = Resolution {
|
||||||
def_id: Some(def_id),
|
def_id: Some(def_id),
|
||||||
import_name: Some(ptr),
|
import: Some(ptr),
|
||||||
};
|
};
|
||||||
items.items.insert(name.clone(), res);
|
items.items.insert(name.clone(), res);
|
||||||
})
|
})
|
||||||
|
@ -452,10 +530,11 @@ mod tests {
|
||||||
let events = db.log_executed(|| {
|
let events = db.log_executed(|| {
|
||||||
db._item_map(source_root).unwrap();
|
db._item_map(source_root).unwrap();
|
||||||
});
|
});
|
||||||
// assert!(
|
assert!(
|
||||||
// !format!("{:?}", events).contains("_item_map"),
|
!format!("{:?}", events).contains("_item_map"),
|
||||||
// "{:#?}", events
|
"{:#?}",
|
||||||
// )
|
events
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
use ra_syntax::{SmolStr, ast, AstNode};
|
use ra_syntax::{SmolStr, ast, AstNode, TextRange};
|
||||||
|
|
||||||
use crate::syntax_ptr::LocalSyntaxPtr;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub(crate) struct Path {
|
pub(crate) struct Path {
|
||||||
|
@ -18,10 +16,7 @@ pub(crate) enum PathKind {
|
||||||
|
|
||||||
impl Path {
|
impl Path {
|
||||||
/// Calls `cb` with all paths, represented by this use item.
|
/// Calls `cb` with all paths, represented by this use item.
|
||||||
pub(crate) fn expand_use_item(
|
pub(crate) fn expand_use_item(item: ast::UseItem, mut cb: impl FnMut(Path, Option<TextRange>)) {
|
||||||
item: ast::UseItem,
|
|
||||||
mut cb: impl FnMut(Path, Option<LocalSyntaxPtr>),
|
|
||||||
) {
|
|
||||||
if let Some(tree) = item.use_tree() {
|
if let Some(tree) = item.use_tree() {
|
||||||
expand_use_tree(None, tree, &mut cb);
|
expand_use_tree(None, tree, &mut cb);
|
||||||
}
|
}
|
||||||
|
@ -77,7 +72,7 @@ impl Path {
|
||||||
fn expand_use_tree(
|
fn expand_use_tree(
|
||||||
prefix: Option<Path>,
|
prefix: Option<Path>,
|
||||||
tree: ast::UseTree,
|
tree: ast::UseTree,
|
||||||
cb: &mut impl FnMut(Path, Option<LocalSyntaxPtr>),
|
cb: &mut impl FnMut(Path, Option<TextRange>),
|
||||||
) {
|
) {
|
||||||
if let Some(use_tree_list) = tree.use_tree_list() {
|
if let Some(use_tree_list) = tree.use_tree_list() {
|
||||||
let prefix = match tree.path() {
|
let prefix = match tree.path() {
|
||||||
|
@ -93,13 +88,13 @@ fn expand_use_tree(
|
||||||
} else {
|
} else {
|
||||||
if let Some(ast_path) = tree.path() {
|
if let Some(ast_path) = tree.path() {
|
||||||
if let Some(path) = convert_path(prefix, ast_path) {
|
if let Some(path) = convert_path(prefix, ast_path) {
|
||||||
let ptr = if tree.has_star() {
|
let range = if tree.has_star() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
let ptr = LocalSyntaxPtr::new(ast_path.segment().unwrap().syntax());
|
let range = ast_path.segment().unwrap().syntax().range();
|
||||||
Some(ptr)
|
Some(range)
|
||||||
};
|
};
|
||||||
cb(path, ptr)
|
cb(path, range)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,8 @@ use std::{
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
FileId,
|
||||||
|
descriptors::FileItemId,
|
||||||
descriptors::module::ModuleId,
|
descriptors::module::ModuleId,
|
||||||
syntax_ptr::SyntaxPtr,
|
syntax_ptr::SyntaxPtr,
|
||||||
input::SourceRootId,
|
input::SourceRootId,
|
||||||
|
@ -102,7 +104,8 @@ pub(crate) enum DefLoc {
|
||||||
source_root: SourceRootId,
|
source_root: SourceRootId,
|
||||||
},
|
},
|
||||||
Item {
|
Item {
|
||||||
ptr: SyntaxPtr,
|
file_id: FileId,
|
||||||
|
id: FileItemId,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,11 +62,6 @@ impl LocalSyntaxPtr {
|
||||||
local: self,
|
local: self,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Seems unfortunate to expose
|
|
||||||
pub(crate) fn range(self) -> TextRange {
|
|
||||||
self.range
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Reference in a new issue