diff options
author | Paul Daniel Faria <[email protected]> | 2020-08-08 19:14:18 +0100 |
---|---|---|
committer | Paul Daniel Faria <[email protected]> | 2020-08-08 19:14:18 +0100 |
commit | 6cde0b1aa0f6b8623c6b81b2396f4a0345891233 (patch) | |
tree | 9d558ee8eeace0aadf241c190248d008e362d17f /crates/ra_ide/src | |
parent | a69f19a6a5899bdfb6fc498371650bf54263deff (diff) |
Add support for extern crate
This adds syntax highlighting, hover and goto def
functionality for extern crate
Diffstat (limited to 'crates/ra_ide/src')
-rw-r--r-- | crates/ra_ide/src/display/short_label.rs | 6 | ||||
-rw-r--r-- | crates/ra_ide/src/goto_definition.rs | 37 | ||||
-rw-r--r-- | crates/ra_ide/src/hover.rs | 49 | ||||
-rw-r--r-- | crates/ra_ide/src/references.rs | 4 | ||||
-rw-r--r-- | crates/ra_ide/src/syntax_highlighting.rs | 2 | ||||
-rw-r--r-- | crates/ra_ide/src/syntax_highlighting/tests.rs | 17 |
6 files changed, 102 insertions, 13 deletions
diff --git a/crates/ra_ide/src/display/short_label.rs b/crates/ra_ide/src/display/short_label.rs index 0fdf8e9a5..b5ff9fa2d 100644 --- a/crates/ra_ide/src/display/short_label.rs +++ b/crates/ra_ide/src/display/short_label.rs | |||
@@ -47,6 +47,12 @@ impl ShortLabel for ast::Module { | |||
47 | } | 47 | } |
48 | } | 48 | } |
49 | 49 | ||
50 | impl ShortLabel for ast::SourceFile { | ||
51 | fn short_label(&self) -> Option<String> { | ||
52 | None | ||
53 | } | ||
54 | } | ||
55 | |||
50 | impl ShortLabel for ast::TypeAlias { | 56 | impl ShortLabel for ast::TypeAlias { |
51 | fn short_label(&self) -> Option<String> { | 57 | fn short_label(&self) -> Option<String> { |
52 | short_label_from_node(self, "type ") | 58 | short_label_from_node(self, "type ") |
diff --git a/crates/ra_ide/src/goto_definition.rs b/crates/ra_ide/src/goto_definition.rs index 4e3f428fa..b44b6fe22 100644 --- a/crates/ra_ide/src/goto_definition.rs +++ b/crates/ra_ide/src/goto_definition.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | use hir::Semantics; | 1 | use hir::Semantics; |
2 | use ra_ide_db::{ | 2 | use ra_ide_db::{ |
3 | defs::{classify_name, classify_name_ref, NameClass}, | 3 | defs::{classify_name, classify_name_ref}, |
4 | symbol_index, RootDatabase, | 4 | symbol_index, RootDatabase, |
5 | }; | 5 | }; |
6 | use ra_syntax::{ | 6 | use ra_syntax::{ |
@@ -40,10 +40,7 @@ pub(crate) fn goto_definition( | |||
40 | reference_definition(&sema, &name_ref).to_vec() | 40 | reference_definition(&sema, &name_ref).to_vec() |
41 | }, | 41 | }, |
42 | ast::Name(name) => { | 42 | ast::Name(name) => { |
43 | let def = match classify_name(&sema, &name)? { | 43 | let def = classify_name(&sema, &name)?.definition(sema.db)?; |
44 | NameClass::Definition(def) | NameClass::ConstReference(def) => def, | ||
45 | NameClass::FieldShorthand { local: _, field } => field, | ||
46 | }; | ||
47 | let nav = def.try_to_nav(sema.db)?; | 44 | let nav = def.try_to_nav(sema.db)?; |
48 | vec![nav] | 45 | vec![nav] |
49 | }, | 46 | }, |
@@ -85,9 +82,7 @@ pub(crate) fn reference_definition( | |||
85 | name_ref: &ast::NameRef, | 82 | name_ref: &ast::NameRef, |
86 | ) -> ReferenceResult { | 83 | ) -> ReferenceResult { |
87 | let name_kind = classify_name_ref(sema, name_ref); | 84 | let name_kind = classify_name_ref(sema, name_ref); |
88 | if let Some(def) = name_kind { | 85 | if let Some(def) = name_kind.and_then(|def| def.definition(sema.db)) { |
89 | let def = def.definition(); | ||
90 | |||
91 | return match def.try_to_nav(sema.db) { | 86 | return match def.try_to_nav(sema.db) { |
92 | Some(nav) => ReferenceResult::Exact(nav), | 87 | Some(nav) => ReferenceResult::Exact(nav), |
93 | None => ReferenceResult::Approximate(Vec::new()), | 88 | None => ReferenceResult::Approximate(Vec::new()), |
@@ -134,6 +129,32 @@ mod tests { | |||
134 | } | 129 | } |
135 | 130 | ||
136 | #[test] | 131 | #[test] |
132 | fn goto_def_for_extern_crate() { | ||
133 | check( | ||
134 | r#" | ||
135 | //- /main.rs | ||
136 | extern crate std<|>; | ||
137 | //- /std/lib.rs | ||
138 | // empty | ||
139 | //^ file | ||
140 | "#, | ||
141 | ) | ||
142 | } | ||
143 | |||
144 | #[test] | ||
145 | fn goto_def_for_renamed_extern_crate() { | ||
146 | check( | ||
147 | r#" | ||
148 | //- /main.rs | ||
149 | extern crate std as abc<|>; | ||
150 | //- /std/lib.rs | ||
151 | // empty | ||
152 | //^ file | ||
153 | "#, | ||
154 | ) | ||
155 | } | ||
156 | |||
157 | #[test] | ||
137 | fn goto_def_in_items() { | 158 | fn goto_def_in_items() { |
138 | check( | 159 | check( |
139 | r#" | 160 | r#" |
diff --git a/crates/ra_ide/src/hover.rs b/crates/ra_ide/src/hover.rs index aa48cb412..a632ea6a2 100644 --- a/crates/ra_ide/src/hover.rs +++ b/crates/ra_ide/src/hover.rs | |||
@@ -85,8 +85,8 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn | |||
85 | let node = token.parent(); | 85 | let node = token.parent(); |
86 | let definition = match_ast! { | 86 | let definition = match_ast! { |
87 | match node { | 87 | match node { |
88 | ast::NameRef(name_ref) => classify_name_ref(&sema, &name_ref).map(|d| d.definition()), | 88 | ast::NameRef(name_ref) => classify_name_ref(&sema, &name_ref).and_then(|d| d.definition(sema.db)), |
89 | ast::Name(name) => classify_name(&sema, &name).map(|d| d.definition()), | 89 | ast::Name(name) => classify_name(&sema, &name).and_then(|d| d.definition(sema.db)), |
90 | _ => None, | 90 | _ => None, |
91 | } | 91 | } |
92 | }; | 92 | }; |
@@ -304,7 +304,10 @@ fn hover_for_definition(db: &RootDatabase, def: Definition) -> Option<Markup> { | |||
304 | let docs = Documentation::from_ast(&it).map(Into::into); | 304 | let docs = Documentation::from_ast(&it).map(Into::into); |
305 | hover_markup(docs, it.short_label(), mod_path) | 305 | hover_markup(docs, it.short_label(), mod_path) |
306 | } | 306 | } |
307 | _ => None, | 307 | ModuleSource::SourceFile(it) => { |
308 | let docs = Documentation::from_ast(&it).map(Into::into); | ||
309 | hover_markup(docs, it.short_label(), mod_path) | ||
310 | } | ||
308 | }, | 311 | }, |
309 | ModuleDef::Function(it) => from_def_source(db, it, mod_path), | 312 | ModuleDef::Function(it) => from_def_source(db, it, mod_path), |
310 | ModuleDef::Adt(Adt::Struct(it)) => from_def_source(db, it, mod_path), | 313 | ModuleDef::Adt(Adt::Struct(it)) => from_def_source(db, it, mod_path), |
@@ -1107,6 +1110,46 @@ fn bar() { fo<|>o(); } | |||
1107 | } | 1110 | } |
1108 | 1111 | ||
1109 | #[test] | 1112 | #[test] |
1113 | fn test_hover_extern_crate() { | ||
1114 | check( | ||
1115 | r#" | ||
1116 | //- /main.rs | ||
1117 | extern crate st<|>d; | ||
1118 | //- /std/lib.rs | ||
1119 | //! Standard library for this test | ||
1120 | //! | ||
1121 | //! Printed? | ||
1122 | //! abc123 | ||
1123 | "#, | ||
1124 | expect![[r#" | ||
1125 | *std* | ||
1126 | Standard library for this test | ||
1127 | |||
1128 | Printed? | ||
1129 | abc123 | ||
1130 | "#]], | ||
1131 | ); | ||
1132 | check( | ||
1133 | r#" | ||
1134 | //- /main.rs | ||
1135 | extern crate std as ab<|>c; | ||
1136 | //- /std/lib.rs | ||
1137 | //! Standard library for this test | ||
1138 | //! | ||
1139 | //! Printed? | ||
1140 | //! abc123 | ||
1141 | "#, | ||
1142 | expect![[r#" | ||
1143 | *abc* | ||
1144 | Standard library for this test | ||
1145 | |||
1146 | Printed? | ||
1147 | abc123 | ||
1148 | "#]], | ||
1149 | ); | ||
1150 | } | ||
1151 | |||
1152 | #[test] | ||
1110 | fn test_hover_mod_with_same_name_as_function() { | 1153 | fn test_hover_mod_with_same_name_as_function() { |
1111 | check( | 1154 | check( |
1112 | r#" | 1155 | r#" |
diff --git a/crates/ra_ide/src/references.rs b/crates/ra_ide/src/references.rs index cf456630a..9dd228b9c 100644 --- a/crates/ra_ide/src/references.rs +++ b/crates/ra_ide/src/references.rs | |||
@@ -130,13 +130,13 @@ fn find_name( | |||
130 | opt_name: Option<ast::Name>, | 130 | opt_name: Option<ast::Name>, |
131 | ) -> Option<RangeInfo<Definition>> { | 131 | ) -> Option<RangeInfo<Definition>> { |
132 | if let Some(name) = opt_name { | 132 | if let Some(name) = opt_name { |
133 | let def = classify_name(sema, &name)?.definition(); | 133 | let def = classify_name(sema, &name)?.definition(sema.db)?; |
134 | let range = name.syntax().text_range(); | 134 | let range = name.syntax().text_range(); |
135 | return Some(RangeInfo::new(range, def)); | 135 | return Some(RangeInfo::new(range, def)); |
136 | } | 136 | } |
137 | let name_ref = | 137 | let name_ref = |
138 | sema.find_node_at_offset_with_descend::<ast::NameRef>(&syntax, position.offset)?; | 138 | sema.find_node_at_offset_with_descend::<ast::NameRef>(&syntax, position.offset)?; |
139 | let def = classify_name_ref(sema, &name_ref)?.definition(); | 139 | let def = classify_name_ref(sema, &name_ref)?.definition(sema.db)?; |
140 | let range = name_ref.syntax().text_range(); | 140 | let range = name_ref.syntax().text_range(); |
141 | Some(RangeInfo::new(range, def)) | 141 | Some(RangeInfo::new(range, def)) |
142 | } | 142 | } |
diff --git a/crates/ra_ide/src/syntax_highlighting.rs b/crates/ra_ide/src/syntax_highlighting.rs index 89efe71da..ec442bcd8 100644 --- a/crates/ra_ide/src/syntax_highlighting.rs +++ b/crates/ra_ide/src/syntax_highlighting.rs | |||
@@ -483,6 +483,7 @@ fn highlight_element( | |||
483 | }; | 483 | }; |
484 | 484 | ||
485 | match name_kind { | 485 | match name_kind { |
486 | Some(NameClass::ExternCrate(_)) => HighlightTag::Module.into(), | ||
486 | Some(NameClass::Definition(def)) => { | 487 | Some(NameClass::Definition(def)) => { |
487 | highlight_name(db, def) | HighlightModifier::Definition | 488 | highlight_name(db, def) | HighlightModifier::Definition |
488 | } | 489 | } |
@@ -500,6 +501,7 @@ fn highlight_element( | |||
500 | let name_ref = element.into_node().and_then(ast::NameRef::cast).unwrap(); | 501 | let name_ref = element.into_node().and_then(ast::NameRef::cast).unwrap(); |
501 | match classify_name_ref(sema, &name_ref) { | 502 | match classify_name_ref(sema, &name_ref) { |
502 | Some(name_kind) => match name_kind { | 503 | Some(name_kind) => match name_kind { |
504 | NameRefClass::ExternCrate(_) => HighlightTag::Module.into(), | ||
503 | NameRefClass::Definition(def) => { | 505 | NameRefClass::Definition(def) => { |
504 | if let Definition::Local(local) = &def { | 506 | if let Definition::Local(local) = &def { |
505 | if let Some(name) = local.name(db) { | 507 | if let Some(name) = local.name(db) { |
diff --git a/crates/ra_ide/src/syntax_highlighting/tests.rs b/crates/ra_ide/src/syntax_highlighting/tests.rs index b9b358022..b8d60bdc6 100644 --- a/crates/ra_ide/src/syntax_highlighting/tests.rs +++ b/crates/ra_ide/src/syntax_highlighting/tests.rs | |||
@@ -380,6 +380,23 @@ macro_rules! noop { | |||
380 | ); | 380 | ); |
381 | } | 381 | } |
382 | 382 | ||
383 | #[test] | ||
384 | fn test_extern_crate() { | ||
385 | check_highlighting( | ||
386 | r#" | ||
387 | //- /main.rs | ||
388 | extern crate std; | ||
389 | extern crate alloc as abc; | ||
390 | //- /std/lib.rs | ||
391 | pub struct S; | ||
392 | //- /alloc/lib.rs | ||
393 | pub struct A | ||
394 | "#, | ||
395 | expect_file!["crates/ra_ide/test_data/highlight_extern_crate.html"], | ||
396 | false, | ||
397 | ); | ||
398 | } | ||
399 | |||
383 | /// Highlights the code given by the `ra_fixture` argument, renders the | 400 | /// Highlights the code given by the `ra_fixture` argument, renders the |
384 | /// result as HTML, and compares it with the HTML file given as `snapshot`. | 401 | /// result as HTML, and compares it with the HTML file given as `snapshot`. |
385 | /// Note that the `snapshot` file is overwritten by the rendered HTML. | 402 | /// Note that the `snapshot` file is overwritten by the rendered HTML. |