From 98718e0544f42e55642d2838b00d6a7bef1e2414 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 15 Jan 2021 21:07:38 +0100 Subject: Wrap remaining self/super/crate in Name{Ref} --- crates/ide/src/display/navigation_target.rs | 14 ++--- crates/ide/src/goto_definition.rs | 5 -- crates/ide/src/hover.rs | 5 +- crates/ide/src/references/rename.rs | 76 +++++++++++-------------- crates/ide/src/syntax_highlighting/highlight.rs | 22 +++---- 5 files changed, 49 insertions(+), 73 deletions(-) (limited to 'crates/ide/src') diff --git a/crates/ide/src/display/navigation_target.rs b/crates/ide/src/display/navigation_target.rs index 685052e7f..00e601244 100644 --- a/crates/ide/src/display/navigation_target.rs +++ b/crates/ide/src/display/navigation_target.rs @@ -400,15 +400,13 @@ impl TryToNav for hir::GenericParam { impl ToNav for hir::Local { fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { let src = self.source(db); - let (node, focus_range) = match &src.value { - Either::Left(bind_pat) => ( - bind_pat.syntax().clone(), - bind_pat - .name() - .map(|it| src.with_value(&it.syntax().clone()).original_file_range(db).range), - ), - Either::Right(it) => (it.syntax().clone(), it.self_token().map(|it| it.text_range())), + let (node, name) = match &src.value { + Either::Left(bind_pat) => (bind_pat.syntax().clone(), bind_pat.name()), + Either::Right(it) => (it.syntax().clone(), it.name()), }; + let focus_range = + name.map(|it| src.with_value(&it.syntax().clone()).original_file_range(db).range); + let full_range = src.with_value(&node).original_file_range(db); let name = match self.name(db) { Some(it) => it.to_string().into(), diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs index 988a5668f..a1d2bce1d 100644 --- a/crates/ide/src/goto_definition.rs +++ b/crates/ide/src/goto_definition.rs @@ -55,11 +55,6 @@ pub(crate) fn goto_definition( } else { reference_definition(&sema, Either::Left(<)).to_vec() }, - ast::SelfParam(self_param) => { - let def = NameClass::classify_self_param(&sema, &self_param)?.referenced_or_defined(sema.db); - let nav = def.try_to_nav(sema.db)?; - vec![nav] - }, _ => return None, } }; diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs index 6022bd275..2024acd94 100644 --- a/crates/ide/src/hover.rs +++ b/crates/ide/src/hover.rs @@ -98,7 +98,6 @@ pub(crate) fn hover( ast::NameRef(name_ref) => NameRefClass::classify(&sema, &name_ref).map(|d| d.referenced(sema.db)), ast::Lifetime(lifetime) => NameClass::classify_lifetime(&sema, &lifetime) .map_or_else(|| NameRefClass::classify_lifetime(&sema, &lifetime).map(|d| d.referenced(sema.db)), |d| d.defined(sema.db)), - ast::SelfParam(self_param) => NameClass::classify_self_param(&sema, &self_param).and_then(|d| d.defined(sema.db)), _ => None, } }; @@ -3223,7 +3222,7 @@ impl Foo { } "#, expect![[r#" - *&self* + *self* ```rust &Foo @@ -3243,7 +3242,7 @@ impl Foo { } "#, expect![[r#" - *self: Arc* + *self* ```rust Arc diff --git a/crates/ide/src/references/rename.rs b/crates/ide/src/references/rename.rs index 9ac4af026..4df189c98 100644 --- a/crates/ide/src/references/rename.rs +++ b/crates/ide/src/references/rename.rs @@ -1,12 +1,9 @@ //! FIXME: write short doc here -use std::{ - convert::TryInto, - fmt::{self, Display}, -}; +use std::fmt::{self, Display}; use hir::{Module, ModuleDef, ModuleSource, Semantics}; use ide_db::{ - base_db::{AnchoredPathBuf, FileId, FileRange, SourceDatabaseExt}, + base_db::{AnchoredPathBuf, FileId, FileRange}, defs::{Definition, NameClass, NameRefClass}, search::FileReference, RootDatabase, @@ -14,14 +11,14 @@ use ide_db::{ use syntax::{ algo::find_node_at_offset, ast::{self, NameOwner}, - lex_single_syntax_kind, match_ast, AstNode, SyntaxKind, SyntaxNode, SyntaxToken, T, + lex_single_syntax_kind, match_ast, AstNode, SyntaxKind, SyntaxNode, T, }; use test_utils::mark; use text_edit::TextEdit; use crate::{ FilePosition, FileSystemEdit, RangeInfo, ReferenceKind, ReferenceSearchResult, SourceChange, - TextRange, TextSize, + TextRange, }; type RenameResult = Result; @@ -52,10 +49,6 @@ pub(crate) fn prepare_rename( let syntax = source_file.syntax(); if let Some(module) = find_module_at_offset(&sema, position, syntax) { rename_mod(&sema, position, module, "dummy") - } else if let Some(self_token) = - syntax.token_at_offset(position.offset).find(|t| t.kind() == T![self]) - { - rename_self_to_param(&sema, position, self_token, "dummy") } else { let RangeInfo { range, .. } = find_all_refs(&sema, position)?; Ok(RangeInfo::new(range, SourceChange::default())) @@ -82,10 +75,6 @@ pub(crate) fn rename_with_semantics( if let Some(module) = find_module_at_offset(&sema, position, syntax) { rename_mod(&sema, position, module, new_name) - } else if let Some(self_token) = - syntax.token_at_offset(position.offset).find(|t| t.kind() == T![self]) - { - rename_self_to_param(&sema, position, self_token, new_name) } else { rename_reference(&sema, position, new_name) } @@ -108,7 +97,7 @@ pub(crate) fn will_rename_file( Some(change) } -#[derive(Debug, PartialEq)] +#[derive(Copy, Clone, Debug, PartialEq)] enum IdentifierKind { Ident, Lifetime, @@ -375,53 +364,50 @@ fn text_edit_from_self_param( fn rename_self_to_param( sema: &Semantics, position: FilePosition, - self_token: SyntaxToken, new_name: &str, + ident_kind: IdentifierKind, + range: TextRange, + refs: ReferenceSearchResult, ) -> Result, RenameError> { - let ident_kind = check_identifier(new_name)?; match ident_kind { IdentifierKind::Lifetime => bail!("Invalid name `{}`: not an identifier", new_name), IdentifierKind::ToSelf => { // no-op mark::hit!(rename_self_to_self); - return Ok(RangeInfo::new(self_token.text_range(), SourceChange::default())); + return Ok(RangeInfo::new(range, SourceChange::default())); } _ => (), } let source_file = sema.parse(position.file_id); let syn = source_file.syntax(); - let text = sema.db.file_text(position.file_id); let fn_def = find_node_at_offset::(syn, position.offset) .ok_or_else(|| format_err!("No surrounding method declaration found"))?; - let search_range = fn_def.syntax().text_range(); let mut source_change = SourceChange::default(); - - for (idx, _) in text.match_indices("self") { - let offset: TextSize = idx.try_into().unwrap(); - if !search_range.contains_inclusive(offset) { - continue; - } - if let Some(ref usage) = syn.token_at_offset(offset).find(|t| t.kind() == T![self]) { - let edit = if let Some(ref self_param) = ast::SelfParam::cast(usage.parent()) { - text_edit_from_self_param(syn, self_param, new_name) - .ok_or_else(|| format_err!("No target type found"))? - } else { - TextEdit::replace(usage.text_range(), String::from(new_name)) - }; + if let Some(self_param) = fn_def.param_list().and_then(|it| it.self_param()) { + if self_param + .syntax() + .text_range() + .contains_range(refs.declaration().nav.focus_or_full_range()) + { + let edit = text_edit_from_self_param(syn, &self_param, new_name) + .ok_or_else(|| format_err!("No target type found"))?; source_change.insert_source_edit(position.file_id, edit); - } - } - if source_change.source_file_edits.len() > 1 && ident_kind == IdentifierKind::Underscore { - bail!("Cannot rename reference to `_` as it is being referenced multiple times"); - } + source_change.extend(refs.references().iter().map(|(&file_id, references)| { + source_edit_from_references(sema, file_id, &references, new_name) + })); - let range = ast::SelfParam::cast(self_token.parent()) - .map_or(self_token.text_range(), |p| p.syntax().text_range()); + if source_change.source_file_edits.len() > 1 && ident_kind == IdentifierKind::Underscore + { + bail!("Cannot rename reference to `_` as it is being referenced multiple times"); + } - Ok(RangeInfo::new(range, source_change)) + return Ok(RangeInfo::new(range, source_change)); + } + } + Err(format_err!("Method has no self param")) } fn rename_reference( @@ -444,8 +430,9 @@ fn rename_reference( mark::hit!(rename_not_an_ident_ref); bail!("Invalid name `{}`: not an identifier", new_name) } - (IdentifierKind::ToSelf, ReferenceKind::SelfParam) => { - unreachable!("rename_self_to_param should've been called instead") + (_, ReferenceKind::SelfParam) => { + mark::hit!(rename_self_to_param); + return rename_self_to_param(sema, position, new_name, ident_kind, range, refs); } (IdentifierKind::ToSelf, _) => { mark::hit!(rename_to_self); @@ -1350,6 +1337,7 @@ impl Foo { #[test] fn test_owned_self_to_parameter() { + mark::check!(rename_self_to_param); check( "foo", r#" diff --git a/crates/ide/src/syntax_highlighting/highlight.rs b/crates/ide/src/syntax_highlighting/highlight.rs index 87578e70a..8625ef5df 100644 --- a/crates/ide/src/syntax_highlighting/highlight.rs +++ b/crates/ide/src/syntax_highlighting/highlight.rs @@ -68,7 +68,8 @@ pub(super) fn element( NAME_REF => { let name_ref = element.into_node().and_then(ast::NameRef::cast).unwrap(); highlight_func_by_name_ref(sema, &name_ref).unwrap_or_else(|| { - match NameRefClass::classify(sema, &name_ref) { + let is_self = name_ref.self_token().is_some(); + let h = match NameRefClass::classify(sema, &name_ref) { Some(name_kind) => match name_kind { NameRefClass::ExternCrate(_) => HlTag::Symbol(SymbolKind::Module).into(), NameRefClass::Definition(def) => { @@ -108,6 +109,11 @@ pub(super) fn element( highlight_name_ref_by_syntax(name_ref, sema) } None => HlTag::UnresolvedReference.into(), + }; + if h.tag == HlTag::Symbol(SymbolKind::Module) && is_self { + HlTag::Symbol(SymbolKind::SelfParam).into() + } else { + h } }) } @@ -225,18 +231,8 @@ pub(super) fn element( T![for] if !is_child_of_impl(&element) => h | HlMod::ControlFlow, T![unsafe] => h | HlMod::Unsafe, T![true] | T![false] => HlTag::BoolLiteral.into(), - T![self] => { - let self_param = element.parent().and_then(ast::SelfParam::cast); - if let Some(NameClass::Definition(def)) = self_param - .and_then(|self_param| NameClass::classify_self_param(sema, &self_param)) - { - highlight_def(db, def) | HlMod::Definition - } else if element.ancestors().any(|it| it.kind() == USE_TREE) { - HlTag::Symbol(SymbolKind::SelfParam).into() - } else { - return None; - } - } + // self is handled as either a Name or NameRef already + T![self] => return None, T![ref] => element .parent() .and_then(ast::IdentPat::cast) -- cgit v1.2.3