diff --git a/Cargo.lock b/Cargo.lock index 6899bb63005..634480e5fb8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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", diff --git a/crates/ra_ide_api/Cargo.toml b/crates/ra_ide_api/Cargo.toml index 73f39b647cd..f9bf0c686a3 100644 --- a/crates/ra_ide_api/Cargo.toml +++ b/crates/ra_ide_api/Cargo.toml @@ -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" } diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide_api/src/goto_definition.rs index 58261728625..d14908b25d0 100644 --- a/crates/ra_ide_api/src/goto_definition.rs +++ b/crates/ra_ide_api/src/goto_definition.rs @@ -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)), diff --git a/crates/ra_ide_api/src/hover.rs b/crates/ra_ide_api/src/hover.rs index 318708df3df..ba328efa140 100644 --- a/crates/ra_ide_api/src/hover.rs +++ b/crates/ra_ide_api/src/hover.rs @@ -100,8 +100,7 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option(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); diff --git a/crates/ra_ide_api/src/references.rs b/crates/ra_ide_api/src/references.rs index 3761fd6e760..3d282d48a79 100644 --- a/crates/ra_ide_api/src/references.rs +++ b/crates/ra_ide_api/src/references.rs @@ -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 { 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::(&syntax, offset) { + + if let Some(name_ref) = + find_node_at_offset::(parse.tree().syntax(), offset) + { let range = name_ref.syntax().text_range(); if let Some(text_range) = text_range { diff --git a/crates/ra_ide_api/src/references/classify.rs b/crates/ra_ide_api/src/references/classify.rs index 5cb194c0eff..93e079cccba 100644 --- a/crates/ra_ide_api/src/references/classify.rs +++ b/crates/ra_ide_api/src/references/classify.rs @@ -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 }) } } } diff --git a/crates/ra_ide_api/src/references/name_definition.rs b/crates/ra_ide_api/src/references/name_definition.rs index 58baf36868b..723d972373a 100644 --- a/crates/ra_ide_api/src/references/name_definition.rs +++ b/crates/ra_ide_api/src/references/name_definition.rs @@ -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, 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, ) -> 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 } } diff --git a/crates/ra_ide_api/src/references/rename.rs b/crates/ra_ide_api/src/references/rename.rs index 7e564a40eb1..c91dada464d 100644 --- a/crates/ra_ide_api/src/references/rename.rs +++ b/crates/ra_ide_api/src/references/rename.rs @@ -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}; diff --git a/crates/ra_ide_api/src/references/search_scope.rs b/crates/ra_ide_api/src/references/search_scope.rs index 346815d3122..aae9db13ba4 100644 --- a/crates/ra_ide_api/src/references/search_scope.rs +++ b/crates/ra_ide_api/src/references/search_scope.rs @@ -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)>, + pub files: Vec<(FileId, Option)>, } 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::>(); 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)] } } } diff --git a/crates/ra_ide_api/src/syntax_highlighting.rs b/crates/ra_ide_api/src/syntax_highlighting.rs index 9254327f66b..33f3cacebee 100644 --- a/crates/ra_ide_api/src/syntax_highlighting.rs +++ b/crates/ra_ide_api/src/syntax_highlighting.rs @@ -101,7 +101,7 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec "macro", Some(Field(_)) => "field",