Skip to content

Commit 7a07d51

Browse files
rhendrictmcw
authored andcommitted
feat: implement @hideconstructor (#898)
Per usejsdoc.org, this tag goes either in a comment attached to a function that has declared that function to be a class, or in a comment on an ES6 class constructor.
1 parent 2df7d3e commit 7a07d51

File tree

6 files changed

+71
-11
lines changed

6 files changed

+71
-11
lines changed

__tests__/lib/infer/params.js

+24
Original file line numberDiff line numberDiff line change
@@ -163,4 +163,28 @@ test('inferParams', function() {
163163
expect(
164164
evaluate('/** Test */ export default function f(x) {}').params
165165
).toEqual([{ lineNumber: 1, name: 'x', title: 'param' }]);
166+
167+
expect(
168+
evaluate(function() {
169+
/**
170+
* @class
171+
* @hideconstructor
172+
*/
173+
function SomeClass(foo, bar) {}
174+
}).params
175+
).toEqual([]);
176+
177+
expect(
178+
evaluate(`
179+
/**
180+
* Test
181+
*/
182+
class SomeClass {
183+
/**
184+
* @hideconstructor
185+
*/
186+
constructor(foo, bar) {}
187+
}
188+
`).params
189+
).toEqual([]);
166190
});

__tests__/lib/parse.js

+8
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,14 @@ test('parse - @global', function() {
444444
).toBe('global');
445445
});
446446

447+
test('parse - @hideconstructor', function() {
448+
expect(
449+
evaluate(function() {
450+
/** @hideconstructor */
451+
})[0].hideconstructor
452+
).toBe(true);
453+
});
454+
447455
test('parse - @host', function() {});
448456

449457
test('parse - @ignore', function() {

declarations/comment.js

+2
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ type Comment = {
8484
classdesc?: Remark,
8585

8686
members: CommentMembers,
87+
constructorComment?: Comment,
8788

8889
name?: string,
8990
kind?: Kind,
@@ -100,6 +101,7 @@ type Comment = {
100101
since?: string,
101102
lends?: string,
102103
override?: boolean,
104+
hideconstructor?: true,
103105

104106
type?: DoctrineType,
105107

src/infer/params.js

+11-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@ function inferParams(comment: Comment) {
2323

2424
// If this is an ES6 class with a constructor method, infer
2525
// parameters from that constructor method.
26-
if (t.isClassDeclaration(path)) {
26+
if (
27+
t.isClassDeclaration(path) &&
28+
!(comment.constructorComment && comment.constructorComment.hideconstructor)
29+
) {
2730
let constructor = path.node.body.body.find(item => {
2831
// https://github.com/babel/babylon/blob/master/ast/spec.md#classbody
2932
return t.isClassMethod(item) && item.kind === 'constructor';
@@ -37,6 +40,10 @@ function inferParams(comment: Comment) {
3740
return comment;
3841
}
3942

43+
if (comment.kind === 'class' && comment.hideconstructor) {
44+
return comment;
45+
}
46+
4047
return inferAndCombineParams(path.node.params, comment);
4148
}
4249

@@ -277,7 +284,9 @@ function mergeTopNodes(inferred, explicit) {
277284

278285
var errors = explicitTagsWithoutInference.map(tag => {
279286
return {
280-
message: `An explicit parameter named ${tag.name || ''} was specified but didn't match ` +
287+
message:
288+
`An explicit parameter named ${tag.name ||
289+
''} was specified but didn't match ` +
281290
`inferred information ${Array.from(inferredNames).join(', ')}`,
282291
commentLineNumber: tag.lineNumber
283292
};

src/parse.js

+1
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ var flatteners = {
168168
global(result) {
169169
result.scope = 'global';
170170
},
171+
hideconstructor: flattenBoolean,
171172
host: synonym('external'),
172173
ignore: flattenBoolean,
173174
implements: todo,

src/parsers/javascript.js

+25-9
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,10 @@ function leftPad(str, width) {
3636
*/
3737
function parseJavaScript(data: Object, config: DocumentationConfig) {
3838
var visited = new Set();
39+
const commentsByNode = new Map();
3940

4041
var ast = parseToAst(data.source);
41-
var addComment = _addComment.bind(null, visited);
42+
var addComment = _addComment.bind(null, visited, commentsByNode);
4243

4344
return _.flatMap(
4445
config.documentExported
@@ -54,6 +55,7 @@ function parseJavaScript(data: Object, config: DocumentationConfig) {
5455

5556
function _addComment(
5657
visited,
58+
commentsByNode,
5759
data,
5860
commentValue,
5961
commentLoc,
@@ -89,19 +91,33 @@ function _addComment(
8991
value: path
9092
});
9193

92-
// #689
93-
if (t.isClassMethod(path) && path.node.kind === 'constructor') {
94-
debuglog(
95-
'A constructor was documented explicitly: document along with the class instead'
96-
);
97-
}
98-
9994
if (path.parentPath && path.parentPath.node) {
10095
var parentNode = path.parentPath.node;
10196
context.code = data.source.substring(parentNode.start, parentNode.end);
10297
}
10398
}
104-
return parse(commentValue, commentLoc, context);
99+
const comment = parse(commentValue, commentLoc, context);
100+
if (includeContext) {
101+
commentsByNode.set(path.node, comment);
102+
103+
if (t.isClassMethod(path) && path.node.kind === 'constructor') {
104+
// #689
105+
if (!comment.hideconstructor) {
106+
debuglog(
107+
'A constructor was documented explicitly: document along with the class instead'
108+
);
109+
}
110+
111+
const parentComment = commentsByNode.get(
112+
path.parentPath.parentPath.node
113+
);
114+
if (parentComment) {
115+
parentComment.constructorComment = comment;
116+
return;
117+
}
118+
}
119+
}
120+
return comment;
105121
}
106122
}
107123

0 commit comments

Comments
 (0)