Skip to content

Commit 1d6f291

Browse files
committed
Move resolver into impls, work on tests
1 parent 108b953 commit 1d6f291

File tree

7 files changed

+138
-71
lines changed

7 files changed

+138
-71
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/ra_hir/src/code_model.rs

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -186,21 +186,34 @@ impl ModuleDef {
186186
module.visibility_of(db, self)
187187
}
188188

189-
pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
189+
pub fn name(&self, db: &dyn HirDatabase) -> Option<Name> {
190190
match self {
191-
ModuleDef::Adt(it) => Some(it.name(db)),
192-
ModuleDef::Trait(it) => Some(it.name(db)),
193-
ModuleDef::Function(it) => Some(it.name(db)),
194-
ModuleDef::EnumVariant(it) => Some(it.name(db)),
195-
ModuleDef::TypeAlias(it) => Some(it.name(db)),
196-
197-
ModuleDef::Module(it) => it.name(db),
198-
ModuleDef::Const(it) => it.name(db),
199-
ModuleDef::Static(it) => it.name(db),
200-
201-
ModuleDef::BuiltinType(it) => Some(it.as_name()),
191+
ModuleDef::Module(m) => m.name(db),
192+
ModuleDef::Function(m) => Some(m.name(db)),
193+
ModuleDef::Adt(m) => Some(m.name(db)),
194+
ModuleDef::EnumVariant(m) => Some(m.name(db)),
195+
ModuleDef::Const(m) => {m.name(db)},
196+
ModuleDef::Static(m) => {m.name(db)},
197+
ModuleDef::Trait(m) => {Some(m.name(db))},
198+
ModuleDef::TypeAlias(m) => {Some(m.name(db))},
199+
ModuleDef::BuiltinType(m) => {Some(m.as_name())}
202200
}
203201
}
202+
203+
pub fn resolver<D: DefDatabase + HirDatabase>(&self, db: &D) -> Option<Resolver> {
204+
Some(match self {
205+
ModuleDef::Module(m) => Into::<ModuleId>::into(m.clone()).resolver(db),
206+
ModuleDef::Function(f) => Into::<FunctionId>::into(f.clone()).resolver(db),
207+
ModuleDef::Adt(adt) => Into::<AdtId>::into(adt.clone()).resolver(db),
208+
ModuleDef::EnumVariant(ev) => Into::<GenericDefId>::into(Into::<GenericDef>::into(ev.clone())).resolver(db),
209+
ModuleDef::Const(c) => Into::<GenericDefId>::into(Into::<GenericDef>::into(c.clone())).resolver(db),
210+
ModuleDef::Static(s) => Into::<StaticId>::into(s.clone()).resolver(db),
211+
ModuleDef::Trait(t) => Into::<TraitId>::into(t.clone()).resolver(db),
212+
ModuleDef::TypeAlias(t) => Into::<ModuleId>::into(t.module(db)).resolver(db),
213+
// TODO: This should be a resolver relative to `std`
214+
ModuleDef::BuiltinType(_t) => None?
215+
})
216+
}
204217
}
205218

