Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide/src/doc_links/tests.rs')
-rw-r--r--crates/ide/src/doc_links/tests.rs109
1 files changed, 84 insertions, 25 deletions
diff --git a/crates/ide/src/doc_links/tests.rs b/crates/ide/src/doc_links/tests.rs
index 91785be8d8..6af156fa66 100644
--- a/crates/ide/src/doc_links/tests.rs
+++ b/crates/ide/src/doc_links/tests.rs
@@ -5,7 +5,7 @@ use hir::Semantics;
use ide_db::{
FilePosition, FileRange, RootDatabase,
defs::Definition,
- documentation::{Documentation, HasDocs},
+ documentation::{DocsRangeMap, Documentation, HasDocs},
};
use itertools::Itertools;
use syntax::{AstNode, SyntaxNode, ast, match_ast};
@@ -45,8 +45,8 @@ fn check_external_docs(
fn check_rewrite(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
let (analysis, position) = fixture::position(ra_fixture);
let sema = &Semantics::new(&analysis.db);
- let (cursor_def, docs) = def_under_cursor(sema, &position);
- let res = rewrite_links(sema.db, docs.as_str(), cursor_def);
+ let (cursor_def, docs, range) = def_under_cursor(sema, &position);
+ let res = rewrite_links(sema.db, docs.as_str(), cursor_def, Some(range));
expect.assert_eq(&res)
}
@@ -56,12 +56,14 @@ fn check_doc_links(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
let (analysis, position, mut expected) = fixture::annotations(ra_fixture);
expected.sort_by_key(key_fn);
let sema = &Semantics::new(&analysis.db);
- let (cursor_def, docs) = def_under_cursor(sema, &position);
+ let (cursor_def, docs, range) = def_under_cursor(sema, &position);
let defs = extract_definitions_from_docs(&docs);
let actual: Vec<_> = defs
.into_iter()
- .flat_map(|(_, link, ns)| {
- let def = resolve_doc_path_for_def(sema.db, cursor_def, &link, ns)
+ .flat_map(|(text_range, link, ns)| {
+ let attr = range.map(text_range);
+ let is_inner_attr = attr.map(|(_file, attr)| attr.is_inner_attr()).unwrap_or(false);
+ let def = resolve_doc_path_for_def(sema.db, cursor_def, &link, ns, is_inner_attr)
.unwrap_or_else(|| panic!("Failed to resolve {link}"));
def.try_to_nav(sema.db).unwrap().into_iter().zip(iter::repeat(link))
})
@@ -78,7 +80,7 @@ fn check_doc_links(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
fn def_under_cursor(
sema: &Semantics<'_, RootDatabase>,
position: &FilePosition,
-) -> (Definition, Documentation) {
+) -> (Definition, Documentation, DocsRangeMap) {
let (docs, def) = sema
.parse_guess_edition(position.file_id)
.syntax()
@@ -89,31 +91,31 @@ fn def_under_cursor(
.find_map(|it| node_to_def(sema, &it))
.expect("no def found")
.unwrap();
- let docs = docs.expect("no docs found for cursor def");
- (def, docs)
+ let (docs, range) = docs.expect("no docs found for cursor def");
+ (def, docs, range)
}
fn node_to_def(
sema: &Semantics<'_, RootDatabase>,
node: &SyntaxNode,
-) -> Option<Option<(Option<Documentation>, Definition)>> {
+) -> Option<Option<(Option<(Documentation, DocsRangeMap)>, Definition)>> {
Some(match_ast! {
match node {
- ast::SourceFile(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::Module(def))),
- ast::Module(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::Module(def))),
- ast::Fn(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::Function(def))),
- ast::Struct(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::Adt(hir::Adt::Struct(def)))),
- ast::Union(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::Adt(hir::Adt::Union(def)))),
- ast::Enum(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::Adt(hir::Adt::Enum(def)))),
- ast::Variant(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::Variant(def))),
- ast::Trait(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::Trait(def))),
- ast::Static(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::Static(def))),
- ast::Const(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::Const(def))),
- ast::TypeAlias(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::TypeAlias(def))),
- ast::Impl(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::SelfType(def))),
- ast::RecordField(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::Field(def))),
- ast::TupleField(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::Field(def))),
- ast::Macro(it) => sema.to_def(&it).map(|def| (def.docs(sema.db), Definition::Macro(def))),
+ ast::SourceFile(it) => sema.to_def(&it).map(|def| (def.docs_with_rangemap(sema.db), Definition::Module(def))),
+ ast::Module(it) => sema.to_def(&it).map(|def| (def.docs_with_rangemap(sema.db), Definition::Module(def))),
+ ast::Fn(it) => sema.to_def(&it).map(|def| (def.docs_with_rangemap(sema.db), Definition::Function(def))),
+ ast::Struct(it) => sema.to_def(&it).map(|def| (def.docs_with_rangemap(sema.db), Definition::Adt(hir::Adt::Struct(def)))),
+ ast::Union(it) => sema.to_def(&it).map(|def| (def.docs_with_rangemap(sema.db), Definition::Adt(hir::Adt::Union(def)))),
+ ast::Enum(it) => sema.to_def(&it).map(|def| (def.docs_with_rangemap(sema.db), Definition::Adt(hir::Adt::Enum(def)))),
+ ast::Variant(it) => sema.to_def(&it).map(|def| (def.docs_with_rangemap(sema.db), Definition::Variant(def))),
+ ast::Trait(it) => sema.to_def(&it).map(|def| (def.docs_with_rangemap(sema.db), Definition::Trait(def))),
+ ast::Static(it) => sema.to_def(&it).map(|def| (def.docs_with_rangemap(sema.db), Definition::Static(def))),
+ ast::Const(it) => sema.to_def(&it).map(|def| (def.docs_with_rangemap(sema.db), Definition::Const(def))),
+ ast::TypeAlias(it) => sema.to_def(&it).map(|def| (def.docs_with_rangemap(sema.db), Definition::TypeAlias(def))),
+ ast::Impl(it) => sema.to_def(&it).map(|def| (def.docs_with_rangemap(sema.db), Definition::SelfType(def))),
+ ast::RecordField(it) => sema.to_def(&it).map(|def| (def.docs_with_rangemap(sema.db), Definition::Field(def))),
+ ast::TupleField(it) => sema.to_def(&it).map(|def| (def.docs_with_rangemap(sema.db), Definition::Field(def))),
+ ast::Macro(it) => sema.to_def(&it).map(|def| (def.docs_with_rangemap(sema.db), Definition::Macro(def))),
// ast::Use(it) => sema.to_def(&it).map(|def| (Box::new(it) as _, def.attrs(sema.db))),
_ => return None,
}
@@ -576,6 +578,40 @@ struct S$0(i32);
}
#[test]
+fn doc_links_module() {
+ check_doc_links(
+ r#"
+/// [`M`]
+/// [`M::f`]
+mod M$0 {
+ //^ M
+ #![doc = "inner_item[`S`]"]
+
+ pub fn f() {}
+ //^ M::f
+ pub struct S;
+ //^ S
+}
+"#,
+ );
+
+ check_doc_links(
+ r#"
+mod M$0 {
+ //^ super::M
+ //! [`super::M`]
+ //! [`super::M::f`]
+ //! [`super::M::S`]
+ pub fn f() {}
+ //^ super::M::f
+ pub struct S;
+ //^ super::M::S
+}
+"#,
+ );
+}
+
+#[test]
fn rewrite_html_root_url() {
check_rewrite(
r#"
@@ -691,6 +727,29 @@ fn rewrite_intra_doc_link_with_anchor() {
}
#[test]
+fn rewrite_module() {
+ check_rewrite(
+ r#"
+//- /main.rs crate:foo
+/// [Foo]
+pub mod $0Foo{
+};
+"#,
+ expect![[r#"[Foo](https://docs.rs/foo/*/foo/Foo/index.html)"#]],
+ );
+
+ check_rewrite(
+ r#"
+//- /main.rs crate:foo
+pub mod $0Foo{
+ //! [super::Foo]
+};
+"#,
+ expect![[r#"[super::Foo](https://docs.rs/foo/*/foo/Foo/index.html)"#]],
+ );
+}
+
+#[test]
fn rewrite_intra_doc_link_to_associated_item() {
check_rewrite(
r#"