6
6
*/
7
7
8
8
var doop = require ( 'jsdoc/util/doop' ) ;
9
+ var jsdoc = {
10
+ doclet : require ( 'jsdoc/doclet' )
11
+ } ;
9
12
var name = require ( 'jsdoc/name' ) ;
10
13
11
14
var hasOwnProp = Object . prototype . hasOwnProperty ;
@@ -75,20 +78,24 @@ function sort(dependencies) {
75
78
}
76
79
77
80
function getMembers ( longname , docs , scopes ) {
78
- var candidate ;
81
+ var memberof = docs . index . memberof [ longname ] || [ ] ;
79
82
var members = [ ] ;
80
83
81
- for ( var i = 0 , l = docs . length ; i < l ; i ++ ) {
82
- candidate = docs [ i ] ;
83
-
84
- if ( candidate . memberof === longname && scopes . indexOf ( candidate . scope ) !== - 1 ) {
84
+ memberof . forEach ( function ( candidate ) {
85
+ if ( scopes . indexOf ( candidate . scope ) !== - 1 ) {
85
86
members . push ( candidate ) ;
86
87
}
87
- }
88
+ } ) ;
88
89
89
90
return members ;
90
91
}
91
92
93
+ function getDocumentedLongname ( longname , docs ) {
94
+ var doclets = docs . index . documented [ longname ] || [ ] ;
95
+
96
+ return doclets [ doclets . length - 1 ] ;
97
+ }
98
+
92
99
function addDocletProperty ( doclets , propName , value ) {
93
100
for ( var i = 0 , l = doclets . length ; i < l ; i ++ ) {
94
101
doclets [ i ] [ propName ] = value ;
@@ -162,6 +169,25 @@ function updateDocumentedDoclets(doclet, documented) {
162
169
documented [ doclet . longname ] . push ( doclet ) ;
163
170
}
164
171
172
+ /**
173
+ * Update the index of doclets with a `memberof` value.
174
+ *
175
+ * @private
176
+ * @param {module:jsdoc/doclet.Doclet } doclet - The doclet to be added to the index.
177
+ * @param {Object.<string, Array.<module:jsdoc/doclet.Doclet>> } memberof - The index of doclets
178
+ * with a `memberof` value.
179
+ * @return {void }
180
+ */
181
+ function updateMemberofDoclets ( doclet , memberof ) {
182
+ if ( doclet . memberof ) {
183
+ if ( ! hasOwnProp . call ( memberof , doclet . memberof ) ) {
184
+ memberof [ doclet . memberof ] = [ ] ;
185
+ }
186
+
187
+ memberof [ doclet . memberof ] . push ( doclet ) ;
188
+ }
189
+ }
190
+
165
191
function explicitlyInherits ( doclets ) {
166
192
var doclet ;
167
193
var inherits = false ;
@@ -177,13 +203,24 @@ function explicitlyInherits(doclets) {
177
203
return inherits ;
178
204
}
179
205
206
+ function changeMemberof ( longname , newMemberof ) {
207
+ var atoms = name . shorten ( longname ) ;
208
+
209
+ atoms . memberof = newMemberof ;
210
+
211
+ return name . combine ( atoms ) ;
212
+ }
213
+
180
214
// TODO: try to reduce overlap with similar methods
181
- function getInheritedAdditions ( doclets , docs , documented ) {
215
+ function getInheritedAdditions ( doclets , docs , index ) {
182
216
var additionIndexes ;
183
217
var additions = [ ] ;
218
+ var childDoclet ;
219
+ var childLongname ;
184
220
var doc ;
221
+ var parentDoclet ;
222
+ var parentMembers ;
185
223
var parents ;
186
- var members ;
187
224
var member ;
188
225
var parts ;
189
226
@@ -199,54 +236,64 @@ function getInheritedAdditions(doclets, docs, documented) {
199
236
additionIndexes = { } ;
200
237
201
238
for ( var j = 0 , jj = parents . length ; j < jj ; j ++ ) {
202
- members = getMembers ( parents [ j ] , docs , [ 'instance' ] ) ;
239
+ parentMembers = getMembers ( parents [ j ] , docs , [ 'instance' ] ) ;
240
+
241
+ for ( var k = 0 , kk = parentMembers . length ; k < kk ; k ++ ) {
242
+ parentDoclet = parentMembers [ k ] ;
203
243
204
- for ( var k = 0 , kk = members . length ; k < kk ; k ++ ) {
205
244
// We only care about symbols that are documented.
206
- if ( members [ k ] . undocumented ) {
245
+ if ( parentDoclet . undocumented ) {
207
246
continue ;
208
247
}
209
248
210
- member = doop ( members [ k ] ) ;
249
+ childLongname = changeMemberof ( parentDoclet . longname , doc . longname ) ;
250
+ childDoclet = getDocumentedLongname ( childLongname , docs ) || { } ;
251
+
252
+ // We don't want to fold in properties from the child doclet if it had an
253
+ // `@inheritdoc` tag.
254
+ if ( hasOwnProp . call ( childDoclet , 'inheritdoc' ) ) {
255
+ childDoclet = { } ;
256
+ }
257
+
258
+ member = jsdoc . doclet . combine ( childDoclet , parentDoclet ) ;
211
259
212
260
if ( ! member . inherited ) {
213
261
member . inherits = member . longname ;
214
262
}
215
263
member . inherited = true ;
216
264
217
- // TODO: this will fail on longnames like: MyClass#"quoted#Longname"
218
- // and nested instance members like: MyClass#MyOtherClass#myMethod;
219
- // switch to updateLongname()!
220
265
member . memberof = doc . longname ;
221
- parts = member . longname . split ( '#' ) ;
222
- parts [ 0 ] = doc . longname ;
223
- member . longname = parts . join ( '#' ) ;
266
+ parts = name . shorten ( member . longname ) ;
267
+ parts . memberof = doc . longname ;
268
+ member . longname = name . combine ( parts ) ;
224
269
225
270
// Indicate what the descendant is overriding. (We only care about the closest
226
271
// ancestor. For classes A > B > C, if B#a overrides A#a, and C#a inherits B#a,
227
272
// we don't want the doclet for C#a to say that it overrides A#a.)
228
273
if ( hasOwnProp . call ( docs . index . longname , member . longname ) ) {
229
- member . overrides = members [ k ] . longname ;
274
+ member . overrides = parentDoclet . longname ;
230
275
}
231
276
else {
232
277
delete member . overrides ;
233
278
}
234
279
235
280
// Add the ancestor's docs unless the descendant overrides the ancestor AND
236
281
// documents the override.
237
- if ( ! hasOwnProp . call ( documented , member . longname ) ) {
282
+ if ( ! hasOwnProp . call ( index . documented , member . longname ) ) {
238
283
updateAddedDoclets ( member , additions , additionIndexes ) ;
239
- updateDocumentedDoclets ( member , documented ) ;
284
+ updateDocumentedDoclets ( member , index . documented ) ;
285
+ updateMemberofDoclets ( member , index . memberof ) ;
240
286
}
241
287
// If the descendant used an @inheritdoc or @override tag, add the ancestor's
242
288
// docs, and ignore the existing doclets.
243
- else if ( explicitlyInherits ( documented [ member . longname ] ) ) {
289
+ else if ( explicitlyInherits ( index . documented [ member . longname ] ) ) {
244
290
// Ignore any existing doclets. (This is safe because we only get here if
245
291
// `member.longname` is an own property of `documented`.)
246
- addDocletProperty ( documented [ member . longname ] , 'ignore' , true ) ;
292
+ addDocletProperty ( index . documented [ member . longname ] , 'ignore' , true ) ;
247
293
248
294
updateAddedDoclets ( member , additions , additionIndexes ) ;
249
- updateDocumentedDoclets ( member , documented ) ;
295
+ updateDocumentedDoclets ( member , index . documented ) ;
296
+ updateMemberofDoclets ( member , index . memberof ) ;
250
297
251
298
// Remove property that's no longer accurate.
252
299
if ( member . virtual ) {
@@ -263,8 +310,8 @@ function getInheritedAdditions(doclets, docs, documented) {
263
310
// If the descendant overrides the ancestor and documents the override,
264
311
// update the doclets to indicate what the descendant is overriding.
265
312
else {
266
- addDocletProperty ( documented [ member . longname ] , 'overrides' ,
267
- members [ k ] . longname ) ;
313
+ addDocletProperty ( index . documented [ member . longname ] , 'overrides' ,
314
+ parentDoclet . longname ) ;
268
315
}
269
316
}
270
317
}
@@ -304,9 +351,10 @@ function updateMixes(mixedDoclet, mixedLongname) {
304
351
}
305
352
306
353
// TODO: try to reduce overlap with similar methods
307
- function getMixedInAdditions ( mixinDoclets , allDoclets , commentedDoclets ) {
354
+ function getMixedInAdditions ( mixinDoclets , allDoclets , index ) {
308
355
var additionIndexes ;
309
356
var additions = [ ] ;
357
+ var commentedDoclets = index . documented ;
310
358
var doclet ;
311
359
var mixedDoclet ;
312
360
var mixedDoclets ;
@@ -346,6 +394,7 @@ function getMixedInAdditions(mixinDoclets, allDoclets, commentedDoclets) {
346
394
347
395
updateAddedDoclets ( mixedDoclet , additions , additionIndexes ) ;
348
396
updateDocumentedDoclets ( mixedDoclet , commentedDoclets ) ;
397
+ updateMemberofDoclets ( mixedDoclet , index . memberof ) ;
349
398
}
350
399
}
351
400
}
@@ -371,14 +420,18 @@ function updateImplements(implDoclets, implementedLongname) {
371
420
}
372
421
373
422
// TODO: try to reduce overlap with similar methods
374
- function getImplementedAdditions ( implDoclets , allDoclets , commentedDoclets ) {
423
+ function getImplementedAdditions ( implDoclets , allDoclets , index ) {
375
424
var additionIndexes ;
376
425
var additions = [ ] ;
426
+ var childDoclet ;
427
+ var childLongname ;
428
+ var commentedDoclets = index . documented ;
377
429
var doclet ;
378
430
var implementations ;
379
431
var implExists ;
380
432
var implementationDoclet ;
381
433
var interfaceDoclets ;
434
+ var parentDoclet ;
382
435
383
436
// interfaceDoclets will be undefined if the implemented symbol isn't documented
384
437
implDoclets = implDoclets || [ ] ;
@@ -395,15 +448,26 @@ function getImplementedAdditions(implDoclets, allDoclets, commentedDoclets) {
395
448
interfaceDoclets = getMembers ( implementations [ j ] , allDoclets , [ 'instance' ] ) ;
396
449
397
450
for ( var k = 0 , kk = interfaceDoclets . length ; k < kk ; k ++ ) {
451
+ parentDoclet = interfaceDoclets [ k ] ;
452
+
398
453
// We only care about symbols that are documented.
399
- if ( interfaceDoclets [ k ] . undocumented ) {
454
+ if ( parentDoclet . undocumented ) {
400
455
continue ;
401
456
}
402
457
403
- implementationDoclet = doop ( interfaceDoclets [ k ] ) ;
458
+ childLongname = changeMemberof ( parentDoclet . longname , doclet . longname ) ;
459
+ childDoclet = getDocumentedLongname ( childLongname , allDoclets ) || { } ;
460
+
461
+ // We don't want to fold in properties from the child doclet if it had an
462
+ // `@inheritdoc` tag.
463
+ if ( hasOwnProp . call ( childDoclet , 'inheritdoc' ) ) {
464
+ childDoclet = { } ;
465
+ }
466
+
467
+ implementationDoclet = jsdoc . doclet . combine ( childDoclet , parentDoclet ) ;
404
468
405
469
reparentDoclet ( doclet , implementationDoclet ) ;
406
- updateImplements ( implementationDoclet , interfaceDoclets [ k ] . longname ) ;
470
+ updateImplements ( implementationDoclet , parentDoclet . longname ) ;
407
471
408
472
// If there's no implementation, move along.
409
473
implExists = hasOwnProp . call ( allDoclets . index . longname ,
@@ -416,6 +480,7 @@ function getImplementedAdditions(implDoclets, allDoclets, commentedDoclets) {
416
480
if ( ! hasOwnProp . call ( commentedDoclets , implementationDoclet . longname ) ) {
417
481
updateAddedDoclets ( implementationDoclet , additions , additionIndexes ) ;
418
482
updateDocumentedDoclets ( implementationDoclet , commentedDoclets ) ;
483
+ updateMemberofDoclets ( implementationDoclet , index . memberof ) ;
419
484
}
420
485
// If the implementation used an @inheritdoc or @override tag, add the
421
486
// interface's docs, and ignore the existing doclets.
@@ -428,6 +493,7 @@ function getImplementedAdditions(implDoclets, allDoclets, commentedDoclets) {
428
493
429
494
updateAddedDoclets ( implementationDoclet , additions , additionIndexes ) ;
430
495
updateDocumentedDoclets ( implementationDoclet , commentedDoclets ) ;
496
+ updateMemberofDoclets ( implementationDoclet , index . memberof ) ;
431
497
432
498
// Remove property that's no longer accurate.
433
499
if ( implementationDoclet . virtual ) {
@@ -445,7 +511,7 @@ function getImplementedAdditions(implDoclets, allDoclets, commentedDoclets) {
445
511
// indicate what the implementation is implementing.
446
512
else {
447
513
updateImplements ( commentedDoclets [ implementationDoclet . longname ] ,
448
- interfaceDoclets [ k ] . longname ) ;
514
+ parentDoclet . longname ) ;
449
515
}
450
516
}
451
517
}
@@ -460,7 +526,7 @@ function augment(doclets, propertyName, docletFinder) {
460
526
var dependencies = sort ( mapDependencies ( index , propertyName ) ) ;
461
527
462
528
dependencies . forEach ( function ( depName ) {
463
- var additions = docletFinder ( index [ depName ] , doclets , doclets . index . documented ) ;
529
+ var additions = docletFinder ( index [ depName ] , doclets , doclets . index ) ;
464
530
465
531
additions . forEach ( function ( addition ) {
466
532
var longname = addition . longname ;
@@ -481,7 +547,7 @@ function augment(doclets, propertyName, docletFinder) {
481
547
* calling this method creates a new doclet for `ClassB#myMethod`.
482
548
*
483
549
* @param {!Array.<module:jsdoc/doclet.Doclet> } doclets - The doclets generated by JSDoc.
484
- * @param {!Object } doclets.index - The doclet index added by { @link module:jsdoc/borrow.indexAll} .
550
+ * @param {!Object } doclets.index - The doclet index.
485
551
* @return {void }
486
552
*/
487
553
exports . addInherited = function ( doclets ) {
@@ -500,7 +566,7 @@ exports.addInherited = function(doclets) {
500
566
* creates a new doclet for the instance method `ClassA#myMethod`.
501
567
*
502
568
* @param {!Array.<module:jsdoc/doclet.Doclet> } doclets - The doclets generated by JSDoc.
503
- * @param {!Object } doclets.index - The doclet index added by { @link module:jsdoc/borrow.indexAll} .
569
+ * @param {!Object } doclets.index - The doclet index.
504
570
* @return {void }
505
571
*/
506
572
exports . addMixedIn = function ( doclets ) {
@@ -521,7 +587,7 @@ exports.addMixedIn = function(doclets) {
521
587
* generate a new doclet that reflects the interface's documentation for `InterfaceA#myMethod`.
522
588
*
523
589
* @param {!Array.<module:jsdoc/doclet.Doclet> } docs - The doclets generated by JSDoc.
524
- * @param {!Object } doclets.index - The doclet index added by { @link module:jsdoc/borrow.indexAll} .
590
+ * @param {!Object } doclets.index - The doclet index.
525
591
* @return {void }
526
592
*/
527
593
exports . addImplemented = function ( doclets ) {
0 commit comments