206219
pub use hir_def::{

crates/ra_ide/src/hover.rs

Lines changed: 93 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,8 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn
146146
}
147147
} {
148148
let range = sema.original_range(&node).range;
149-
let text = hover_text_from_name_kind(db, name_kind.clone()).map(|text| rewrite_links(db, &text, &name_kind).unwrap_or(text));
149+
let text = hover_text_from_name_kind(db, name_kind.clone());
150+
let text = text.map(|text| rewrite_links(db, &text, &name_kind).unwrap_or(text));
150151
res.extend(text);
151152

152153
if !res.is_empty() {
@@ -405,8 +406,8 @@ fn rewrite_links(db: &RootDatabase, markdown: &str, definition: &Definition) ->
405406
Err(_) => {
406407
let link_str = String::from_utf8(link.url.clone()).unwrap();
407408
let link_text = String::from_utf8(link.title.clone()).unwrap();
408-
let resolved = try_resolve_path(db, definition, &link_str)
409-
.or_else(|| try_resolve_intra(db, definition, &link_text, &link_str));
409+
let resolved = try_resolve_intra(db, definition, &link_text, &link_str)
410+
.or_else(|| try_resolve_path(db, definition, &link_str));
410411

411412
if let Some(resolved) = resolved {
412413
link.url = resolved.as_bytes().to_vec();
@@ -420,7 +421,7 @@ fn rewrite_links(db: &RootDatabase, markdown: &str, definition: &Definition) ->
420421
});
421422
let mut out = Vec::new();
422423
format_commonmark(doc, &ComrakOptions::default(), &mut out).ok()?;
423-
Some(String::from_utf8(out).unwrap())
424+
Some(String::from_utf8(out).unwrap().trim().to_string())
424425
}
425426

426427
#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)]
@@ -470,32 +471,7 @@ fn try_resolve_intra(db: &RootDatabase, definition: &Definition, link_text: &str
470471
let modpath = ModPath::from_src(path, &Hygiene::new_unhygienic()).unwrap();
471472

472473
// Resolve it relative to symbol's location (according to the RFC this should consider small scopes
473-
let resolver = {
474-
use ra_hir_def::*;
475-
use hir::*;
476-
477-
// TODO: This should be replaced by implementing HasResolver/TryHasResolver on ModuleDef and Definition.
478-
match definition {
479-
Definition::ModuleDef(def) => match def {
480-
ModuleDef::Module(m) => Into::<ModuleId>::into(m.clone()).resolver(db),
481-
ModuleDef::Function(f) => Into::<FunctionId>::into(f.clone()).resolver(db),
482-
ModuleDef::Adt(adt) => Into::<AdtId>::into(adt.clone()).resolver(db),
483-
ModuleDef::EnumVariant(ev) => Into::<GenericDefId>::into(Into::<GenericDef>::into(ev.clone())).resolver(db),
484-
ModuleDef::Const(c) => Into::<GenericDefId>::into(Into::<GenericDef>::into(c.clone())).resolver(db),
485-
ModuleDef::Static(s) => Into::<StaticId>::into(s.clone()).resolver(db),
486-
ModuleDef::Trait(t) => Into::<TraitId>::into(t.clone()).resolver(db),
487-
ModuleDef::TypeAlias(t) => Into::<ModuleId>::into(t.module(db)).resolver(db),
488-
// TODO: This should be a resolver relative to `std`
489-
ModuleDef::BuiltinType(_t) => Into::<ModuleId>::into(definition.module(db)?).resolver(db)
490-
},
491-
Definition::Field(field) => Into::<VariantId>::into(Into::<VariantDef>::into(field.parent_def(db))).resolver(db),
492-
Definition::Macro(m) => Into::<ModuleId>::into(m.module(db)?).resolver(db),
493-
Definition::SelfType(imp) => Into::<ImplId>::into(imp.clone()).resolver(db),
494-
// it's possible, read probable, that other arms of this are also unreachable
495-
Definition::Local(_local) => unreachable!(),
496-
Definition::TypeParam(tp) => Into::<ModuleId>::into(tp.module(db)).resolver(db)
497-
}
498-
};
474+
let resolver = definition.resolver(db)?;
499475

500476
// Namespace disambiguation
501477
let namespace = Namespace::from_intra_spec(link_target);
@@ -527,7 +503,7 @@ fn try_resolve_intra(db: &RootDatabase, definition: &Definition, link_text: &str
527503
get_doc_url(db, &krate)?
528504
.join(&format!("{}/", krate.display_name(db)?)).ok()?
529505
.join(&path.segments.iter().map(|name| format!("{}", name)).join("/")).ok()?
530-
.join(&get_symbol_filename(db, definition)?).ok()?
506+
.join(&get_symbol_filename(db, &Definition::ModuleDef(def))?).ok()?
531507
.into_string()
532508
)
533509
}
@@ -637,11 +613,20 @@ mod tests {
637613

638614
use crate::mock_analysis::analysis_and_position;
639615

640-
fn trim_markup(s: &str) -> &str {
641-
s.trim_start_matches("```rust\n").trim_end_matches("\n```")
616+
fn trim_markup(s: &str) -> String {
617+
s
618+
.replace("``` rust", "```rust")
619+
.replace("-----", "___")
620+
.replace("\n\n___\n\n", "\n___\n\n")
621+
.replace("\\<-", "<-")
622+
.trim_start_matches("test\n```\n\n")
623+
.trim_start_matches("```rust\n")
624+
.trim_start_matches("test\n```\n\n```rust\n")
625+
.trim_end_matches("\n```")
626+
.to_string()
642627
}
643628

644-
fn trim_markup_opt(s: Option<&str>) -> Option<&str> {
629+
fn trim_markup_opt(s: Option<&str>) -> Option<String> {
645630
s.map(trim_markup)
646631
}
647632

@@ -689,7 +674,7 @@ fn main() {
689674
);
690675
let hover = analysis.hover(position).unwrap().unwrap();
691676
assert_eq!(hover.range, TextRange::new(58.into(), 63.into()));
692-
assert_eq!(trim_markup_opt(hover.info.first()), Some("u32"));
677+
assert_eq!(trim_markup_opt(hover.info.first()).as_deref(), Some("u32"));
693678
}
694679

695680
#[test]
@@ -818,7 +803,7 @@ fn main() {
818803
};
819804
}
820805
"#,
821-
&["Foo\n```\n\n```rust\nfield_a: u32"],
806+
&["test::Foo\n```\n\n```rust\nfield_a: u32"],
822807
);
823808

824809
// Hovering over the field in the definition
@@ -835,7 +820,7 @@ fn main() {
835820
};
836821
}
837822
"#,
838-
&["Foo\n```\n\n```rust\nfield_a: u32"],
823+
&["test::Foo\n```\n\n```rust\nfield_a: u32"],
839824
);
840825
}
841826

