diff options
Diffstat (limited to 'crates/ide')
-rw-r--r-- | crates/ide/src/goto_implementation.rs | 7 | ||||
-rw-r--r-- | crates/ide/src/hover.rs | 2 | ||||
-rw-r--r-- | crates/ide/src/rename.rs | 46 | ||||
-rw-r--r-- | crates/ide/src/typing.rs | 36 |
4 files changed, 57 insertions, 34 deletions
diff --git a/crates/ide/src/goto_implementation.rs b/crates/ide/src/goto_implementation.rs index 0013820b4..07686017d 100644 --- a/crates/ide/src/goto_implementation.rs +++ b/crates/ide/src/goto_implementation.rs | |||
@@ -236,15 +236,10 @@ impl T for &Foo {} | |||
236 | fn goto_implementation_to_builtin_derive() { | 236 | fn goto_implementation_to_builtin_derive() { |
237 | check( | 237 | check( |
238 | r#" | 238 | r#" |
239 | //- minicore: copy, derive | ||
239 | #[derive(Copy)] | 240 | #[derive(Copy)] |
240 | //^^^^^^^^^^^^^^^ | 241 | //^^^^^^^^^^^^^^^ |
241 | struct Foo$0; | 242 | struct Foo$0; |
242 | |||
243 | mod marker { | ||
244 | trait Copy {} | ||
245 | } | ||
246 | #[rustc_builtin_macro] | ||
247 | macro Copy {} | ||
248 | "#, | 243 | "#, |
249 | ); | 244 | ); |
250 | } | 245 | } |
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs index 05a2b1293..2e1359eef 100644 --- a/crates/ide/src/hover.rs +++ b/crates/ide/src/hover.rs | |||
@@ -2258,7 +2258,7 @@ pub fn fo$0o() {} | |||
2258 | case 13. collapsed link: foo | 2258 | case 13. collapsed link: foo |
2259 | case 14. shortcut link: foo | 2259 | case 14. shortcut link: foo |
2260 | case 15. inline without URL: foo | 2260 | case 15. inline without URL: foo |
2261 | case 16. just escaped text: \[foo] | 2261 | case 16. just escaped text: \[foo\] |
2262 | case 17. inline link: Foo | 2262 | case 17. inline link: Foo |
2263 | 2263 | ||
2264 | [^example]: https://www.example.com/ | 2264 | [^example]: https://www.example.com/ |
diff --git a/crates/ide/src/rename.rs b/crates/ide/src/rename.rs index 8096dfa0e..96bd07708 100644 --- a/crates/ide/src/rename.rs +++ b/crates/ide/src/rename.rs | |||
@@ -10,7 +10,7 @@ use ide_db::{ | |||
10 | rename::{bail, format_err, source_edit_from_references, IdentifierKind}, | 10 | rename::{bail, format_err, source_edit_from_references, IdentifierKind}, |
11 | RootDatabase, | 11 | RootDatabase, |
12 | }; | 12 | }; |
13 | use stdx::never; | 13 | use stdx::{always, never}; |
14 | use syntax::{ast, AstNode, SyntaxNode}; | 14 | use syntax::{ast, AstNode, SyntaxNode}; |
15 | 15 | ||
16 | use text_edit::TextEdit; | 16 | use text_edit::TextEdit; |
@@ -31,10 +31,13 @@ pub(crate) fn prepare_rename( | |||
31 | let source_file = sema.parse(position.file_id); | 31 | let source_file = sema.parse(position.file_id); |
32 | let syntax = source_file.syntax(); | 32 | let syntax = source_file.syntax(); |
33 | 33 | ||
34 | let def = find_definition(&sema, syntax, position)?; | 34 | let (name_like, def) = find_definition(&sema, syntax, position)?; |
35 | let frange = def | 35 | if def.range_for_rename(&sema).is_none() { |
36 | .range_for_rename(&sema) | 36 | bail!("No references found at position") |
37 | .ok_or_else(|| format_err!("No references found at position"))?; | 37 | } |
38 | |||
39 | let frange = sema.original_range(name_like.syntax()); | ||
40 | always!(frange.range.contains_inclusive(position.offset) && frange.file_id == position.file_id); | ||
38 | Ok(RangeInfo::new(frange.range, ())) | 41 | Ok(RangeInfo::new(frange.range, ())) |
39 | } | 42 | } |
40 | 43 | ||
@@ -55,31 +58,23 @@ pub(crate) fn rename( | |||
55 | new_name: &str, | 58 | new_name: &str, |
56 | ) -> RenameResult<SourceChange> { | 59 | ) -> RenameResult<SourceChange> { |
57 | let sema = Semantics::new(db); | 60 | let sema = Semantics::new(db); |
58 | rename_with_semantics(&sema, position, new_name) | ||
59 | } | ||
60 | |||
61 | pub(crate) fn rename_with_semantics( | ||
62 | sema: &Semantics<RootDatabase>, | ||
63 | position: FilePosition, | ||
64 | new_name: &str, | ||
65 | ) -> RenameResult<SourceChange> { | ||
66 | let source_file = sema.parse(position.file_id); | 61 | let source_file = sema.parse(position.file_id); |
67 | let syntax = source_file.syntax(); | 62 | let syntax = source_file.syntax(); |
68 | 63 | ||
69 | let def = find_definition(sema, syntax, position)?; | 64 | let (_name_like, def) = find_definition(&sema, syntax, position)?; |
70 | 65 | ||
71 | if let Definition::Local(local) = def { | 66 | if let Definition::Local(local) = def { |
72 | if let Some(self_param) = local.as_self_param(sema.db) { | 67 | if let Some(self_param) = local.as_self_param(sema.db) { |
73 | cov_mark::hit!(rename_self_to_param); | 68 | cov_mark::hit!(rename_self_to_param); |
74 | return rename_self_to_param(sema, local, self_param, new_name); | 69 | return rename_self_to_param(&sema, local, self_param, new_name); |
75 | } | 70 | } |
76 | if new_name == "self" { | 71 | if new_name == "self" { |
77 | cov_mark::hit!(rename_to_self); | 72 | cov_mark::hit!(rename_to_self); |
78 | return rename_to_self(sema, local); | 73 | return rename_to_self(&sema, local); |
79 | } | 74 | } |
80 | } | 75 | } |
81 | 76 | ||
82 | def.rename(sema, new_name) | 77 | def.rename(&sema, new_name) |
83 | } | 78 | } |
84 | 79 | ||
85 | /// Called by the client when it is about to rename a file. | 80 | /// Called by the client when it is about to rename a file. |
@@ -100,11 +95,12 @@ fn find_definition( | |||
100 | sema: &Semantics<RootDatabase>, | 95 | sema: &Semantics<RootDatabase>, |
101 | syntax: &SyntaxNode, | 96 | syntax: &SyntaxNode, |
102 | position: FilePosition, | 97 | position: FilePosition, |
103 | ) -> RenameResult<Definition> { | 98 | ) -> RenameResult<(ast::NameLike, Definition)> { |
104 | match sema | 99 | let name_like = sema |
105 | .find_node_at_offset_with_descend(syntax, position.offset) | 100 | .find_node_at_offset_with_descend::<ast::NameLike>(syntax, position.offset) |
106 | .ok_or_else(|| format_err!("No references found at position"))? | 101 | .ok_or_else(|| format_err!("No references found at position"))?; |
107 | { | 102 | |
103 | let def = match &name_like { | ||
108 | // renaming aliases would rename the item being aliased as the HIR doesn't track aliases yet | 104 | // renaming aliases would rename the item being aliased as the HIR doesn't track aliases yet |
109 | ast::NameLike::Name(name) | 105 | ast::NameLike::Name(name) |
110 | if name.syntax().parent().map_or(false, |it| ast::Rename::can_cast(it.kind())) => | 106 | if name.syntax().parent().map_or(false, |it| ast::Rename::can_cast(it.kind())) => |
@@ -134,7 +130,9 @@ fn find_definition( | |||
134 | .map(|it| it.referenced_or_defined(sema.db)) | 130 | .map(|it| it.referenced_or_defined(sema.db)) |
135 | }), | 131 | }), |
136 | } | 132 | } |
137 | .ok_or_else(|| format_err!("No references found at position")) | 133 | .ok_or_else(|| format_err!("No references found at position"))?; |
134 | |||
135 | Ok((name_like, def)) | ||
138 | } | 136 | } |
139 | 137 | ||
140 | fn rename_to_self(sema: &Semantics<RootDatabase>, local: hir::Local) -> RenameResult<SourceChange> { | 138 | fn rename_to_self(sema: &Semantics<RootDatabase>, local: hir::Local) -> RenameResult<SourceChange> { |
@@ -328,7 +326,7 @@ mod tests { | |||
328 | fn test_prepare_rename_namelikes() { | 326 | fn test_prepare_rename_namelikes() { |
329 | check_prepare(r"fn name$0<'lifetime>() {}", expect![[r#"3..7: name"#]]); | 327 | check_prepare(r"fn name$0<'lifetime>() {}", expect![[r#"3..7: name"#]]); |
330 | check_prepare(r"fn name<'lifetime$0>() {}", expect![[r#"8..17: 'lifetime"#]]); | 328 | check_prepare(r"fn name<'lifetime$0>() {}", expect![[r#"8..17: 'lifetime"#]]); |
331 | check_prepare(r"fn name<'lifetime>() { name$0(); }", expect![[r#"3..7: name"#]]); | 329 | check_prepare(r"fn name<'lifetime>() { name$0(); }", expect![[r#"23..27: name"#]]); |
332 | } | 330 | } |
333 | 331 | ||
334 | #[test] | 332 | #[test] |
diff --git a/crates/ide/src/typing.rs b/crates/ide/src/typing.rs index 4ad49eca0..37ae92350 100644 --- a/crates/ide/src/typing.rs +++ b/crates/ide/src/typing.rs | |||
@@ -23,7 +23,7 @@ use syntax::{ | |||
23 | algo::find_node_at_offset, | 23 | algo::find_node_at_offset, |
24 | ast::{self, edit::IndentLevel, AstToken}, | 24 | ast::{self, edit::IndentLevel, AstToken}, |
25 | AstNode, Parse, SourceFile, | 25 | AstNode, Parse, SourceFile, |
26 | SyntaxKind::{FIELD_EXPR, METHOD_CALL_EXPR}, | 26 | SyntaxKind::{self, FIELD_EXPR, METHOD_CALL_EXPR}, |
27 | TextRange, TextSize, | 27 | TextRange, TextSize, |
28 | }; | 28 | }; |
29 | 29 | ||
@@ -95,9 +95,16 @@ fn on_opening_brace_typed(file: &Parse<SourceFile>, offset: TextSize) -> Option< | |||
95 | } | 95 | } |
96 | 96 | ||
97 | let brace_token = file.tree().syntax().token_at_offset(offset).right_biased()?; | 97 | let brace_token = file.tree().syntax().token_at_offset(offset).right_biased()?; |
98 | if brace_token.kind() != SyntaxKind::L_CURLY { | ||
99 | return None; | ||
100 | } | ||
98 | 101 | ||
99 | // Remove the `{` to get a better parse tree, and reparse | 102 | // Remove the `{` to get a better parse tree, and reparse. |
100 | let file = file.reparse(&Indel::delete(brace_token.text_range())); | 103 | let range = brace_token.text_range(); |
104 | if !stdx::always!(range.len() == TextSize::of('{')) { | ||
105 | return None; | ||
106 | } | ||
107 | let file = file.reparse(&Indel::delete(range)); | ||
101 | 108 | ||
102 | if let Some(edit) = brace_expr(&file.tree(), offset) { | 109 | if let Some(edit) = brace_expr(&file.tree(), offset) { |
103 | return Some(edit); | 110 | return Some(edit); |
@@ -550,6 +557,29 @@ fn f() { | |||
550 | } | 557 | } |
551 | 558 | ||
552 | #[test] | 559 | #[test] |
560 | fn noop_in_string_literal() { | ||
561 | // Regression test for #9351 | ||
562 | type_char_noop( | ||
563 | '{', | ||
564 | r##" | ||
565 | fn check_with(ra_fixture: &str, expect: Expect) { | ||
566 | let base = r#" | ||
567 | enum E { T(), R$0, C } | ||
568 | use self::E::X; | ||
569 | const Z: E = E::C; | ||
570 | mod m {} | ||
571 | asdasdasdasdasdasda | ||
572 | sdasdasdasdasdasda | ||
573 | sdasdasdasdasd | ||
574 | "#; | ||
575 | let actual = completion_list(&format!("{}\n{}", base, ra_fixture)); | ||
576 | expect.assert_eq(&actual) | ||
577 | } | ||
578 | "##, | ||
579 | ); | ||
580 | } | ||
581 | |||
582 | #[test] | ||
553 | fn adds_closing_brace_for_use_tree() { | 583 | fn adds_closing_brace_for_use_tree() { |
554 | type_char( | 584 | type_char( |
555 | '{', | 585 | '{', |