Skip to content

Commit ade4f34

Browse files
committed
More correct parsing for kind shorthand (@Class, @constant, etc)
* Set the `kind` property of the comment, not a property named by the kind. * Set the `type` property as appropriate for these shorthands. * Parse @callback as shorthand for @typedef {Function}
1 parent e93e4e4 commit ade4f34

16 files changed

+265
-143
lines changed

Diff for: lib/infer/kind.js

+1-13
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,8 @@
33
var shouldSkipInference = require('./should_skip_inference');
44
var t = require('babel-types');
55

6-
var kindShorthands = ['class', 'constant', 'event', 'external', 'file',
7-
'function', 'member', 'mixin', 'module', 'namespace', 'typedef'];
8-
96
/**
10-
* Infers a `kind` tag from other tags or from the context.
7+
* Infers a `kind` tag from the context.
118
*
129
* @name inferKind
1310
* @param {Object} comment parsed comment
@@ -19,15 +16,6 @@ module.exports = function () {
1916
return comment;
2017
}
2118

22-
for (var i = 0; i < kindShorthands.length; i++) {
23-
var kind = kindShorthands[i];
24-
if (kind in comment) {
25-
comment.kind = kind;
26-
// only allow a comment to have one kind
27-
return comment;
28-
}
29-
}
30-
3119
function findKind(path) {
3220
if (!path) {
3321
return comment;

Diff for: lib/infer/membership.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ module.exports = function () {
7272
var currentModule;
7373

7474
function inferModuleName(comment) {
75-
return (comment.module && comment.module.name) ||
75+
return (comment.kind === 'module' && comment.name) ||
7676
pathParse(comment.context.file).name;
7777
}
7878

@@ -121,7 +121,7 @@ module.exports = function () {
121121

122122
return shouldSkipInference(function inferMembership(comment) {
123123

124-
if (comment.module) {
124+
if (comment.kind === 'module') {
125125
currentModule = comment;
126126
}
127127

Diff for: lib/infer/name.js

+4-22
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,15 @@ var shouldSkipInference = require('./should_skip_inference'),
44
pathParse = require('parse-filepath');
55

66
/**
7-
* Infers a `name` tag from the context,
8-
* and adopt `@class` and other other tags as implied name tags.
7+
* Infers a `name` tag from the context.
98
*
109
* @name inferName
1110
* @param {Object} comment parsed comment
1211
* @returns {Object} comment with name inferred
1312
*/
1413
module.exports = function () {
1514
return shouldSkipInference(function inferName(comment) {
16-
17-
if (comment.event) {
18-
comment.name = comment.event;
15+
if (comment.name) {
1916
return comment;
2017
}
2118

@@ -24,23 +21,8 @@ module.exports = function () {
2421
return comment;
2522
}
2623

27-
if (comment.callback) {
28-
comment.name = comment.callback;
29-
return comment;
30-
}
31-
32-
if (comment.class && comment.class.name) {
33-
comment.name = comment.class.name;
34-
return comment;
35-
}
36-
37-
if (comment.module) {
38-
comment.name = comment.module.name || pathParse(comment.context.file).name;
39-
return comment;
40-
}
41-
42-
if (comment.typedef) {
43-
comment.name = comment.typedef.name;
24+
if (comment.kind === 'module') {
25+
comment.name = pathParse(comment.context.file).name;
4426
return comment;
4527
}
4628

Diff for: lib/parse.js

+48-17
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,22 @@ var flatteners = {
2424
},
2525
'author': flattenDescription,
2626
'borrows': todo,
27-
'callback': flattenDescription,
28-
'class': flattenTypedName,
27+
'callback': function (result, tag) {
28+
result.kind = 'typedef';
29+
30+
if (tag.description) {
31+
result.name = tag.description;
32+
}
33+
34+
result.type = {
35+
type: 'NameExpression',
36+
name: 'Function'
37+
};
38+
},
39+
'class': flattenKindShorthand,
2940
'classdesc': flattenMarkdownDescription,
3041
'const': synonym('constant'),
31-
'constant': flattenTypedName,
42+
'constant': flattenKindShorthand,
3243
'constructor': synonym('class'),
3344
'constructs': todo,
3445
'copyright': flattenMarkdownDescription,
@@ -39,7 +50,13 @@ var flatteners = {
3950
'description': flattenMarkdownDescription,
4051
'emits': synonym('fires'),
4152
'enum': todo,
42-
'event': flattenDescription,
53+
'event': function (result, tag) {
54+
result.kind = 'event';
55+
56+
if (tag.description) {
57+
result.name = tag.description;
58+
}
59+
},
4360
'example': function (result, tag) {
4461
if (!tag.description) {
4562
result.errors.push({
@@ -66,12 +83,24 @@ var flatteners = {
6683
'exception': synonym('throws'),
6784
'exports': todo,
6885
'extends': synonym('augments'),
69-
'external': flattenDescription,
70-
'file': flattenDescription,
86+
'external': function (result, tag) {
87+
result.kind = 'external';
88+
89+
if (tag.description) {
90+
result.name = tag.description;
91+
}
92+
},
93+
'file': function (result, tag) {
94+
result.kind = 'file';
95+
96+
if (tag.description) {
97+
result.description = parseMarkdown(tag.description);
98+
}
99+
},
71100
'fileoverview': synonym('file'),
72101
'fires': todo,
73102
'func': synonym('function'),
74-
'function': flattenName,
103+
'function': flattenKindShorthand,
75104
'global': function (result) {
76105
result.scope = 'global';
77106
},
@@ -97,14 +126,14 @@ var flatteners = {
97126
'lends': flattenDescription,
98127
'license': flattenDescription,
99128
'listens': todo,
100-
'member': flattenTypedName,
129+
'member': flattenKindShorthand,
101130
'memberof': flattenDescription,
102131
'method': synonym('function'),
103132
'mixes': todo,
104-
'mixin': flattenName,
105-
'module': flattenTypedName,
133+
'mixin': flattenKindShorthand,
134+
'module': flattenKindShorthand,
106135
'name': flattenName,
107-
'namespace': flattenTypedName,
136+
'namespace': flattenKindShorthand,
108137
'override': flattenBoolean,
109138
'overview': synonym('file'),
110139
'param': function (result, tag) {
@@ -212,7 +241,7 @@ var flatteners = {
212241
},
213242
'tutorial': todo,
214243
'type': todo,
215-
'typedef': flattenTypedName,
244+
'typedef': flattenKindShorthand,
216245
'var': synonym('member'),
217246
'variation': function (result, tag) {
218247
result.variation = tag.variation;
@@ -245,13 +274,15 @@ function flattenMarkdownDescription(result, tag, key) {
245274
result[key] = parseMarkdown(tag.description);
246275
}
247276

248-
function flattenTypedName(result, tag, key) {
249-
result[key] = {
250-
name: tag.name
251-
};
277+
function flattenKindShorthand(result, tag, key) {
278+
result.kind = key;
279+
280+
if (tag.name) {
281+
result.name = tag.name;
282+
}
252283

253284
if (tag.type) {
254-
result[key].type = tag.type;
285+
result.type = tag.type;
255286
}
256287
}
257288

Diff for: test/fixture/class.output.json

+2-5
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,8 @@
9595
"code": "/**\n * This is my class, a demo thing.\n * @class MyClass\n * @property {number} howMany how many things it contains\n */\nfunction MyClass() {\n this.howMany = 2;\n}\n\n/**\n * Get the number 42\n * @param {boolean} getIt whether to get the number\n * @returns {number} forty-two\n */\nMyClass.prototype.getFoo = function (getIt) {\n return getIt ? 42 : 0;\n};\n\n/**\n * Get undefined\n * @returns {undefined} does not return anything.\n */\nMyClass.prototype.getUndefined = function () { };\n"
9696
},
9797
"errors": [],
98-
"class": {
99-
"name": "MyClass"
100-
},
98+
"kind": "class",
99+
"name": "MyClass",
101100
"properties": [
102101
{
103102
"name": "howMany",
@@ -160,8 +159,6 @@
160159
}
161160
}
162161
],
163-
"name": "MyClass",
164-
"kind": "class",
165162
"members": {
166163
"instance": [
167164
{

Diff for: test/fixture/event.output.json

+2-3
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,8 @@
111111
}
112112
},
113113
"errors": [],
114-
"event": "Map#mousemove",
114+
"kind": "event",
115+
"name": "Map#mousemove",
115116
"properties": [
116117
{
117118
"name": "point",
@@ -234,8 +235,6 @@
234235
}
235236
}
236237
],
237-
"name": "Map#mousemove",
238-
"kind": "event",
239238
"members": {
240239
"instance": [],
241240
"static": []

Diff for: test/fixture/factory.output.json

+2-6
Original file line numberDiff line numberDiff line change
@@ -192,11 +192,8 @@
192192
"code": "/**\n * an area chart generator\n * @returns {area} chart\n */\nvar area = function() {\n\n /**\n * @class area\n */\n var chart = function(selection) {\n };\n\n /**\n * Sets the chart data.\n * @function\n */\n chart.data = function(_) {\n };\n\n return chart;\n};\n"
193193
},
194194
"errors": [],
195-
"class": {
196-
"name": "area"
197-
},
198-
"name": "area",
199195
"kind": "class",
196+
"name": "area",
200197
"params": [
201198
{
202199
"title": "param",
@@ -302,9 +299,8 @@
302299
"commentLineNumber": 0
303300
}
304301
],
305-
"function": null,
306-
"name": "data",
307302
"kind": "function",
303+
"name": "data",
308304
"params": [
309305
{
310306
"title": "param",

Diff for: test/fixture/inheritance.output.json

+1-4
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,14 @@
3939
"commentLineNumber": 0
4040
}
4141
],
42-
"class": {
43-
"name": "Foo"
44-
},
42+
"kind": "class",
4543
"name": "Foo",
4644
"augments": [
4745
{
4846
"title": "augments",
4947
"name": "Bar"
5048
}
5149
],
52-
"kind": "class",
5350
"memberof": "module",
5451
"scope": "static",
5552
"members": {

Diff for: test/fixture/memberedclass.output.json

+2-5
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,9 @@
9595
"commentLineNumber": 4
9696
}
9797
],
98-
"class": {
99-
"name": "MyClass"
100-
},
101-
"memberof": "com.Test",
102-
"name": "MyClass",
10398
"kind": "class",
99+
"name": "MyClass",
100+
"memberof": "com.Test",
104101
"members": {
105102
"instance": [
106103
{

Diff for: test/fixture/nearby_params.output.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@
142142
"code": "/** Attempt to establish a cookie-based session in exchange for credentials.\n * @function\n * @name sessions.create\n * @param {object} credentials\n * @param {string} credentials.name Login username. Also accepted as `username` or `email`.\n * @param {string} credentials.password Login password\n * @param {function} [callback] Gets passed `(err, { success:Boolean })`.\n * @returns {Promise} promise, to be resolved on success or rejected on failure\n */\nsessions.addMethod('create', 'POST / form', {\n // normalize request body params\n before({ body }) {\n }\n});\n"
143143
},
144144
"errors": [],
145-
"function": null,
145+
"kind": "function",
146146
"name": "sessions.create",
147147
"params": [
148148
{

Diff for: test/fixture/params.output.json

+4-10
Original file line numberDiff line numberDiff line change
@@ -177,9 +177,8 @@
177177
"code": "/**\n * This function returns the number one.\n * @param {number} b the second param\n */\nfunction addThem(a, b, c, { d, e, f }) {\n return a + b + c + d + e + f;\n}\n\n/**\n * This method has partially inferred params\n * @param {String} $0.fishes number of kinds of fish\n */\nfunction fishesAndFoxes({ fishes, foxes }) {\n return fishes + foxes;\n}\n\n/**\n * This method has a type in the description and a default in the code\n * @param {number} x\n */\nfunction withDefault(x = 2) {\n return x;\n}\n\n/**\n * This is foo's documentation\n */\nclass Foo {\n /**\n * The method\n * @param {number} x Param to method\n */\n method(x) {\n }\n}\n\n/**\n * Represents an IPv6 address\n *\n * This tests our support of optional parameters\n * @class Address6\n * @param {string} address - An IPv6 address string\n * @param {number} [groups=8] - How many octets to parse\n * @param {?number} third - A third argument\n * @param {Array} [foo=[1]] to properly be parsed\n * @example\n * var address = new Address6('2001::/32');\n */\nfunction Address6() {}\n\n/**\n * Create a GeoJSON data source instance given an options object\n *\n * This tests our support of nested parameters\n * @class GeoJSONSource\n * @param {Object} [options] optional options\n * @param {Object|string} options.data A GeoJSON data object or URL to it.\n * The latter is preferable in case of large GeoJSON files.\n * @param {number} [options.maxzoom=14] Maximum zoom to preserve detail at.\n * @param {number} [options.buffer] Tile buffer on each side.\n * @param {number} [options.tolerance] Simplification tolerance (higher means simpler).\n */\nfunction GeoJSONSource(options) {\n this.options = options;\n}\n\n/**\n * This tests our support for parameters with explicit types but with default\n * values specified in code.\n *\n * @param {number} x an argument\n *\n * @returns {number} some\n */\nexport const myfunc = (x = 123) => x;\n\n/**\n * This tests our support of JSDoc param tags without type information,\n * or any type information we could infer from annotations.\n *\n * @param address - An IPv6 address string\n */\nfunction foo(address) {\n return address;\n}\n"
178178
},
179179
"errors": [],
180-
"class": {
181-
"name": "Address6"
182-
},
180+
"kind": "class",
181+
"name": "Address6",
183182
"params": [
184183
{
185184
"name": "address",
@@ -437,8 +436,6 @@
437436
"description": "var address = new Address6('2001::/32');"
438437
}
439438
],
440-
"name": "Address6",
441-
"kind": "class",
442439
"members": {
443440
"instance": [],
444441
"static": []
@@ -1423,9 +1420,8 @@
14231420
"code": "/**\n * This function returns the number one.\n * @param {number} b the second param\n */\nfunction addThem(a, b, c, { d, e, f }) {\n return a + b + c + d + e + f;\n}\n\n/**\n * This method has partially inferred params\n * @param {String} $0.fishes number of kinds of fish\n */\nfunction fishesAndFoxes({ fishes, foxes }) {\n return fishes + foxes;\n}\n\n/**\n * This method has a type in the description and a default in the code\n * @param {number} x\n */\nfunction withDefault(x = 2) {\n return x;\n}\n\n/**\n * This is foo's documentation\n */\nclass Foo {\n /**\n * The method\n * @param {number} x Param to method\n */\n method(x) {\n }\n}\n\n/**\n * Represents an IPv6 address\n *\n * This tests our support of optional parameters\n * @class Address6\n * @param {string} address - An IPv6 address string\n * @param {number} [groups=8] - How many octets to parse\n * @param {?number} third - A third argument\n * @param {Array} [foo=[1]] to properly be parsed\n * @example\n * var address = new Address6('2001::/32');\n */\nfunction Address6() {}\n\n/**\n * Create a GeoJSON data source instance given an options object\n *\n * This tests our support of nested parameters\n * @class GeoJSONSource\n * @param {Object} [options] optional options\n * @param {Object|string} options.data A GeoJSON data object or URL to it.\n * The latter is preferable in case of large GeoJSON files.\n * @param {number} [options.maxzoom=14] Maximum zoom to preserve detail at.\n * @param {number} [options.buffer] Tile buffer on each side.\n * @param {number} [options.tolerance] Simplification tolerance (higher means simpler).\n */\nfunction GeoJSONSource(options) {\n this.options = options;\n}\n\n/**\n * This tests our support for parameters with explicit types but with default\n * values specified in code.\n *\n * @param {number} x an argument\n *\n * @returns {number} some\n */\nexport const myfunc = (x = 123) => x;\n\n/**\n * This tests our support of JSDoc param tags without type information,\n * or any type information we could infer from annotations.\n *\n * @param address - An IPv6 address string\n */\nfunction foo(address) {\n return address;\n}\n"
14241421
},
14251422
"errors": [],
1426-
"class": {
1427-
"name": "GeoJSONSource"
1428-
},
1423+
"kind": "class",
1424+
"name": "GeoJSONSource",
14291425
"params": [
14301426
{
14311427
"name": "options",
@@ -1755,8 +1751,6 @@
17551751
]
17561752
}
17571753
],
1758-
"name": "GeoJSONSource",
1759-
"kind": "class",
17601754
"members": {
17611755
"instance": [],
17621756
"static": []

Diff for: test/fixture/trailing.output.json

+1-4
Original file line numberDiff line numberDiff line change
@@ -400,11 +400,8 @@
400400
}
401401
},
402402
"errors": [],
403-
"class": {
404-
"name": "Something"
405-
},
406-
"name": "Something",
407403
"kind": "class",
404+
"name": "Something",
408405
"members": {
409406
"instance": [],
410407
"static": []

Diff for: test/fixture/type_application.output.json

+2-5
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,8 @@
103103
}
104104
},
105105
"errors": [],
106-
"class": {
107-
"name": "Address6"
108-
},
106+
"kind": "class",
107+
"name": "Address6",
109108
"params": [
110109
{
111110
"name": "address",
@@ -177,8 +176,6 @@
177176
}
178177
}
179178
],
180-
"name": "Address6",
181-
"kind": "class",
182179
"members": {
183180
"instance": [],
184181
"static": []

0 commit comments

Comments
 (0)