@@ -888,7 +873,7 @@ fn main() {
888873
",
889874
);
890875
let hover = analysis.hover(position).unwrap().unwrap();
891-
assert_eq!(trim_markup_opt(hover.info.first()), Some("Option\n```\n\n```rust\nSome"));
876+
assert_eq!(trim_markup_opt(hover.info.first()).as_deref(), Some("test::Option\n```\n\n```rust\nSome"));
892877

893878
let (analysis, position) = analysis_and_position(
894879
"
@@ -901,7 +886,7 @@ fn main() {
901886
",
902887
);
903888
let hover = analysis.hover(position).unwrap().unwrap();
904-
assert_eq!(trim_markup_opt(hover.info.first()), Some("Option<i32>"));
889+
assert_eq!(trim_markup_opt(hover.info.first()).as_deref(), Some("Option<i32>"));
905890
}
906891

907892
#[test]
@@ -915,7 +900,7 @@ fn main() {
915900
}
916901
"#,
917902
&["
918-
Option
903+
test::Option
919904
```
920905
921906
```rust
@@ -940,7 +925,7 @@ The None variant
940925
}
941926
"#,
942927
&["
943-
Option
928+
test::Option
944929
```
945930
946931
```rust
@@ -958,14 +943,14 @@ The Some variant
958943
fn hover_for_local_variable() {
959944
let (analysis, position) = analysis_and_position("fn func(foo: i32) { fo<|>o; }");
960945
let hover = analysis.hover(position).unwrap().unwrap();
961-
assert_eq!(trim_markup_opt(hover.info.first()), Some("i32"));
946+
assert_eq!(trim_markup_opt(hover.info.first()).as_deref(), Some("i32"));
962947
}
963948

964949
#[test]
965950
fn hover_for_local_variable_pat() {
966951
let (analysis, position) = analysis_and_position("fn func(fo<|>o: i32) {}");
967952
let hover = analysis.hover(position).unwrap().unwrap();
968-
assert_eq!(trim_markup_opt(hover.info.first()), Some("i32"));
953+
assert_eq!(trim_markup_opt(hover.info.first()).as_deref(), Some("i32"));
969954
}
970955

971956
#[test]
@@ -976,14 +961,14 @@ fn func(foo: i32) { if true { <|>foo; }; }
976961
",
977962
);
978963
let hover = analysis.hover(position).unwrap().unwrap();
979-
assert_eq!(trim_markup_opt(hover.info.first()), Some("i32"));
964+
assert_eq!(trim_markup_opt(hover.info.first()).as_deref(), Some("i32"));
980965
}
981966

