Skip to content

Commit 80cbfe7

Browse files
robertoaloimeta-codesync[bot]
authored andcommitted
Enable documentation for types
Summary: Since OTP 27, [it's possible to use `-doc` attributes for user defined types](https://www.erlang.org/doc/system/documentation.html). This diff enables extraction of type documentation for both local and remote types, ensuring documentation is visible on hover. Since no test cases were covering documentation extraction, I also added a couple of them for functions. Reviewed By: alanz Differential Revision: D84680999 fbshipit-source-id: 120dbfab0e046e34363563c7139369cb36de202b
1 parent a893656 commit 80cbfe7

File tree

3 files changed

+104
-2
lines changed

3 files changed

+104
-2
lines changed

crates/ide/src/handlers/get_docs.rs

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,100 @@ pub(crate) fn get_doc_for_token(
2222
let docs = elp_ide_db::docs::Documentation::new(db, sema);
2323
Doc::from_reference(&docs, token)
2424
}
25+
26+
#[cfg(test)]
27+
mod tests {
28+
use crate::fixture;
29+
30+
#[track_caller]
31+
fn check(fixture: &str, expected: &str) {
32+
let (analysis, fixture) = fixture::with_fixture(fixture);
33+
let docs = analysis
34+
.get_docs_at_position(fixture.position())
35+
.unwrap()
36+
.unwrap();
37+
let doc = docs.doc.unwrap();
38+
assert_eq!(doc.markdown_text(), expected);
39+
}
40+
41+
#[test]
42+
fn local_type() {
43+
check(
44+
r#"
45+
-module(main).
46+
-export([main/0]).
47+
-doc """
48+
My integer
49+
""".
50+
-type my_integer() :: integer().
51+
52+
-spec main() -> my_in~teger().
53+
main() -> 42.
54+
"#,
55+
"\
56+
```erlang
57+
-type my_integer() :: integer().
58+
```
59+
60+
-----
61+
62+
My integer",
63+
);
64+
}
65+
66+
#[test]
67+
fn remote_type() {
68+
check(
69+
r#"
70+
//- /src/main.erl
71+
-module(main).
72+
-export([main/0]).
73+
-spec main() -> other:my_in~teger().
74+
main() -> 42.
75+
76+
//- /src/other.erl
77+
-module(other).
78+
-doc """
79+
My integer
80+
""".
81+
-export_type([my_integer/0]).
82+
-type my_integer() :: integer().
83+
"#,
84+
"\
85+
```erlang
86+
-type my_integer() :: integer().
87+
```
88+
89+
-----
90+
91+
My integer",
92+
);
93+
}
94+
95+
#[test]
96+
fn local_function() {
97+
check(
98+
r#"
99+
-module(main).
100+
-export([main/0]).
101+
102+
-doc """
103+
My function
104+
""".
105+
-spec main() -> ok.
106+
main() -> ok.
107+
108+
-spec caller() -> ok.
109+
caller() -> ma~in().
110+
"#,
111+
"\
112+
```erlang
113+
-spec main() -> ok.
114+
```
115+
116+
-----
117+
118+
My function",
119+
);
120+
}
121+
}

crates/ide/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ pub struct AnalysisHost {
170170
db: RootDatabase,
171171
}
172172

173+
#[derive(Debug)]
173174
pub struct DocResult {
174175
pub doc: Option<Doc>,
175176
pub token_kind: SyntaxKind,

crates/ide_db/src/docs.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,9 @@ impl ToDoc for InFile<&ast::Remote> {
137137
let name_arity = fun_def.name;
138138
docs.function_doc(file_id, name_arity)
139139
}
140-
CallDef::Type(_) | CallDef::FuzzyType(_) => None,
140+
CallDef::Type(type_def) | CallDef::FuzzyType(type_def) => {
141+
docs.type_doc(type_def.file.file_id, type_def.name().clone())
142+
}
141143
}
142144
} else {
143145
None
@@ -152,7 +154,9 @@ impl ToDoc for InFile<&ast::Call> {
152154
CallDef::Function(fun_def) | CallDef::FuzzyFunction(fun_def) => {
153155
docs.function_doc(fun_def.file.file_id, fun_def.name)
154156
}
155-
CallDef::Type(_) | CallDef::FuzzyType(_) => None,
157+
CallDef::Type(type_def) | CallDef::FuzzyType(type_def) => {
158+
docs.type_doc(type_def.file.file_id, type_def.name().clone())
159+
}
156160
}
157161
} else {
158162
None

0 commit comments

Comments
 (0)