Skip to content
This repository was archived by the owner on Jan 11, 2023. It is now read-only.

Commit 82e01e4

Browse files
committed
Constructor generation with documentation.
From [PR#74](englercj#74) with fix.
1 parent 1cefe92 commit 82e01e4

File tree

5 files changed

+91
-42
lines changed

5 files changed

+91
-42
lines changed

src/Emitter.ts

Lines changed: 52 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -51,22 +51,31 @@ function isExportDefault(doclet: TDoclet)
5151

5252
function shouldMoveOutOfClass(doclet: TDoclet)
5353
{
54-
if (isConstructor(doclet))
55-
{
56-
return false;
57-
}
58-
else
59-
{
60-
return isClassLike(doclet)
61-
|| isModuleLike(doclet)
62-
|| isEnum(doclet)
63-
|| doclet.kind === 'typedef';
64-
}
54+
return isClassLike(doclet)
55+
|| isModuleLike(doclet)
56+
|| isEnum(doclet)
57+
|| doclet.kind === 'typedef';
58+
}
59+
60+
function isClassDeclaration(doclet: TDoclet)
61+
{
62+
return (
63+
doclet && (doclet.kind === 'class')
64+
&& doclet.meta && (
65+
// When the owner class's comment contains a @class tag, the first doclet for the class is detached one,
66+
// btw the 'code' section is empty.
67+
(! doclet.meta.code.type)
68+
|| (doclet.meta.code.type === 'ClassDeclaration')
69+
)
70+
);
6571
}
6672

6773
function isConstructor(doclet: TDoclet)
6874
{
69-
return doclet.kind === "class" && doclet.name === doclet.memberof
75+
return (
76+
(doclet.kind === 'class')
77+
&& doclet.meta && (doclet.meta.code.type === 'MethodDefinition')
78+
);
7079
}
7180

7281
export class Emitter
@@ -158,6 +167,26 @@ export class Emitter
158167
{
159168
const doclet = docs[i];
160169

170+
if ((doclet.kind !== 'package') && isConstructor(doclet))
171+
{
172+
// If this doclet is a constructor, do not watch the 'memberof' attribute,
173+
// it usually has the same value as the owner class's declaration,
174+
// it does point the owner class itself.
175+
// Use the 'longname' which equals the owner class's 'longname'.
176+
const ownerClass = this._treeNodes[doclet.longname];
177+
if ((!ownerClass) || (!isClassDeclaration(ownerClass.doclet)))
178+
{
179+
warn(`Failed to find owner class of constructor '${doclet.longname}'.`, doclet);
180+
continue;
181+
}
182+
debug(`Emitter._buildTree(): adding constructor ${docletDebugInfo(doclet)} to class declaration ${docletDebugInfo(ownerClass.doclet)}`);
183+
ownerClass.children.push({ doclet: doclet, children: [] });
184+
continue;
185+
186+
// Note: The constructor should be generated with its documentation whatever its access level.
187+
// Do not move this block after the test below.
188+
}
189+
161190
if (doclet.kind === 'package' || this._ignoreDoclet(doclet))
162191
{
163192
debug(`Emitter._buildTree(): skipping ${docletDebugInfo(doclet) } (package or ignored)`, doclet);
@@ -380,10 +409,17 @@ export class Emitter
380409

381410
private _ignoreDoclet(doclet: TAnyDoclet): boolean
382411
{
383-
if (doclet.kind === 'package'
384-
|| doclet.ignore
385-
|| (!this.options.private && doclet.access === 'private')) {
386-
debug(`Emitter._ignoreDoclet(doclet=${docletDebugInfo(doclet)}) => true (package, ignored or private disabled)`);
412+
let reason: string|undefined = undefined;
413+
if (doclet.kind === 'package')
414+
reason = 'package doclet';
415+
else if (!!doclet.ignore)
416+
reason = 'doclet with an ignore flag';
417+
else if (!this.options.private && doclet.access === 'private')
418+
reason = 'private access disabled';
419+
if (reason
420+
|| (doclet.kind === 'package')) // <= hack for typescript resolutions
421+
{
422+
debug(`Emitter._ignoreDoclet(doclet=${docletDebugInfo(doclet)}) => true (${reason})`);
387423
return true
388424
}
389425

src/create_helpers.ts

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -108,16 +108,19 @@ export function createClass(doclet: IClassDoclet, children?: ts.Node[]): ts.Clas
108108

109109
if (doclet.params)
110110
{
111-
const params = createFunctionParams(doclet);
112-
113-
members.unshift(
114-
ts.createConstructor(
115-
undefined, // decorators
116-
undefined, // modifiers
117-
params, // parameters
118-
undefined // body
119-
)
120-
);
111+
// Check whether the constructor has already been declared.
112+
if (members.filter(member => ts.isConstructorDeclaration(member)).length === 0)
113+
{
114+
debug(`createClass(${docletDebugInfo(doclet)}): no constructor set yet, adding one automatically`);
115+
members.unshift(
116+
ts.createConstructor(
117+
undefined, // decorators
118+
undefined, // modifiers
119+
createFunctionParams(doclet), // parameters
120+
undefined // body
121+
)
122+
);
123+
}
121124
}
122125

123126
if (doclet.properties)
@@ -346,12 +349,11 @@ export function createConstructor(doclet: IClassDoclet): ts.ConstructorDeclarati
346349
{
347350
debug(`createConstructor(${docletDebugInfo(doclet)})`);
348351

349-
const params = createFunctionParams(doclet);
350352
return handleComment(doclet, ts.createConstructor(
351-
undefined, // decorators
352-
getAccessModifiers(doclet), // modifiers
353-
params, // parameters
354-
undefined // body
353+
undefined, // decorators
354+
getAccessModifiers(doclet), // modifiers
355+
createFunctionParams(doclet), // parameters
356+
undefined // body
355357
))
356358
}
357359

src/publish.ts

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,30 +10,39 @@ import { setVerbose, setDebug, debug, docletDebugInfo } from './logger';
1010
*/
1111
export function publish(data: TDocletDb, opts: ITemplateConfig)
1212
{
13-
// start with taking into account 'verbose' and 'debug' options
13+
// Start with taking into account 'verbose' and 'debug' options.
1414
setVerbose(!!opts.verbose);
1515
setDebug(!!opts.debug);
1616

17-
// in order not to break backward compatibility, the 'documented' generation strategy is used by default
17+
// In order not to break backward compatibility, the 'documented' generation strategy is used by default.
1818
if (! opts.generationStrategy)
1919
{
2020
opts.generationStrategy = 'documented';
2121
}
2222
debug(`publish(): Generation strategy: '${opts.generationStrategy}'`);
2323

24-
// do not remove undocumented doclet with the 'exported' generation strategy
25-
// the Emitter._walkExportedDoclets() function will make the appropriate selection later
24+
// Do not remove undocumented doclet with the 'exported' generation strategy.
25+
// The Emitter._walkExportedDoclets() function will make the appropriate selection later.
2626
if (opts.generationStrategy !== 'exported')
2727
{
2828
// remove undocumented stuff.
2929
data(
30-
// use of a function as the TaffyDB query in order to track what is removed
30+
// Use of a function as the TaffyDB query in order to track what is removed.
3131
// see [TaffyDB documentation](http://taffydb.com/writing_queries.html)
3232
function(this: TDoclet) // <= 'this' type declaration inspired from [stackoverflow](https://stackoverflow.com/questions/41944650)
3333
{
3434
if (this.undocumented)
3535
{
36-
debug(`publish(): ${docletDebugInfo(this)} removed`);
36+
// Some doclets are marked 'undocumented', but actually have a 'comment' set.
37+
if ((! this.comment) || (this.comment === ''))
38+
{
39+
debug(`publish(): ${docletDebugInfo(this)} removed`);
40+
return true;
41+
}
42+
else
43+
{
44+
debug(`publish(): ${docletDebugInfo(this)} saved from removal`);
45+
}
3746
}
3847
return false;
3948
}

test/expected/class_all.d.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,12 @@ declare module "util" {
132132
* @mixes Things
133133
*/
134134
class MyThing extends OtherThing implements Stuff, Things {
135-
constructor(...a: number[]);
135+
/**
136+
* Constructs!
137+
* @param {...number} a - The number.
138+
* @private
139+
*/
140+
private constructor(...a: number[]);
136141
/**
137142
* Derp or something.
138143
*

test/expected/constructors.d.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
* Class documentation.
33
*/
44
declare class MyClass {
5-
65
/**
76
* Constructor documentation.
87
* @public
@@ -16,7 +15,6 @@ declare class MyClass {
1615
* Class documentation.
1716
*/
1817
declare class MyClass2 {
19-
2018
/**
2119
* Constructor documentation.
2220
* @protected
@@ -30,7 +28,6 @@ declare class MyClass2 {
3028
* Class documentation.
3129
*/
3230
declare class MyClass3 {
33-
3431
/**
3532
* Constructor documentation.
3633
* @package
@@ -44,7 +41,6 @@ declare class MyClass3 {
4441
* Class documentation.
4542
*/
4643
declare class MyClass4 {
47-
4844
/**
4945
* Constructor documentation.
5046
* @private
@@ -53,3 +49,4 @@ declare class MyClass4 {
5349
*/
5450
private constructor(a: number, b: string);
5551
}
52+

0 commit comments

Comments
 (0)