Skip to content

Commit ebcbcab

Browse files
authored
feat: support leading @module JSDoc blocks (#167)
Closes: #42
1 parent bf6983e commit ebcbcab

File tree

9 files changed

+200
-103
lines changed

9 files changed

+200
-103
lines changed

lib/deno_doc.generated.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ const imports = {
352352
__wbindgen_throw: function (arg0, arg1) {
353353
throw new Error(getStringFromWasm0(arg0, arg1));
354354
},
355-
__wbindgen_closure_wrapper808: function (arg0, arg1, arg2) {
355+
__wbindgen_closure_wrapper819: function (arg0, arg1, arg2) {
356356
var ret = makeMutClosure(arg0, arg1, 154, __wbg_adapter_16);
357357
return addHeapObject(ret);
358358
},

lib/deno_doc_bg.wasm

1.73 KB
Binary file not shown.

lib/types.d.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright 2020-2021 the Deno authors. All rights reserved. MIT license.
22

33
export type DocNode =
4+
| DocNodeModuleDoc
45
| DocNodeFunction
56
| DocNodeVariable
67
| DocNodeEnum
@@ -18,6 +19,7 @@ interface DocNodeBase {
1819
}
1920

2021
export type DocNodeKind =
22+
| "moduleDoc"
2123
| "function"
2224
| "variable"
2325
| "enum"
@@ -27,6 +29,11 @@ export type DocNodeKind =
2729
| "interface"
2830
| "import";
2931

32+
export interface DocNodeModuleDoc extends DocNodeBase {
33+
kind: "moduleDoc";
34+
jsDoc: JsDoc;
35+
}
36+
3037
export interface DocNodeFunction extends DocNodeBase {
3138
kind: "function";
3239
functionDef: FunctionDef;
@@ -206,6 +213,7 @@ export type JsDocTagKind =
206213
| "deprecated"
207214
| "enum"
208215
| "extends"
216+
| "module"
209217
| "param"
210218
| "public"
211219
| "private"
@@ -234,7 +242,13 @@ export interface JsDocTagBase {
234242
}
235243

236244
export interface JsDocTagOnly extends JsDocTagBase {
237-
kind: "constructor" | "public" | "private" | "protected" | "readonly";
245+
kind:
246+
| "constructor"
247+
| "module"
248+
| "public"
249+
| "private"
250+
| "protected"
251+
| "readonly";
238252
}
239253

240254
export interface JsDocTagDoc extends JsDocTagBase {

src/js_doc.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ lazy_static! {
88
static ref JS_DOC_TAG_MAYBE_DOC_RE: Regex = Regex::new(r#"^\s*@(deprecated)(?:\s+(.+))?"#).unwrap();
99
static ref JS_DOC_TAG_NAMED_RE: Regex = Regex::new(r#"(?s)^\s*@(callback|template)\s+([a-zA-Z_$]\S*)(?:\s+(.+))?"#).unwrap();
1010
static ref JS_DOC_TAG_NAMED_TYPED_RE: Regex = Regex::new(r#"(?s)^\s*@(prop(?:erty)?|typedef)\s+\{([^}]+)\}\s+([a-zA-Z_$]\S*)(?:\s+(.+))?"#).unwrap();
11-
static ref JS_DOC_TAG_ONLY_RE: Regex = Regex::new(r#"^\s*@(constructor|class|public|private|protected|readonly)"#).unwrap();
11+
static ref JS_DOC_TAG_ONLY_RE: Regex = Regex::new(r#"^\s*@(constructor|class|module|public|private|protected|readonly)"#).unwrap();
1212
static ref JS_DOC_TAG_PARAM_RE: Regex = Regex::new(
1313
r#"(?s)^\s*@(?:param|arg(?:ument)?)(?:\s+\{([^}]+)\})?\s+([a-zA-Z_$]\S*)(?:\s+(.+))?"#
1414
)
@@ -66,7 +66,7 @@ impl From<String> for JsDoc {
6666
}
6767
}
6868

69-
#[derive(Debug, Clone, Deserialize, Serialize)]
69+
#[derive(Debug, Clone, Deserialize, Serialize, Eq, PartialEq)]
7070
#[serde(tag = "kind", rename_all = "lowercase")]
7171
pub enum JsDocTag {
7272
/// `@callback Predicate comment`
@@ -96,6 +96,8 @@ pub enum JsDocTag {
9696
#[serde(skip_serializing_if = "Option::is_none")]
9797
doc: Option<String>,
9898
},
99+
/// `@module`
100+
Module,
99101
/// `@param {type} name comment` or `@arg {type} name comment` or
100102
/// `@argument {type} name comment`
101103
Param {
@@ -168,6 +170,7 @@ impl From<String> for JsDocTag {
168170
let kind = caps.get(1).unwrap().as_str();
169171
match kind {
170172
"constructor" | "class" => Self::Constructor,
173+
"module" => Self::Module,
171174
"public" => Self::Public,
172175
"private" => Self::Private,
173176
"protected" => Self::Protected,

src/node.rs

Lines changed: 41 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use crate::js_doc::JsDoc;
88
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
99
#[serde(rename_all = "camelCase")]
1010
pub enum DocNodeKind {
11+
ModuleDoc,
1112
Function,
1213
Variable,
1314
Class,
@@ -93,7 +94,39 @@ pub struct DocNode {
9394
pub import_def: Option<ImportDef>,
9495
}
9596

97+
impl Default for DocNode {
98+
fn default() -> Self {
99+
Self {
100+
kind: DocNodeKind::ModuleDoc,
101+
name: "".to_string(),
102+
location: Location {
103+
filename: "".to_string(),
104+
line: 0,
105+
col: 0,
106+
},
107+
js_doc: JsDoc::default(),
108+
function_def: None,
109+
variable_def: None,
110+
enum_def: None,
111+
class_def: None,
112+
type_alias_def: None,
113+
namespace_def: None,
114+
interface_def: None,
115+
import_def: None,
116+
}
117+
}
118+
}
119+
96120
impl DocNode {
121+
pub fn module_doc(location: Location, js_doc: JsDoc) -> Self {
122+
Self {
123+
kind: DocNodeKind::ModuleDoc,
124+
name: "".to_string(),
125+
location,
126+
js_doc,
127+
..Default::default()
128+
}
129+
}
97130
pub fn function(
98131
name: String,
99132
location: Location,
@@ -106,13 +139,7 @@ impl DocNode {
106139
location,
107140
js_doc,
108141
function_def: Some(fn_def),
109-
variable_def: None,
110-
enum_def: None,
111-
class_def: None,
112-
type_alias_def: None,
113-
namespace_def: None,
114-
interface_def: None,
115-
import_def: None,
142+
..Default::default()
116143
}
117144
}
118145

@@ -127,14 +154,8 @@ impl DocNode {
127154
name,
128155
location,
129156
js_doc,
130-
function_def: None,
131157
variable_def: Some(var_def),
132-
enum_def: None,
133-
class_def: None,
134-
type_alias_def: None,
135-
namespace_def: None,
136-
interface_def: None,
137-
import_def: None,
158+
..Default::default()
138159
}
139160
}
140161

@@ -149,14 +170,8 @@ impl DocNode {
149170
name,
150171
location,
151172
js_doc,
152-
function_def: None,
153-
variable_def: None,
154173
enum_def: Some(enum_def),
155-
class_def: None,
156-
type_alias_def: None,
157-
namespace_def: None,
158-
interface_def: None,
159-
import_def: None,
174+
..Default::default()
160175
}
161176
}
162177

@@ -171,14 +186,8 @@ impl DocNode {
171186
name,
172187
location,
173188
js_doc,
174-
function_def: None,
175-
variable_def: None,
176-
enum_def: None,
177189
class_def: Some(class_def),
178-
type_alias_def: None,
179-
namespace_def: None,
180-
interface_def: None,
181-
import_def: None,
190+
..Default::default()
182191
}
183192
}
184193

@@ -193,14 +202,8 @@ impl DocNode {
193202
name,
194203
location,
195204
js_doc,
196-
function_def: None,
197-
variable_def: None,
198-
enum_def: None,
199-
class_def: None,
200205
type_alias_def: Some(type_alias_def),
201-
namespace_def: None,
202-
interface_def: None,
203-
import_def: None,
206+
..Default::default()
204207
}
205208
}
206209

@@ -215,14 +218,8 @@ impl DocNode {
215218
name,
216219
location,
217220
js_doc,
218-
function_def: None,
219-
variable_def: None,
220-
enum_def: None,
221-
class_def: None,
222-
type_alias_def: None,
223221
namespace_def: Some(namespace_def),
224-
interface_def: None,
225-
import_def: None,
222+
..Default::default()
226223
}
227224
}
228225

@@ -237,14 +234,8 @@ impl DocNode {
237234
name,
238235
location,
239236
js_doc,
240-
function_def: None,
241-
variable_def: None,
242-
enum_def: None,
243-
class_def: None,
244-
type_alias_def: None,
245-
namespace_def: None,
246237
interface_def: Some(interface_def),
247-
import_def: None,
238+
..Default::default()
248239
}
249240
}
250241

@@ -259,14 +250,8 @@ impl DocNode {
259250
name,
260251
location,
261252
js_doc,
262-
function_def: None,
263-
variable_def: None,
264-
enum_def: None,
265-
class_def: None,
266-
type_alias_def: None,
267-
namespace_def: None,
268-
interface_def: None,
269253
import_def: Some(import_def),
254+
..Default::default()
270255
}
271256
}
272257
}

src/parser.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use crate::node::DocNode;
77
use crate::node::ModuleDoc;
88
use crate::swc_util::get_location;
99
use crate::swc_util::js_doc_for_span;
10+
use crate::swc_util::module_js_doc_for_source;
1011
use crate::ImportDef;
1112
use crate::Location;
1213
use crate::ReexportKind;
@@ -668,6 +669,13 @@ impl<'a> DocParser<'a> {
668669

669670
let mut is_ambient = true;
670671

672+
// check to see if there is a module level JSDoc for the source file
673+
if let Some((js_doc, span)) = module_js_doc_for_source(parsed_source) {
674+
let doc_node =
675+
DocNode::module_doc(get_location(parsed_source, span.lo), js_doc);
676+
doc_entries.push(doc_node);
677+
}
678+
671679
for node in module_body.iter() {
672680
match node {
673681
ModuleItem::Stmt(stmt) => {

src/printer.rs

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -96,14 +96,15 @@ impl<'a> DocPrinter<'a> {
9696

9797
fn kind_order(&self, kind: &DocNodeKind) -> i64 {
9898
match kind {
99-
DocNodeKind::Function => 0,
100-
DocNodeKind::Variable => 1,
101-
DocNodeKind::Class => 2,
102-
DocNodeKind::Enum => 3,
103-
DocNodeKind::Interface => 4,
104-
DocNodeKind::TypeAlias => 5,
105-
DocNodeKind::Namespace => 6,
106-
DocNodeKind::Import => 7,
99+
DocNodeKind::ModuleDoc => 0,
100+
DocNodeKind::Function => 1,
101+
DocNodeKind::Variable => 2,
102+
DocNodeKind::Class => 3,
103+
DocNodeKind::Enum => 4,
104+
DocNodeKind::Interface => 5,
105+
DocNodeKind::TypeAlias => 6,
106+
DocNodeKind::Namespace => 7,
107+
DocNodeKind::Import => 8,
107108
}
108109
}
109110

@@ -114,6 +115,7 @@ impl<'a> DocPrinter<'a> {
114115
indent: i64,
115116
) -> FmtResult {
116117
match node.kind {
118+
DocNodeKind::ModuleDoc => self.format_module_doc(w, node, indent),
117119
DocNodeKind::Function => self.format_function_signature(w, node, indent),
118120
DocNodeKind::Variable => self.format_variable_signature(w, node, indent),
119121
DocNodeKind::Class => self.format_class_signature(w, node, indent),
@@ -360,6 +362,17 @@ impl<'a> DocPrinter<'a> {
360362
writeln!(w)
361363
}
362364

365+
fn format_module_doc(
366+
&self,
367+
_w: &mut Formatter<'_>,
368+
_node: &DocNode,
369+
_indent: i64,
370+
) -> FmtResult {
371+
// currently we do not print out JSDoc in the printer, so there is nothing
372+
// to print.
373+
Ok(())
374+
}
375+
363376
fn format_type_alias_signature(
364377
&self,
365378
w: &mut Formatter<'_>,

0 commit comments

Comments
 (0)