982967
#[test]
983968
fn hover_for_param_edge() {
984969
let (analysis, position) = analysis_and_position("fn func(<|>foo: i32) {}");
985970
let hover = analysis.hover(position).unwrap().unwrap();
986-
assert_eq!(trim_markup_opt(hover.info.first()), Some("i32"));
971+
assert_eq!(trim_markup_opt(hover.info.first()).as_deref(), Some("i32"));
987972
}
988973

989974
#[test]
@@ -1004,7 +989,7 @@ fn func(foo: i32) { if true { <|>foo; }; }
1004989
",
1005990
);
1006991
let hover = analysis.hover(position).unwrap().unwrap();
1007-
assert_eq!(trim_markup_opt(hover.info.first()), Some("Thing"));
992+
assert_eq!(trim_markup_opt(hover.info.first()).as_deref(), Some("Thing"));
1008993
}
1009994

1010995
#[test]
@@ -1028,8 +1013,8 @@ fn func(foo: i32) { if true { <|>foo; }; }
10281013
);
10291014
let hover = analysis.hover(position).unwrap().unwrap();
10301015
assert_eq!(
1031-
trim_markup_opt(hover.info.first()),
1032-
Some("wrapper::Thing\n```\n\n```rust\nfn new() -> Thing")
1016+
trim_markup_opt(hover.info.first()).as_deref(),
1017+
Some("test::wrapper::Thing\n```\n\n```rust\nfn new() -> Thing")
10331018
);
10341019
}
10351020

@@ -1052,7 +1037,7 @@ fn func(foo: i32) { if true { <|>foo; }; }
10521037
",
10531038
);
10541039
let hover = analysis.hover(position).unwrap().unwrap();
1055-
assert_eq!(trim_markup_opt(hover.info.first()), Some("const C: u32"));
1040+
assert_eq!(trim_markup_opt(hover.info.first()).as_deref(), Some("const C: u32"));
10561041
}
10571042

10581043
#[test]
@@ -1068,7 +1053,7 @@ fn func(foo: i32) { if true { <|>foo; }; }
10681053
",
10691054
);
10701055
let hover = analysis.hover(position).unwrap().unwrap();
1071-
assert_eq!(trim_markup_opt(hover.info.first()), Some("Thing"));
1056+
assert_eq!(trim_markup_opt(hover.info.first()).as_deref(), Some("Thing"));
10721057

