mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-02 07:22:42 +00:00
wip
This commit is contained in:
parent
dca8f612d0
commit
0447be7589
@ -40,16 +40,13 @@ use hir_def::{
|
||||
adt::{ReprKind, VariantData},
|
||||
body::{BodyDiagnostic, SyntheticSyntax},
|
||||
expr::{BindingAnnotation, LabelId, Pat, PatId},
|
||||
item_tree::ItemTreeNode,
|
||||
lang_item::LangItemTarget,
|
||||
nameres,
|
||||
per_ns::PerNs,
|
||||
resolver::{HasResolver, Resolver},
|
||||
src::HasSource as _,
|
||||
AdtId, AssocContainerId, AssocItemId, AssocItemLoc, AttrDefId, ConstId, ConstParamId,
|
||||
DefWithBodyId, EnumId, FunctionId, GenericDefId, HasModule, ImplId, LifetimeParamId,
|
||||
LocalEnumVariantId, LocalFieldId, Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId,
|
||||
TypeParamId, UnionId,
|
||||
AssocContainerId, AssocItemId, AttrDefId, ConstId, ConstParamId, DefWithBodyId, EnumId,
|
||||
FunctionId, GenericDefId, HasModule, ImplId, LifetimeParamId, LocalEnumVariantId, LocalFieldId,
|
||||
StaticId, StructId, TraitId, TypeAliasId, TypeParamId, UnionId,
|
||||
};
|
||||
use hir_expand::{name::name, MacroCallKind, MacroDefId, MacroDefKind};
|
||||
use hir_ty::{
|
||||
@ -109,10 +106,19 @@ pub use {
|
||||
attr::{Attr, Attrs, AttrsWithOwner, Documentation},
|
||||
find_path::PrefixKind,
|
||||
import_map,
|
||||
nameres::ModuleSource,
|
||||
item_scope::ItemScope,
|
||||
item_tree::ItemTreeNode,
|
||||
nameres::{DefMap, ModuleData, ModuleOrigin, ModuleSource},
|
||||
path::{ModPath, PathKind},
|
||||
src::HasSource as DefHasSource, // xx: I don't like this shadowing of HasSource... :(
|
||||
type_ref::{Mutability, TypeRef},
|
||||
visibility::Visibility,
|
||||
AdtId,
|
||||
AssocItemLoc,
|
||||
ItemLoc,
|
||||
Lookup,
|
||||
ModuleDefId,
|
||||
ModuleId,
|
||||
},
|
||||
hir_expand::{
|
||||
name::{known, Name},
|
||||
|
@ -148,7 +148,7 @@ pub enum ModuleOrigin {
|
||||
}
|
||||
|
||||
impl ModuleOrigin {
|
||||
fn declaration(&self) -> Option<AstId<ast::Module>> {
|
||||
pub fn declaration(&self) -> Option<AstId<ast::Module>> {
|
||||
match self {
|
||||
ModuleOrigin::File { declaration: module, .. }
|
||||
| ModuleOrigin::Inline { definition: module, .. } => Some(*module),
|
||||
|
@ -4,8 +4,8 @@ use std::fmt;
|
||||
|
||||
use either::Either;
|
||||
use hir::{
|
||||
AssocItem, Documentation, FieldSource, HasAttrs, HasSource, HirDisplay, InFile, ModuleSource,
|
||||
Semantics,
|
||||
db::AstDatabase, AssocItem, Documentation, FieldSource, HasAttrs, HasSource, HirDisplay,
|
||||
InFile, ModuleSource, Semantics,
|
||||
};
|
||||
use ide_db::{
|
||||
base_db::{FileId, FileRange},
|
||||
@ -170,7 +170,7 @@ impl NavigationTarget {
|
||||
impl ToNav for FileSymbol {
|
||||
fn to_nav(&self, db: &RootDatabase) -> NavigationTarget {
|
||||
NavigationTarget {
|
||||
file_id: self.file_id,
|
||||
file_id: self.file_id.original_file(db),
|
||||
name: self.name.clone(),
|
||||
kind: Some(match self.kind {
|
||||
FileSymbolKind::Function => SymbolKind::Function,
|
||||
@ -517,8 +517,8 @@ impl TryToNav for hir::ConstParam {
|
||||
/// e.g. `struct Name`, `enum Name`, `fn Name`
|
||||
pub(crate) fn description_from_symbol(db: &RootDatabase, symbol: &FileSymbol) -> Option<String> {
|
||||
let sema = Semantics::new(db);
|
||||
let parse = sema.parse(symbol.file_id);
|
||||
let node = symbol.ptr.to_node(parse.syntax());
|
||||
let syntax = sema.db.parse_or_expand(symbol.file_id)?;
|
||||
let node = symbol.ptr.to_node(&syntax);
|
||||
|
||||
match_ast! {
|
||||
match node {
|
||||
|
@ -4,6 +4,7 @@
|
||||
//! are located in different caches, with different APIs.
|
||||
use either::Either;
|
||||
use hir::{
|
||||
db::AstDatabase,
|
||||
import_map::{self, ImportKind},
|
||||
AsAssocItem, Crate, ItemInNs, Semantics,
|
||||
};
|
||||
@ -135,7 +136,7 @@ fn get_name_definition(
|
||||
let _p = profile::span("get_name_definition");
|
||||
let file_id = import_candidate.file_id;
|
||||
|
||||
let candidate_node = import_candidate.ptr.to_node(sema.parse(file_id).syntax());
|
||||
let candidate_node = import_candidate.ptr.to_node(&sema.db.parse_or_expand(file_id)?);
|
||||
let candidate_name_node = if candidate_node.kind() != NAME {
|
||||
candidate_node.children().find(|it| it.kind() == NAME)?
|
||||
} else {
|
||||
|
@ -33,7 +33,10 @@ use base_db::{
|
||||
CrateId, FileId, SourceDatabaseExt, SourceRootId,
|
||||
};
|
||||
use fst::{self, Streamer};
|
||||
use hir::db::DefDatabase;
|
||||
use hir::{
|
||||
db::DefDatabase, AdtId, AssocItemLoc, DefHasSource, HirFileId, ItemLoc, ItemScope,
|
||||
ItemTreeNode, Lookup, ModuleData, ModuleDefId, ModuleId,
|
||||
};
|
||||
use rayon::prelude::*;
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
use syntax::{
|
||||
@ -202,21 +205,29 @@ pub fn crate_symbols(db: &RootDatabase, krate: CrateId, query: Query) -> Vec<Fil
|
||||
// that instead?
|
||||
|
||||
let def_map = db.crate_def_map(krate);
|
||||
let mut files = Vec::new();
|
||||
let mut modules = vec![def_map.root()];
|
||||
while let Some(module) = modules.pop() {
|
||||
let data = &def_map[module];
|
||||
files.extend(data.origin.file_id());
|
||||
modules.extend(data.children.values());
|
||||
}
|
||||
// let mut files = Vec::new();
|
||||
// let mut modules = vec![def_map.root()];
|
||||
// while let Some(module) = modules.pop() {
|
||||
// let data = &def_map[module];
|
||||
// files.extend(data.origin.file_id());
|
||||
// modules.extend(data.children.values());
|
||||
// }
|
||||
|
||||
let snap = Snap(db.snapshot());
|
||||
// let snap = Snap(db.snapshot());
|
||||
|
||||
let buf = files
|
||||
.par_iter()
|
||||
.map_with(snap, |db, &file_id| db.0.file_symbols(file_id))
|
||||
.collect::<Vec<_>>();
|
||||
let buf = buf.iter().map(|it| &**it).collect::<Vec<_>>();
|
||||
// let buf = files
|
||||
// .par_iter()
|
||||
// .map_with(snap, |db, &file_id| db.0.file_symbols(file_id))
|
||||
// .collect::<Vec<_>>();
|
||||
|
||||
// todo: make this fast!!!
|
||||
// how do i salsa this?
|
||||
|
||||
let buf: Vec<_> = def_map
|
||||
.modules()
|
||||
.map(|(_, module_data)| SymbolIndex::new(module_data_to_file_symbols(db, module_data)))
|
||||
.collect();
|
||||
let buf = buf.iter().collect::<Vec<_>>();
|
||||
|
||||
query.search(&buf)
|
||||
}
|
||||
@ -364,7 +375,7 @@ impl Query {
|
||||
/// possible.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct FileSymbol {
|
||||
pub file_id: FileId,
|
||||
pub file_id: HirFileId,
|
||||
pub name: SmolStr,
|
||||
pub kind: FileSymbolKind,
|
||||
pub range: TextRange,
|
||||
@ -456,23 +467,134 @@ fn to_file_symbol(node: &SyntaxNode, file_id: FileId) -> Option<FileSymbol> {
|
||||
to_symbol(node).map(move |(name, ptr, name_range)| FileSymbol {
|
||||
name,
|
||||
kind: match node.kind() {
|
||||
FN => FileSymbolKind::Function,
|
||||
STRUCT => FileSymbolKind::Struct,
|
||||
ENUM => FileSymbolKind::Enum,
|
||||
TRAIT => FileSymbolKind::Trait,
|
||||
MODULE => FileSymbolKind::Module,
|
||||
TYPE_ALIAS => FileSymbolKind::TypeAlias,
|
||||
CONST => FileSymbolKind::Const,
|
||||
STATIC => FileSymbolKind::Static,
|
||||
MACRO_RULES => FileSymbolKind::Macro,
|
||||
MACRO_DEF => FileSymbolKind::Macro,
|
||||
UNION => FileSymbolKind::Union,
|
||||
FN => FileSymbolKind::Function, // FunctionId
|
||||
STRUCT => FileSymbolKind::Struct, // AdtId::StructId
|
||||
ENUM => FileSymbolKind::Enum, // AdtId::EnumId
|
||||
TRAIT => FileSymbolKind::Trait, // TraitId
|
||||
MODULE => FileSymbolKind::Module, // ModuleId
|
||||
TYPE_ALIAS => FileSymbolKind::TypeAlias, // TypeAliasId
|
||||
CONST => FileSymbolKind::Const, // ConstId
|
||||
STATIC => FileSymbolKind::Static, // StaticId
|
||||
MACRO_RULES => FileSymbolKind::Macro, // via ItemScope::macros
|
||||
MACRO_DEF => FileSymbolKind::Macro, // via ItemScope::macros
|
||||
UNION => FileSymbolKind::Union, // AdtId::UnionId
|
||||
kind => unreachable!("{:?}", kind),
|
||||
},
|
||||
range: node.text_range(),
|
||||
ptr,
|
||||
file_id,
|
||||
file_id: file_id.into(),
|
||||
name_range: Some(name_range),
|
||||
container_name: None,
|
||||
})
|
||||
}
|
||||
|
||||
fn module_data_to_file_symbols(db: &dyn DefDatabase, module_data: &ModuleData) -> Vec<FileSymbol> {
|
||||
let mut symbols = Vec::new();
|
||||
collect_symbols_from_item_scope(db, &mut symbols, &module_data.scope);
|
||||
// todo: collect macros from scope.macros().
|
||||
symbols
|
||||
}
|
||||
|
||||
fn collect_symbols_from_item_scope(
|
||||
db: &dyn DefDatabase,
|
||||
symbols: &mut Vec<FileSymbol>,
|
||||
scope: &ItemScope,
|
||||
) {
|
||||
// todo: dedupe code.
|
||||
fn decl_assoc<L, T>(db: &dyn DefDatabase, id: L, kind: FileSymbolKind) -> Option<FileSymbol>
|
||||
where
|
||||
L: Lookup<Data = AssocItemLoc<T>>,
|
||||
T: ItemTreeNode,
|
||||
<T as ItemTreeNode>::Source: HasName,
|
||||
{
|
||||
let loc = id.lookup(db);
|
||||
let source = loc.source(db);
|
||||
let name = source.value.name()?;
|
||||
let file_id = loc.id.file_id();
|
||||
|
||||
let name_range = name.syntax().text_range();
|
||||
let name = name.text().into();
|
||||
let ptr = SyntaxNodePtr::new(source.value.syntax());
|
||||
|
||||
Some(FileSymbol {
|
||||
name,
|
||||
kind,
|
||||
range: source.value.syntax().text_range(),
|
||||
// todo: fill out based on loc.container.
|
||||
container_name: None,
|
||||
file_id,
|
||||
name_range: Some(name_range),
|
||||
ptr,
|
||||
})
|
||||
}
|
||||
fn decl<L, T>(db: &dyn DefDatabase, id: L, kind: FileSymbolKind) -> Option<FileSymbol>
|
||||
where
|
||||
L: Lookup<Data = ItemLoc<T>>,
|
||||
T: ItemTreeNode,
|
||||
<T as ItemTreeNode>::Source: HasName,
|
||||
{
|
||||
let loc = id.lookup(db);
|
||||
let source = loc.source(db);
|
||||
let name = source.value.name()?;
|
||||
let file_id = loc.id.file_id();
|
||||
let name_range = name.syntax().text_range();
|
||||
let name = name.text().into();
|
||||
let ptr = SyntaxNodePtr::new(source.value.syntax());
|
||||
|
||||
Some(FileSymbol {
|
||||
name,
|
||||
kind,
|
||||
range: source.value.syntax().text_range(),
|
||||
container_name: None,
|
||||
file_id,
|
||||
name_range: Some(name_range),
|
||||
ptr,
|
||||
})
|
||||
}
|
||||
|
||||
fn decl_module(db: &dyn DefDatabase, module_id: ModuleId) -> Option<FileSymbol> {
|
||||
let def_map = module_id.def_map(db);
|
||||
let module_data = &def_map[module_id.local_id];
|
||||
let declaration = module_data.origin.declaration()?;
|
||||
let file_id = match module_data.origin.file_id() {
|
||||
Some(file_id) => file_id.into(),
|
||||
None => declaration.file_id,
|
||||
};
|
||||
|
||||
let module = declaration.to_node(db.upcast());
|
||||
let name = module.name()?;
|
||||
let name_range = name.syntax().text_range();
|
||||
let name = name.text().into();
|
||||
let ptr = SyntaxNodePtr::new(module.syntax());
|
||||
|
||||
Some(FileSymbol {
|
||||
name,
|
||||
kind: FileSymbolKind::Module,
|
||||
range: module.syntax().text_range(),
|
||||
container_name: None,
|
||||
file_id,
|
||||
name_range: Some(name_range),
|
||||
ptr,
|
||||
})
|
||||
}
|
||||
|
||||
let symbols_iter = scope.declarations().filter_map(|module_def_id| match module_def_id {
|
||||
ModuleDefId::ModuleId(module_id) => decl_module(db, module_id),
|
||||
ModuleDefId::FunctionId(function_id) => {
|
||||
decl_assoc(db, function_id, FileSymbolKind::Function)
|
||||
}
|
||||
ModuleDefId::AdtId(AdtId::StructId(struct_id)) => {
|
||||
decl(db, struct_id, FileSymbolKind::Struct)
|
||||
}
|
||||
ModuleDefId::AdtId(AdtId::EnumId(enum_id)) => decl(db, enum_id, FileSymbolKind::Enum),
|
||||
ModuleDefId::AdtId(AdtId::UnionId(union_id)) => decl(db, union_id, FileSymbolKind::Union),
|
||||
ModuleDefId::EnumVariantId(_) => None,
|
||||
ModuleDefId::ConstId(const_id) => decl_assoc(db, const_id, FileSymbolKind::Const),
|
||||
ModuleDefId::StaticId(static_id) => decl(db, static_id, FileSymbolKind::Static),
|
||||
ModuleDefId::TraitId(trait_id) => decl(db, trait_id, FileSymbolKind::Trait),
|
||||
ModuleDefId::TypeAliasId(alias_id) => decl_assoc(db, alias_id, FileSymbolKind::TypeAlias),
|
||||
ModuleDefId::BuiltinType(_) => None,
|
||||
});
|
||||
|
||||
symbols.extend(symbols_iter);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user