Skip to content

Commit 7374730

Browse files
authored
refactor(nest): Better nesting implementation (#732)
* refactor(nest): Better nesting implementation This nesting implementation uses a proper recursive tree algorithm Fixes #554 BREAKING CHANGE: referencing inferred destructure params without renaming them, like $0.x, from JSDoc comments will no longer work. To reference them, instead add a param tag to name the destructuring param, and then refer to members of that name. Before: ```js /** * @param {number} $0.x a member of x */ function a({ x }) {} ``` After: ```js /** * @param {Object} options * @param {number} options.x a member of x */ function a({ x }) {} ``` * Address review comments * Reduce testing node requirement back down to 4 * Don't output empty properties, reduce diff noise * Rearrange and document params * Simplify param inference, update test fixtures. This is focused around Array destructuring: documenting destructured array elements with indices instead of names, because the names are purely internal details * Use temporary fork to get through blocker
1 parent 9eca36c commit 7374730

22 files changed

+1240
-568
lines changed

declarations/comment.js

+45-30
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
declare type DocumentationConfig = {
1+
type DocumentationConfig = {
22
polyglot?: boolean,
33
inferPrivate?: boolean,
44
noPackage?: boolean,
@@ -12,25 +12,25 @@ declare type DocumentationConfig = {
1212
parseExtension: Array<string>
1313
};
1414

15-
declare type InputsConfig = {
15+
type InputsConfig = {
1616
inputs: Array<SourceFile>,
1717
config: DocumentationConfig
1818
};
1919

20-
declare type CommentError = {
20+
type CommentError = {
2121
message: string,
2222
commentLineNumber?: number
2323
};
2424

25-
declare type DoctrineType = {
25+
type DoctrineType = {
2626
elements?: Array<DoctrineType>,
2727
expression?: DoctrineType,
2828
applications?: Array<DoctrineType>,
2929
type: string,
3030
name?: string
3131
};
3232

33-
declare type CommentLoc = {
33+
type CommentLoc = {
3434
start: {
3535
line: number
3636
},
@@ -39,12 +39,12 @@ declare type CommentLoc = {
3939
}
4040
};
4141

42-
declare type SourceFile = {
42+
type SourceFile = {
4343
source?: string,
4444
file: string
4545
};
4646

47-
declare type CommentContext = {
47+
type CommentContext = {
4848
sortKey: string,
4949
file: string,
5050
ast: Object,
@@ -53,12 +53,26 @@ declare type CommentContext = {
5353
github?: CommentContextGitHub
5454
};
5555

56-
declare type CommentContextGitHub = {
56+
type CommentContextGitHub = {
5757
path: string,
5858
url: string
5959
};
6060

61-
declare type CommentTag = {
61+
type CommentTagBase = {
62+
title: string
63+
};
64+
65+
type CommentTag = CommentTagBase & {
66+
name?: string,
67+
title: string,
68+
description?: Object,
69+
default?: any,
70+
lineNumber?: number,
71+
type?: DoctrineType,
72+
properties?: Array<CommentTag>
73+
};
74+
75+
type CommentTagNamed = CommentTag & {
6276
name?: string,
6377
title: string,
6478
description?: Object,
@@ -68,40 +82,41 @@ declare type CommentTag = {
6882
properties?: Array<CommentTag>
6983
};
7084

71-
declare type CommentMembers = {
85+
type CommentMembers = {
7286
static: Array<Comment>,
7387
instance: Array<Comment>,
7488
events: Array<Comment>,
7589
global: Array<Comment>,
7690
inner: Array<Comment>
7791
};
7892

79-
declare type CommentExample = {
93+
type CommentExample = {
8094
caption?: string,
8195
description?: Object
8296
};
8397

84-
declare type Remark = {
98+
type Remark = {
8599
type: string,
86100
children: Array<Object>
87101
};
88102

89-
declare type Access = 'private' | 'public' | 'protected';
90-
declare type Scope = 'instance' | 'static' | 'inner' | 'global';
91-
declare type Kind = 'class' |
92-
'constant' |
93-
'event' |
94-
'external' |
95-
'file' |
96-
'function' |
97-
'member' |
98-
'mixin' |
99-
'module' |
100-
'namespace' |
101-
'typedef' |
102-
'interface';
103-
104-
declare type Comment = {
103+
type Access = 'private' | 'public' | 'protected';
104+
type Scope = 'instance' | 'static' | 'inner' | 'global';
105+
type Kind =
106+
| 'class'
107+
| 'constant'
108+
| 'event'
109+
| 'external'
110+
| 'file'
111+
| 'function'
112+
| 'member'
113+
| 'mixin'
114+
| 'module'
115+
| 'namespace'
116+
| 'typedef'
117+
| 'interface';
118+
119+
type Comment = {
105120
errors: Array<CommentError>,
106121
tags: Array<CommentTag>,
107122

@@ -148,8 +163,8 @@ declare type Comment = {
148163
}>
149164
};
150165

151-
declare type ReducedComment = {
166+
type ReducedComment = {
152167
name: string,
153168
kind: ?Kind,
154169
scope?: ?Scope
155-
}
170+
};

default_theme/section._

+2-2
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
= <code><%- param.default %></code><% } %>)</code>
5353
<%= md(param.description, true) %>
5454
</div>
55-
<% if (param.properties) { %>
55+
<% if (param.properties && param.properties.length) { %>
5656
<table class='mt1 mb2 fixed-table h5 col-12'>
5757
<colgroup>
5858
<col width='30%' />
@@ -93,7 +93,7 @@
9393
<% } %><% if (property.description) {
9494
%>: <%= md(property.description, true) %><%
9595
} %>
96-
<% if (property.properties) { %>
96+
<% if (property.properties && property.properties.length) { %>
9797
<ul>
9898
<% property.properties.forEach(function(property) { %>
9999
<li><code><%- property.name %></code> <%= formatType(property.type) %>

index.js

+21-22
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,10 @@ function pipeline() {
4545
};
4646
}
4747

48-
49-
50-
function configure(indexes, args)/*: Promise<InputsConfig> */ {
48+
function configure(indexes, args) /*: Promise<InputsConfig> */ {
5149
let mergedConfig = mergeConfig(args);
5250

5351
return mergedConfig.then(config => {
54-
5552
let expandedInputs = expandInputs(indexes, config);
5653

5754
return expandedInputs.then(inputs => {
@@ -71,8 +68,10 @@ function configure(indexes, args)/*: Promise<InputsConfig> */ {
7168
* @param {Object} config options
7269
* @returns {Promise<Array<string>>} promise with results
7370
*/
74-
function expandInputs(indexes/*: string|Array<string> */,
75-
config /*: DocumentationConfig */) {
71+
function expandInputs(
72+
indexes /*: string|Array<string> */,
73+
config /*: DocumentationConfig */
74+
) {
7675
// Ensure that indexes is an array of strings
7776
indexes = [].concat(indexes);
7877

@@ -91,40 +90,42 @@ function buildInternal(inputsAndConfig) {
9190
config.access = ['public', 'undefined', 'protected'];
9291
}
9392

94-
var parseFn = (config.polyglot) ? polyglot : parseJavaScript;
93+
var parseFn = config.polyglot ? polyglot : parseJavaScript;
9594

9695
var buildPipeline = pipeline(
9796
inferName,
9897
inferAccess(config.inferPrivate),
9998
inferAugments,
10099
inferKind,
100+
nest,
101101
inferParams,
102102
inferProperties,
103103
inferReturn,
104104
inferMembership(),
105105
inferType,
106-
nest,
107106
config.github && github,
108-
garbageCollect);
107+
garbageCollect
108+
);
109109

110-
let extractedComments = _.flatMap(inputs, function (sourceFile) {
110+
let extractedComments = _.flatMap(inputs, function(sourceFile) {
111111
if (!sourceFile.source) {
112112
sourceFile.source = fs.readFileSync(sourceFile.file, 'utf8');
113113
}
114114

115115
return parseFn(sourceFile, config).map(buildPipeline);
116116
}).filter(Boolean);
117117

118-
return filterAccess(config.access,
119-
hierarchy(
120-
sort(extractedComments, config)));
118+
return filterAccess(
119+
config.access,
120+
hierarchy(sort(extractedComments, config))
121+
);
121122
}
122123

123124
function lintInternal(inputsAndConfig) {
124125
let inputs = inputsAndConfig.inputs;
125126
let config = inputsAndConfig.config;
126127

127-
let parseFn = (config.polyglot) ? polyglot : parseJavaScript;
128+
let parseFn = config.polyglot ? polyglot : parseJavaScript;
128129

129130
let lintPipeline = pipeline(
130131
lintComments,
@@ -137,7 +138,8 @@ function lintInternal(inputsAndConfig) {
137138
inferReturn,
138139
inferMembership(),
139140
inferType,
140-
nest);
141+
nest
142+
);
141143

142144
let extractedComments = _.flatMap(inputs, sourceFile => {
143145
if (!sourceFile.source) {
@@ -183,8 +185,7 @@ function lintInternal(inputsAndConfig) {
183185
* }
184186
* });
185187
*/
186-
let lint = (indexes, args) => configure(indexes, args)
187-
.then(lintInternal);
188+
let lint = (indexes, args) => configure(indexes, args).then(lintInternal);
188189

189190
/**
190191
* Generate JavaScript documentation as a list of parsed JSDoc
@@ -227,8 +228,7 @@ let lint = (indexes, args) => configure(indexes, args)
227228
* // any other kind of code data.
228229
* });
229230
*/
230-
let build = (indexes, args) => configure(indexes, args)
231-
.then(buildInternal);
231+
let build = (indexes, args) => configure(indexes, args).then(buildInternal);
232232

233233
/**
234234
* Documentation's formats are modular methods that take comments
@@ -240,9 +240,8 @@ let build = (indexes, args) => configure(indexes, args)
240240
var formats = {
241241
html: require('./lib/output/html'),
242242
md: require('./lib/output/markdown'),
243-
remark: (comments/*: Array<Comment> */, config/*: DocumentationConfig */) =>
244-
markdownAST(comments, config)
245-
.then(res => JSON.stringify(res, null, 2)),
243+
remark: (comments /*: Array<Comment> */, config /*: DocumentationConfig */) =>
244+
markdownAST(comments, config).then(res => JSON.stringify(res, null, 2)),
246245
json: require('./lib/output/json')
247246
};
248247

0 commit comments

Comments
 (0)