10731058
/* FIXME: revive these tests
10741059
let (analysis, position) = analysis_and_position(
@@ -1125,7 +1110,7 @@ fn func(foo: i32) { if true { <|>foo; }; }
11251110
",
11261111
);
11271112
let hover = analysis.hover(position).unwrap().unwrap();
1128-
assert_eq!(trim_markup_opt(hover.info.first()), Some("i32"));
1113+
assert_eq!(trim_markup_opt(hover.info.first()).as_deref(), Some("i32"));
11291114
}
11301115

11311116
#[test]
@@ -1142,7 +1127,7 @@ fn func(foo: i32) { if true { <|>foo; }; }
11421127
",
11431128
);
11441129
let hover = analysis.hover(position).unwrap().unwrap();
1145-
assert_eq!(trim_markup_opt(hover.info.first()), Some("macro_rules! foo"));
1130+
assert_eq!(trim_markup_opt(hover.info.first()).as_deref(), Some("macro_rules! foo"));
11461131
}
11471132

11481133
#[test]
@@ -1153,7 +1138,7 @@ fn func(foo: i32) { if true { <|>foo; }; }
11531138
",
11541139
);
11551140
let hover = analysis.hover(position).unwrap().unwrap();
1156-
assert_eq!(trim_markup_opt(hover.info.first()), Some("i32"));
1141+
assert_eq!(trim_markup_opt(hover.info.first()).as_deref(), Some("i32"));
11571142
}
11581143

11591144
#[test]
@@ -1414,6 +1399,59 @@ fn func(foo: i32) { if true { <|>foo; }; }
14141399
);
14151400
}
14161401

1402+
#[test]
1403+
fn test_hover_path_link() {
1404+
check_hover_result(
1405+
r"
1406+
//- /lib.rs
1407+
pub struct Foo;
1408+
/// [Foo](struct.Foo.html)
1409+
pub struct B<|>ar
1410+
",
1411+
&["pub struct Bar\n```\n___\n\n[Foo](https://docs.rs/test/*/test/struct.Foo.html)"]
1412+
);
1413+
}
1414+
1415+
#[test]
1416+
fn test_hover_intra_link() {
1417+
check_hover_result(
1418+
r"
1419+
//- /lib.rs
1420+
pub struct Foo;
1421+
/// [Foo](Foo)
1422+
pub struct B<|>ar
1423+
",
1424+
&["pub struct Bar\n```\n___\n\n[Foo](https://docs.rs/test/*/test/struct.Foo.html)"]
1425+
);
1426+
}
1427+
1428+
#[test]
1429+
fn test_hover_intra_link_shortlink() {
1430+
check_hover_result(
1431+
r"
1432+
//- /lib.rs
1433+
pub struct Foo;
1434+
/// [Foo]
1435+
pub struct B<|>ar
1436+
",
1437+
&["pub struct Bar\n```\n___\n\n[Foo](https://docs.rs/test/*/test/struct.Foo.html)"]
1438+
);
1439+
}
1440+
1441+
#[test]
1442+
fn test_hover_intra_link_namespaced() {
1443+
check_hover_result(
1444+
r"
1445+
//- /lib.rs
1446+
pub struct Foo;
1447+
fn Foo() {}
1448+
/// [Foo()]
1449+
pub struct B<|>ar
1450+
",
1451+
&["pub struct Bar\n```\n___\n\n[Foo](https://docs.rs/test/*/test/struct.Foo.html)"]
1452+
);
1453+
}
1454+
14171455
#[test]
14181456
fn test_hover_macro_generated_struct_fn_doc_comment() {
14191457
mark::check!(hover_macro_generated_struct_fn_doc_comment);
@@ -1438,7 +1476,7 @@ fn func(foo: i32) { if true { <|>foo; }; }
14381476
bar.fo<|>o();
14391477
}
14401478
"#,
1441-
&["Bar\n```\n\n```rust\nfn foo(&self)\n```\n___\n\n Do the foo"],
1479+
&["test::Bar\n```\n\n```rust\nfn foo(&self)\n```\n___\n\nDo the foo"],
14421480
);
14431481
}
14441482

@@ -1466,7 +1504,7 @@ fn func(foo: i32) { if true { <|>foo; }; }
14661504
bar.fo<|>o();
14671505
}
14681506
"#,
1469-
&["Bar\n```\n\n```rust\nfn foo(&self)\n```\n___\n\nDo the foo"],
1507+
&["test::Bar\n```\n\n```rust\nfn foo(&self)\n```\n___\n\nDo the foo"],
14701508
);
14711509
}
14721510

0 commit comments

Comments
 (0)