diff --git a/lib/jsdoc/src/parser.js b/lib/jsdoc/src/parser.js index 974d234e..4d5dca04 100644 --- a/lib/jsdoc/src/parser.js +++ b/lib/jsdoc/src/parser.js @@ -257,6 +257,11 @@ function aboutNode(node) { about.node.type = tkn.NAMEDFUNCTIONSTATEMENT; } } + else if (node.type === Token.GETPROP) { + about.node = node; + about.name = nodeToString(about.node); + about.type = getTypeName(node); + } else { // type 39 (NAME) var string = nodeToString(node); @@ -441,6 +446,16 @@ exports.Parser.prototype._visitNode = function(comments, node) { }; e = this._makeEvent(node, comments, extras); } + else if (node.type === Token.GETPROP) { // like 'obj.prop' in '/** @typedef {string} */ obj.prop;' + // this COULD be a Closure Compiler-style typedef, but it's probably not; to avoid filling + // the parse tree with junk, only fire an event if there's a JSDoc comment attached + extras = { + lineno: node.getLineno() + }; + if ( node.getJsDoc() ) { + e = this._makeEvent(node, comments, extras); + } + } else if (node.type == Token.VAR || node.type == Token.LET || node.type == Token.CONST) { if (node.variables) { diff --git a/test/fixtures/typedeftag.js b/test/fixtures/typedeftag.js index 9d82cfdc..fa2b0890 100644 --- a/test/fixtures/typedeftag.js +++ b/test/fixtures/typedeftag.js @@ -1,5 +1,11 @@ /** @typedef {(string|number)} calc.NumberLike */ +/** @typedef {string} */ +calc.Operator; + +/** @typedef {calc.NumberLike} calc.Result */ +calc.Outcome; + /** @param {calc.NumberLike} x A number or a string. */ calc.readNumber = function(x) { -} \ No newline at end of file +}; diff --git a/test/specs/tags/typedeftag.js b/test/specs/tags/typedeftag.js index 3ace0fa0..a3cacebb 100644 --- a/test/specs/tags/typedeftag.js +++ b/test/specs/tags/typedeftag.js @@ -1,12 +1,15 @@ -describe("@typedef tag", function() { - var docSet = jasmine.getDocSetFromFile('test/fixtures/typedeftag.js'), - numberlike = docSet.getByLongname('calc.NumberLike')[0]; +/*global describe: true, expect: true, it: true, jasmine: true */ +describe('@typedef tag', function() { + var docSet = jasmine.getDocSetFromFile('test/fixtures/typedeftag.js'); + var numberlike = docSet.getByLongname('calc.NumberLike')[0]; + var operator = docSet.getByLongname('calc.Operator')[0]; + var result = docSet.getByLongname('calc.Result')[0]; - it('When a symbol has an @typedef tag, the doclet has a kind property set to "typedef".', function() { + it('When a comment has a @typedef tag, the doclet has a kind property set to "typedef".', function() { expect(numberlike.kind).toBe('typedef'); }); - it('When a symbol has an @typedef tag with a type, the doclet has a type property set to that type.', function() { + it('When a comment has a @typedef tag with a type, the doclet has a type property set to that type.', function() { expect(typeof numberlike.type).toBe('object'); expect(typeof numberlike.type.names).toBe('object'); expect(numberlike.type.names.length).toBe(2); @@ -14,8 +17,18 @@ describe("@typedef tag", function() { expect(numberlike.type.names[1]).toBe('number'); }); - it('When a symbol has an @typedef tag with a name, the doclet has a name property set to that name.', function() { + it('When a comment has a @typedef tag with a name, the doclet has a name property set to that name.', function() { expect(numberlike.name).toBe('NumberLike'); expect(numberlike.longname).toBe('calc.NumberLike'); }); -}); \ No newline at end of file + + it('When a symbol has a @typedef tag without a name, the doclet has a name property set to the symbol name.', function() { + expect(operator.name).toBe('Operator'); + expect(operator.longname).toBe('calc.Operator'); + }); + + it('When a symbol has a @typedef tag with a name, the name in the tag takes precedence over the symbol name.', function() { + expect(result.name).toBe('Result'); + expect(result.longname).toBe('calc.Result'); + }); +});