|
3 | 3 | var through = require('through'), |
4 | 4 | types = require('ast-types'); |
5 | 5 |
|
| 6 | +/** |
| 7 | + * Create a transform stream that attempts to infer a `name` tag from the context. |
| 8 | + * |
| 9 | + * @name inferName |
| 10 | + * @return {stream.Transform} |
| 11 | + */ |
6 | 12 | module.exports = function () { |
7 | 13 | return through(function (comment) { |
8 | 14 | if (comment.tags.some(function (tag) { return tag.title === 'name'; })) { |
9 | 15 | this.push(comment); |
10 | 16 | return; |
11 | 17 | } |
12 | 18 |
|
13 | | - /** |
14 | | - * Infer the function's name from the context, if possible. |
15 | | - * If `inferredName` is present and `comment` does not already |
16 | | - * have a `name` tag, `inferredName` is tagged as the name. |
17 | | - * @param {Object} comment the current state of the parsed JSDoc comment |
18 | | - * @param {string} inferredName a name inferred by the nearest function |
19 | | - * or variable in the AST |
20 | | - * @return {boolean} `false`: to satisfy an ast-types requirement for visitor methods |
21 | | - */ |
22 | | - function inferName(inferredName) { |
23 | | - if (inferredName) { |
24 | | - comment.tags.push({ |
25 | | - title: 'name', |
26 | | - name: inferredName |
27 | | - }); |
28 | | - } |
29 | | - return false; |
30 | | - } |
31 | | - |
| 19 | + // The strategy here is to do a depth-first traversal of the AST, |
| 20 | + // looking for nodes with a "name" property, with exceptions as needed. |
| 21 | + // For example, name inference for a MemberExpression `foo.bar = baz` will |
| 22 | + // infer the named based on the `property` of the MemberExpression (`bar`) |
| 23 | + // rather than the `object` (`foo`). |
32 | 24 | types.visit(comment.context.ast, { |
33 | | - visitExpressionStatement: function (path) { |
34 | | - return inferName(path.value.expression.left.name); |
| 25 | + inferName: function(path, value) { |
| 26 | + if (value && value.name) { |
| 27 | + comment.tags.push({ |
| 28 | + title: 'name', |
| 29 | + name: value.name |
| 30 | + }); |
| 31 | + return false; |
| 32 | + } |
| 33 | + this.traverse(path); |
35 | 34 | }, |
36 | 35 |
|
37 | | - visitMemberExpression: function (path) { |
38 | | - return inferName(path.value.property.name); |
| 36 | + visitNode: function (path) { |
| 37 | + return this.inferName(path, path.value); |
39 | 38 | }, |
40 | 39 |
|
41 | | - visitIdentifier: function (path) { |
42 | | - return inferName(path.value.name); |
| 40 | + visitMemberExpression: function (path) { |
| 41 | + return this.inferName(path, path.value.property); |
43 | 42 | } |
44 | 43 | }); |
45 | 44 |
|
|
0 commit comments