Skip to content

Commit f0cd386

Browse files
GearsDatapackslpil
authored andcommitted
Warn for detatched doc comments
1 parent c785817 commit f0cd386

File tree

5 files changed

+107
-0
lines changed

5 files changed

+107
-0
lines changed

CHANGELOG.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,35 @@
5151
containing scientific notation or trailing zeros (i.e. `100` and `1e2`).
5252
([ptdewey](https://github.com/ptdewey))
5353

54+
- The compiler now emits a warning when a doc comment is not attached to a
55+
definition due to a regular comment in between. For example, in the following
56+
code:
57+
58+
```gleam
59+
/// This documentation is not attached
60+
// This is not a doc comment
61+
/// This is actual documentation
62+
pub fn wibble() {
63+
todo
64+
}
65+
```
66+
67+
Will now produce the following warning:
68+
69+
```txt
70+
warning: Detached doc comment
71+
┌─ src/main.gleam:1:4
72+
73+
1 │ /// This documentation is not attached
74+
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This is not attached to a definition
75+
76+
This doc comment is followed by a regular comment so it is not attached to
77+
any definition.
78+
Hint: Move the comment above the doc comment
79+
```
80+
81+
([Surya Rose](https://github.com/GearsDatapacks))
82+
5483
### Build tool
5584

5685
- The help text displayed by `gleam dev --help`, `gleam test --help`, and

compiler-core/src/parse.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,14 @@ pub fn parse_module(
173173
});
174174
}
175175

176+
for detached in parser.detached_doc_comments {
177+
warnings.emit(Warning::DetachedDocComment {
178+
path: path.clone(),
179+
src: src.clone(),
180+
location: detached,
181+
});
182+
}
183+
176184
Ok(parsed)
177185
}
178186

@@ -218,6 +226,7 @@ pub struct Parser<T: Iterator<Item = LexResult>> {
218226
tok1: Option<Spanned>,
219227
extra: ModuleExtra,
220228
doc_comments: VecDeque<(u32, EcoString)>,
229+
detached_doc_comments: Vec<SrcSpan>,
221230
}
222231
impl<T> Parser<T>
223232
where
@@ -232,6 +241,7 @@ where
232241
tok1: None,
233242
extra: ModuleExtra::new(),
234243
doc_comments: VecDeque::new(),
244+
detached_doc_comments: Vec::new(),
235245
};
236246
parser.advance();
237247
parser.advance();
@@ -4061,9 +4071,12 @@ functions are declared separately from types.";
40614071
if *start >= until {
40624072
break;
40634073
}
4074+
40644075
if self.extra.has_comment_between(*start, until) {
40654076
// We ignore doc comments that come before a regular comment.
4077+
let location = SrcSpan::new(*start, start + line.len() as u32);
40664078
_ = self.doc_comments.pop_front();
4079+
self.detached_doc_comments.push(location);
40674080
continue;
40684081
}
40694082

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
---
2+
source: compiler-core/src/type_/tests/warnings.rs
3+
expression: "\n/// This comment is detached\n//\n\n/// This is actual documentation\npub const pi = 3.14\n"
4+
---
5+
----- SOURCE CODE
6+
7+
/// This comment is detached
8+
//
9+
10+
/// This is actual documentation
11+
pub const pi = 3.14
12+
13+
14+
----- WARNING
15+
warning: Detached doc comment
16+
┌─ test/path:2:4
17+
18+
2/// This comment is detached
19+
^^^^^^^^^^^^^^^^^^^^^^^^^ This is not attached to a definition
20+
21+
This doc comment is followed by a regular comment so it is not attached to
22+
any definition.
23+
Hint: Move the comment above the doc comment

compiler-core/src/type_/tests/warnings.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4612,3 +4612,16 @@ pub type Wobble
46124612
"#,
46134613
);
46144614
}
4615+
4616+
#[test]
4617+
fn detached_doc_comment() {
4618+
assert_warning!(
4619+
"
4620+
/// This comment is detached
4621+
//
4622+
4623+
/// This is actual documentation
4624+
pub const pi = 3.14
4625+
"
4626+
);
4627+
}

compiler-core/src/warning.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,12 @@ pub enum Warning {
174174
path: Utf8PathBuf,
175175
name: EcoString,
176176
},
177+
178+
DetachedDocComment {
179+
path: Utf8PathBuf,
180+
src: EcoString,
181+
location: SrcSpan,
182+
},
177183
}
178184

179185
#[derive(Debug, Clone, Eq, PartialEq, Copy)]
@@ -424,6 +430,29 @@ To have a clause without a guard, remove this.",
424430
}
425431
}
426432

433+
Warning::DetachedDocComment {
434+
path,
435+
src,
436+
location,
437+
} => Diagnostic {
438+
title: "Detached doc comment".into(),
439+
text: wrap(
440+
"This doc comment is followed by a regular \
441+
comment so it is not attached to any definition.",
442+
),
443+
level: diagnostic::Level::Warning,
444+
location: Some(Location {
445+
path: path.to_path_buf(),
446+
src: src.clone(),
447+
label: diagnostic::Label {
448+
text: Some("This is not attached to a definition".into()),
449+
span: *location,
450+
},
451+
extra_labels: Vec::new(),
452+
}),
453+
hint: Some("Move the comment above the doc comment".into()),
454+
},
455+
427456
Warning::Type { path, warning, src } => match warning {
428457
type_::Warning::Todo {
429458
kind,

0 commit comments

Comments
 (0)