use Lazy, some fixes

This commit is contained in:
Ekaterina Babshukova 2019-10-14 14:59:02 +03:00
parent 19fbf2c16b
commit 88ff88d318
10 changed files with 51 additions and 43 deletions

1
Cargo.lock generated
View file

@ -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",

View file

@ -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" }

View file

@ -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)),

View file

@ -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);

View file

@ -5,6 +5,7 @@ mod name_definition;
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 {

View file

@ -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, &macro_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 })
}
}
}

View file

@ -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 }
}

View file

@ -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};

View file

@ -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 crate::db::RootDatabase;
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 @@ impl NameDefinition {
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 @@ impl NameDefinition {
}
}
return SearchScope { scope: files };
return SearchScope { files };
}
// FIXME: "pub(super)", "pub(in path)"
}
@ -56,6 +58,6 @@ impl NameDefinition {
ModuleSource::Module(m) => Some(m.syntax().text_range()),
ModuleSource::SourceFile(_) => None,
};
SearchScope { scope: vec![(file_id, range)] }
SearchScope { files: vec![(file_id, range)] }
}
}

View file

@ -101,7 +101,7 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRa
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",