use Lazy, some fixes
This commit is contained in:
parent
19fbf2c16b
commit
88ff88d318
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -1025,6 +1025,7 @@ dependencies = [
|
||||
"itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"join_to_string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proptest 0.9.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ra_assists 0.1.0",
|
||||
"ra_cfg 0.1.0",
|
||||
|
@ -19,6 +19,7 @@ rustc-hash = "1.0"
|
||||
unicase = "2.2.0"
|
||||
superslice = "1.0.0"
|
||||
rand = { version = "0.7.0", features = ["small_rng"] }
|
||||
once_cell = "1.2.0"
|
||||
|
||||
ra_syntax = { path = "../ra_syntax" }
|
||||
ra_text_edit = { path = "../ra_text_edit" }
|
||||
|
@ -54,7 +54,7 @@ pub(crate) fn reference_definition(
|
||||
) -> ReferenceResult {
|
||||
use self::ReferenceResult::*;
|
||||
|
||||
let name_kind = classify_name_ref(db, file_id, &name_ref).map(|d| d.item);
|
||||
let name_kind = classify_name_ref(db, file_id, &name_ref).map(|d| d.kind);
|
||||
match name_kind {
|
||||
Some(Macro(mac)) => return Exact(NavigationTarget::from_macro_def(db, mac)),
|
||||
Some(Field(field)) => return Exact(NavigationTarget::from_field(db, field)),
|
||||
|
@ -100,8 +100,7 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn
|
||||
let mut range = None;
|
||||
if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(file.syntax(), position.offset) {
|
||||
let mut no_fallback = false;
|
||||
let name_kind =
|
||||
classify_name_ref(db, position.file_id, &name_ref).and_then(|d| Some(d.item));
|
||||
let name_kind = classify_name_ref(db, position.file_id, &name_ref).map(|d| d.kind);
|
||||
match name_kind {
|
||||
Some(Macro(it)) => {
|
||||
let src = it.source(db);
|
||||
|
@ -5,6 +5,7 @@
|
||||
mod rename;
|
||||
mod search_scope;
|
||||
|
||||
use once_cell::unsync::Lazy;
|
||||
use ra_db::{SourceDatabase, SourceDatabaseExt};
|
||||
use ra_syntax::{algo::find_node_at_offset, ast, AstNode, SourceFile, SyntaxNode, TextUnit};
|
||||
|
||||
@ -61,7 +62,7 @@ pub(crate) fn find_all_refs(
|
||||
let syntax = parse.tree().syntax().clone();
|
||||
let RangeInfo { range, info: (name, def) } = find_name(db, &syntax, position)?;
|
||||
|
||||
let declaration = match def.item {
|
||||
let declaration = match def.kind {
|
||||
NameKind::Macro(mac) => NavigationTarget::from_macro_def(db, mac),
|
||||
NameKind::Field(field) => NavigationTarget::from_field(db, field),
|
||||
NameKind::AssocItem(assoc) => NavigationTarget::from_assoc_item(db, assoc),
|
||||
@ -98,7 +99,7 @@ fn find_name<'a>(
|
||||
|
||||
fn process_definition(db: &RootDatabase, def: NameDefinition, name: String) -> Vec<FileRange> {
|
||||
let pat = name.as_str();
|
||||
let scope = def.scope(db).scope;
|
||||
let scope = def.scope(db).files;
|
||||
let mut refs = vec![];
|
||||
|
||||
let is_match = |file_id: FileId, name_ref: &ast::NameRef| -> bool {
|
||||
@ -112,12 +113,14 @@ fn process_definition(db: &RootDatabase, def: NameDefinition, name: String) -> V
|
||||
|
||||
for (file_id, text_range) in scope {
|
||||
let text = db.file_text(file_id);
|
||||
let parse = SourceFile::parse(&text);
|
||||
let syntax = parse.tree().syntax().clone();
|
||||
let parse = Lazy::new(|| SourceFile::parse(&text));
|
||||
|
||||
for (idx, _) in text.match_indices(pat) {
|
||||
let offset = TextUnit::from_usize(idx);
|
||||
if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(&syntax, offset) {
|
||||
|
||||
if let Some(name_ref) =
|
||||
find_node_at_offset::<ast::NameRef>(parse.tree().syntax(), offset)
|
||||
{
|
||||
let range = name_ref.syntax().text_range();
|
||||
|
||||
if let Some(text_range) = text_range {
|
||||
|
@ -1,3 +1,5 @@
|
||||
//! FIXME: write short doc here
|
||||
|
||||
use hir::{Either, FromSource, Module, ModuleSource, Path, PathResolution, Source, SourceAnalyzer};
|
||||
use ra_db::FileId;
|
||||
use ra_syntax::{ast, match_ast, AstNode, AstPtr};
|
||||
@ -102,8 +104,9 @@ pub(crate) fn classify_name_ref(
|
||||
let analyzer = SourceAnalyzer::new(db, file_id, name_ref.syntax(), None);
|
||||
|
||||
if let Some(method_call) = ast::MethodCallExpr::cast(parent.clone()) {
|
||||
let func = analyzer.resolve_method_call(&method_call)?;
|
||||
return Some(from_assoc_item(db, func.into()));
|
||||
if let Some(func) = analyzer.resolve_method_call(&method_call) {
|
||||
return Some(from_assoc_item(db, func.into()));
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(field_expr) = ast::FieldExpr::cast(parent.clone()) {
|
||||
@ -128,15 +131,10 @@ pub(crate) fn classify_name_ref(
|
||||
let container = Module::from_definition(db, Source { file_id, ast })?;
|
||||
let visibility = None;
|
||||
|
||||
if let Some(macro_call) =
|
||||
parent.parent().and_then(|node| node.parent()).and_then(ast::MacroCall::cast)
|
||||
{
|
||||
if let Some(macro_call) = parent.ancestors().find_map(ast::MacroCall::cast) {
|
||||
if let Some(macro_def) = analyzer.resolve_macro_call(db, ¯o_call) {
|
||||
return Some(NameDefinition {
|
||||
item: NameKind::Macro(macro_def),
|
||||
container,
|
||||
visibility,
|
||||
});
|
||||
let kind = NameKind::Macro(macro_def);
|
||||
return Some(NameDefinition { kind, container, visibility });
|
||||
}
|
||||
}
|
||||
|
||||
@ -147,23 +145,23 @@ pub(crate) fn classify_name_ref(
|
||||
AssocItem(item) => Some(from_assoc_item(db, item)),
|
||||
LocalBinding(Either::A(pat)) => from_pat(db, file_id, pat),
|
||||
LocalBinding(Either::B(par)) => {
|
||||
let item = NameKind::SelfParam(par);
|
||||
Some(NameDefinition { item, container, visibility })
|
||||
let kind = NameKind::SelfParam(par);
|
||||
Some(NameDefinition { kind, container, visibility })
|
||||
}
|
||||
GenericParam(par) => {
|
||||
// FIXME: get generic param def
|
||||
let item = NameKind::GenericParam(par);
|
||||
Some(NameDefinition { item, container, visibility })
|
||||
let kind = NameKind::GenericParam(par);
|
||||
Some(NameDefinition { kind, container, visibility })
|
||||
}
|
||||
Macro(def) => {
|
||||
let item = NameKind::Macro(def);
|
||||
Some(NameDefinition { item, container, visibility })
|
||||
let kind = NameKind::Macro(def);
|
||||
Some(NameDefinition { kind, container, visibility })
|
||||
}
|
||||
SelfType(impl_block) => {
|
||||
let ty = impl_block.target_ty(db);
|
||||
let item = NameKind::SelfType(ty);
|
||||
let kind = NameKind::SelfType(ty);
|
||||
let container = impl_block.module();
|
||||
Some(NameDefinition { item, container, visibility })
|
||||
Some(NameDefinition { kind, container, visibility })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
//! FIXME: write short doc here
|
||||
|
||||
use hir::{
|
||||
db::AstDatabase, Adt, AssocItem, DefWithBody, FromSource, HasSource, HirFileId, MacroDef,
|
||||
Module, ModuleDef, StructField, Ty, VariantDef,
|
||||
@ -22,7 +24,7 @@ pub enum NameKind {
|
||||
pub(crate) struct NameDefinition {
|
||||
pub visibility: Option<ast::Visibility>,
|
||||
pub container: Module,
|
||||
pub item: NameKind,
|
||||
pub kind: NameKind,
|
||||
}
|
||||
|
||||
pub(super) fn from_pat(
|
||||
@ -50,9 +52,9 @@ pub(super) fn from_pat(
|
||||
}
|
||||
}
|
||||
})?;
|
||||
let item = NameKind::Pat((def, pat));
|
||||
let kind = NameKind::Pat((def, pat));
|
||||
let container = def.module(db);
|
||||
Some(NameDefinition { item, container, visibility: None })
|
||||
Some(NameDefinition { kind, container, visibility: None })
|
||||
}
|
||||
|
||||
pub(super) fn from_assoc_item(db: &RootDatabase, item: AssocItem) -> NameDefinition {
|
||||
@ -62,19 +64,19 @@ pub(super) fn from_assoc_item(db: &RootDatabase, item: AssocItem) -> NameDefinit
|
||||
AssocItem::Const(c) => c.source(db).ast.visibility(),
|
||||
AssocItem::TypeAlias(a) => a.source(db).ast.visibility(),
|
||||
};
|
||||
let item = NameKind::AssocItem(item);
|
||||
NameDefinition { item, container, visibility }
|
||||
let kind = NameKind::AssocItem(item);
|
||||
NameDefinition { kind, container, visibility }
|
||||
}
|
||||
|
||||
pub(super) fn from_struct_field(db: &RootDatabase, field: StructField) -> NameDefinition {
|
||||
let item = NameKind::Field(field);
|
||||
let kind = NameKind::Field(field);
|
||||
let parent = field.parent_def(db);
|
||||
let container = parent.module(db);
|
||||
let visibility = match parent {
|
||||
VariantDef::Struct(s) => s.source(db).ast.visibility(),
|
||||
VariantDef::EnumVariant(e) => e.source(db).ast.parent_enum().visibility(),
|
||||
};
|
||||
NameDefinition { item, container, visibility }
|
||||
NameDefinition { kind, container, visibility }
|
||||
}
|
||||
|
||||
pub(super) fn from_module_def(
|
||||
@ -82,7 +84,7 @@ pub(super) fn from_module_def(
|
||||
def: ModuleDef,
|
||||
module: Option<Module>,
|
||||
) -> NameDefinition {
|
||||
let item = NameKind::Def(def);
|
||||
let kind = NameKind::Def(def);
|
||||
let (container, visibility) = match def {
|
||||
ModuleDef::Module(it) => {
|
||||
let container = it.parent(db).or_else(|| Some(it)).unwrap();
|
||||
@ -104,5 +106,5 @@ pub(super) fn from_module_def(
|
||||
ModuleDef::Adt(Adt::Enum(it)) => (it.module(db), it.source(db).ast.visibility()),
|
||||
ModuleDef::BuiltinType(..) => (module.unwrap(), None),
|
||||
};
|
||||
NameDefinition { item, container, visibility }
|
||||
NameDefinition { kind, container, visibility }
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
//! FIXME: write short doc here
|
||||
|
||||
use hir::ModuleSource;
|
||||
use ra_db::SourceDatabase;
|
||||
use ra_syntax::{algo::find_node_at_offset, ast, AstNode, SyntaxNode};
|
||||
|
@ -1,3 +1,5 @@
|
||||
//! FIXME: write short doc here
|
||||
|
||||
use hir::{DefWithBody, HasSource, ModuleSource};
|
||||
use ra_db::{FileId, SourceDatabase};
|
||||
use ra_syntax::{AstNode, TextRange};
|
||||
@ -7,21 +9,21 @@
|
||||
use super::{NameDefinition, NameKind};
|
||||
|
||||
pub(crate) struct SearchScope {
|
||||
pub scope: Vec<(FileId, Option<TextRange>)>,
|
||||
pub files: Vec<(FileId, Option<TextRange>)>,
|
||||
}
|
||||
|
||||
impl NameDefinition {
|
||||
pub fn scope(&self, db: &RootDatabase) -> SearchScope {
|
||||
pub(crate) fn scope(&self, db: &RootDatabase) -> SearchScope {
|
||||
let module_src = self.container.definition_source(db);
|
||||
let file_id = module_src.file_id.original_file(db);
|
||||
|
||||
if let NameKind::Pat((def, _)) = self.item {
|
||||
if let NameKind::Pat((def, _)) = self.kind {
|
||||
let range = match def {
|
||||
DefWithBody::Function(f) => f.source(db).ast.syntax().text_range(),
|
||||
DefWithBody::Const(c) => c.source(db).ast.syntax().text_range(),
|
||||
DefWithBody::Static(s) => s.source(db).ast.syntax().text_range(),
|
||||
};
|
||||
return SearchScope { scope: vec![(file_id, Some(range))] };
|
||||
return SearchScope { files: vec![(file_id, Some(range))] };
|
||||
}
|
||||
|
||||
if let Some(ref vis) = self.visibility {
|
||||
@ -30,7 +32,7 @@ pub fn scope(&self, db: &RootDatabase) -> SearchScope {
|
||||
let mut files = source_root.walk().map(|id| (id.into(), None)).collect::<Vec<_>>();
|
||||
|
||||
if vis.syntax().to_string().as_str() == "pub(crate)" {
|
||||
return SearchScope { scope: files };
|
||||
return SearchScope { files };
|
||||
}
|
||||
if vis.syntax().to_string().as_str() == "pub" {
|
||||
let krate = self.container.krate(db).unwrap();
|
||||
@ -47,7 +49,7 @@ pub fn scope(&self, db: &RootDatabase) -> SearchScope {
|
||||
}
|
||||
}
|
||||
|
||||
return SearchScope { scope: files };
|
||||
return SearchScope { files };
|
||||
}
|
||||
// FIXME: "pub(super)", "pub(in path)"
|
||||
}
|
||||
@ -56,6 +58,6 @@ pub fn scope(&self, db: &RootDatabase) -> SearchScope {
|
||||
ModuleSource::Module(m) => Some(m.syntax().text_range()),
|
||||
ModuleSource::SourceFile(_) => None,
|
||||
};
|
||||
SearchScope { scope: vec![(file_id, range)] }
|
||||
SearchScope { files: vec![(file_id, range)] }
|
||||
}
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ fn hash<T: std::hash::Hash + std::fmt::Debug>(x: T) -> u64 {
|
||||
continue;
|
||||
}
|
||||
if let Some(name_ref) = node.as_node().cloned().and_then(ast::NameRef::cast) {
|
||||
let name_kind = classify_name_ref(db, file_id, &name_ref).map(|d| d.item);
|
||||
let name_kind = classify_name_ref(db, file_id, &name_ref).map(|d| d.kind);
|
||||
match name_kind {
|
||||
Some(Macro(_)) => "macro",
|
||||
Some(Field(_)) => "field",
|
||||
|
Loading…
Reference in New Issue
Block a user