aboutsummaryrefslogtreecommitdiff
path: root/crates/ide
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide')
-rw-r--r--crates/ide/src/display/navigation_target.rs8
-rw-r--r--crates/ide/src/references/rename.rs103
-rw-r--r--crates/ide/src/syntax_highlighting/highlight.rs9
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlighting.html4
4 files changed, 114 insertions, 10 deletions
diff --git a/crates/ide/src/display/navigation_target.rs b/crates/ide/src/display/navigation_target.rs
index 364be260c..2079c22a3 100644
--- a/crates/ide/src/display/navigation_target.rs
+++ b/crates/ide/src/display/navigation_target.rs
@@ -20,7 +20,7 @@ use syntax::{
20 20
21use crate::FileSymbol; 21use crate::FileSymbol;
22 22
23/// `NavigationTarget` represents and element in the editor's UI which you can 23/// `NavigationTarget` represents an element in the editor's UI which you can
24/// click on to navigate to a particular piece of code. 24/// click on to navigate to a particular piece of code.
25/// 25///
26/// Typically, a `NavigationTarget` corresponds to some element in the source 26/// Typically, a `NavigationTarget` corresponds to some element in the source
@@ -35,12 +35,10 @@ pub struct NavigationTarget {
35 /// Clients should use this range to answer "is the cursor inside the 35 /// Clients should use this range to answer "is the cursor inside the
36 /// element?" question. 36 /// element?" question.
37 pub full_range: TextRange, 37 pub full_range: TextRange,
38 /// A "most interesting" range withing the `full_range`. 38 /// A "most interesting" range within the `full_range`.
39 /// 39 ///
40 /// Typically, `full_range` is the whole syntax node, including doc 40 /// Typically, `full_range` is the whole syntax node, including doc
41 /// comments, and `focus_range` is the range of the identifier. "Most 41 /// comments, and `focus_range` is the range of the identifier.
42 /// interesting" range within the full range, typically the range of
43 /// identifier.
44 /// 42 ///
45 /// Clients should place the cursor on this range when navigating to this target. 43 /// Clients should place the cursor on this range when navigating to this target.
46 pub focus_range: Option<TextRange>, 44 pub focus_range: Option<TextRange>,
diff --git a/crates/ide/src/references/rename.rs b/crates/ide/src/references/rename.rs
index 2408a0181..175e7a31d 100644
--- a/crates/ide/src/references/rename.rs
+++ b/crates/ide/src/references/rename.rs
@@ -50,6 +50,17 @@ pub(crate) fn prepare_rename(
50 let sema = Semantics::new(db); 50 let sema = Semantics::new(db);
51 let source_file = sema.parse(position.file_id); 51 let source_file = sema.parse(position.file_id);
52 let syntax = source_file.syntax(); 52 let syntax = source_file.syntax();
53
54 let def = find_definition(&sema, syntax, position)?;
55 match def {
56 Definition::SelfType(_) => bail!("Cannot rename `Self`"),
57 Definition::ModuleDef(ModuleDef::BuiltinType(_)) => bail!("Cannot rename builtin type"),
58 _ => {}
59 };
60 let nav =
61 def.try_to_nav(sema.db).ok_or_else(|| format_err!("No references found at position"))?;
62 nav.focus_range.ok_or_else(|| format_err!("No identifier available to rename"))?;
63
53 let name_like = sema 64 let name_like = sema
54 .find_node_at_offset_with_descend(&syntax, position.offset) 65 .find_node_at_offset_with_descend(&syntax, position.offset)
55 .ok_or_else(|| format_err!("No references found at position"))?; 66 .ok_or_else(|| format_err!("No references found at position"))?;
@@ -507,7 +518,8 @@ fn source_edit_from_def(
507 def.try_to_nav(sema.db).ok_or_else(|| format_err!("No references found at position"))?; 518 def.try_to_nav(sema.db).ok_or_else(|| format_err!("No references found at position"))?;
508 519
509 let mut replacement_text = String::new(); 520 let mut replacement_text = String::new();
510 let mut repl_range = nav.focus_or_full_range(); 521 let mut repl_range =
522 nav.focus_range.ok_or_else(|| format_err!("No identifier available to rename"))?;
511 if let Definition::Local(local) = def { 523 if let Definition::Local(local) = def {
512 if let Either::Left(pat) = local.source(sema.db).value { 524 if let Either::Left(pat) = local.source(sema.db).value {
513 if matches!( 525 if matches!(
@@ -626,6 +638,49 @@ foo!(Foo$0);",
626 } 638 }
627 639
628 #[test] 640 #[test]
641 fn test_prepare_rename_tuple_field() {
642 check_prepare(
643 r#"
644struct Foo(i32);
645
646fn baz() {
647 let mut x = Foo(4);
648 x.0$0 = 5;
649}
650"#,
651 expect![[r#"No identifier available to rename"#]],
652 );
653 }
654
655 #[test]
656 fn test_prepare_rename_builtin() {
657 check_prepare(
658 r#"
659fn foo() {
660 let x: i32$0 = 0;
661}
662"#,
663 expect![[r#"Cannot rename builtin type"#]],
664 );
665 }
666
667 #[test]
668 fn test_prepare_rename_self() {
669 check_prepare(
670 r#"
671struct Foo {}
672
673impl Foo {
674 fn foo(self) -> Self$0 {
675 self
676 }
677}
678"#,
679 expect![[r#"Cannot rename `Self`"#]],
680 );
681 }
682
683 #[test]
629 fn test_rename_to_underscore() { 684 fn test_rename_to_underscore() {
630 check("_", r#"fn main() { let i$0 = 1; }"#, r#"fn main() { let _ = 1; }"#); 685 check("_", r#"fn main() { let i$0 = 1; }"#, r#"fn main() { let _ = 1; }"#);
631 } 686 }
@@ -1787,4 +1842,50 @@ fn foo() {
1787"#, 1842"#,
1788 ) 1843 )
1789 } 1844 }
1845
1846 #[test]
1847 fn test_rename_tuple_field() {
1848 check(
1849 "foo",
1850 r#"
1851struct Foo(i32);
1852
1853fn baz() {
1854 let mut x = Foo(4);
1855 x.0$0 = 5;
1856}
1857"#,
1858 "error: No identifier available to rename",
1859 );
1860 }
1861
1862 #[test]
1863 fn test_rename_builtin() {
1864 check(
1865 "foo",
1866 r#"
1867fn foo() {
1868 let x: i32$0 = 0;
1869}
1870"#,
1871 "error: Cannot rename builtin type",
1872 );
1873 }
1874
1875 #[test]
1876 fn test_rename_self() {
1877 check(
1878 "foo",
1879 r#"
1880struct Foo {}
1881
1882impl Foo {
1883 fn foo(self) -> Self$0 {
1884 self
1885 }
1886}
1887"#,
1888 "error: Cannot rename `Self`",
1889 );
1890 }
1790} 1891}
diff --git a/crates/ide/src/syntax_highlighting/highlight.rs b/crates/ide/src/syntax_highlighting/highlight.rs
index 8731699dc..b586dcc17 100644
--- a/crates/ide/src/syntax_highlighting/highlight.rs
+++ b/crates/ide/src/syntax_highlighting/highlight.rs
@@ -286,8 +286,13 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight {
286 let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Function)); 286 let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Function));
287 if let Some(item) = func.as_assoc_item(db) { 287 if let Some(item) = func.as_assoc_item(db) {
288 h |= HlMod::Associated; 288 h |= HlMod::Associated;
289 if func.self_param(db).is_none() { 289 match func.self_param(db) {
290 h |= HlMod::Static 290 Some(sp) => {
291 if let hir::Access::Exclusive = sp.access(db) {
292 h |= HlMod::Mutable;
293 }
294 }
295 None => h |= HlMod::Static,
291 } 296 }
292 297
293 match item.container(db) { 298 match item.container(db) {
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlighting.html b/crates/ide/src/syntax_highlighting/test_data/highlighting.html
index 4319e8b50..df4192194 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlighting.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlighting.html
@@ -81,7 +81,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
81 <span class="value_param">f</span><span class="operator">.</span><span class="function associated consuming">baz</span><span class="parenthesis">(</span><span class="self_keyword consuming mutable">self</span><span class="parenthesis">)</span> 81 <span class="value_param">f</span><span class="operator">.</span><span class="function associated consuming">baz</span><span class="parenthesis">(</span><span class="self_keyword consuming mutable">self</span><span class="parenthesis">)</span>
82 <span class="brace">}</span> 82 <span class="brace">}</span>
83 83
84 <span class="keyword">fn</span> <span class="function associated declaration">qux</span><span class="parenthesis">(</span><span class="operator">&</span><span class="keyword">mut</span> <span class="self_keyword declaration mutable">self</span><span class="parenthesis">)</span> <span class="brace">{</span> 84 <span class="keyword">fn</span> <span class="function associated declaration mutable">qux</span><span class="parenthesis">(</span><span class="operator">&</span><span class="keyword">mut</span> <span class="self_keyword declaration mutable">self</span><span class="parenthesis">)</span> <span class="brace">{</span>
85 <span class="self_keyword mutable">self</span><span class="operator">.</span><span class="field">x</span> <span class="operator">=</span> <span class="numeric_literal">0</span><span class="semicolon">;</span> 85 <span class="self_keyword mutable">self</span><span class="operator">.</span><span class="field">x</span> <span class="operator">=</span> <span class="numeric_literal">0</span><span class="semicolon">;</span>
86 <span class="brace">}</span> 86 <span class="brace">}</span>
87 87
@@ -100,7 +100,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
100 <span class="value_param">f</span><span class="operator">.</span><span class="function associated">baz</span><span class="parenthesis">(</span><span class="self_keyword">self</span><span class="parenthesis">)</span> 100 <span class="value_param">f</span><span class="operator">.</span><span class="function associated">baz</span><span class="parenthesis">(</span><span class="self_keyword">self</span><span class="parenthesis">)</span>
101 <span class="brace">}</span> 101 <span class="brace">}</span>
102 102
103 <span class="keyword">fn</span> <span class="function associated declaration">qux</span><span class="parenthesis">(</span><span class="operator">&</span><span class="keyword">mut</span> <span class="self_keyword declaration mutable">self</span><span class="parenthesis">)</span> <span class="brace">{</span> 103 <span class="keyword">fn</span> <span class="function associated declaration mutable">qux</span><span class="parenthesis">(</span><span class="operator">&</span><span class="keyword">mut</span> <span class="self_keyword declaration mutable">self</span><span class="parenthesis">)</span> <span class="brace">{</span>
104 <span class="self_keyword mutable">self</span><span class="operator">.</span><span class="field">x</span> <span class="operator">=</span> <span class="numeric_literal">0</span><span class="semicolon">;</span> 104 <span class="self_keyword mutable">self</span><span class="operator">.</span><span class="field">x</span> <span class="operator">=</span> <span class="numeric_literal">0</span><span class="semicolon">;</span>
105 <span class="brace">}</span> 105 <span class="brace">}</span>
106 106