diff --git a/lib/jsdoc/schema.js b/lib/jsdoc/schema.js index e5fd1545..1b9364d7 100644 --- a/lib/jsdoc/schema.js +++ b/lib/jsdoc/schema.js @@ -597,6 +597,12 @@ var DOCLET_SCHEMA = exports.DOCLET_SCHEMA = { virtual: { type: BOOLEAN, optional: true + }, + yields: { + type: ARRAY, + optional: true, + minItems: 1, + items: PARAM_SCHEMA } } }; diff --git a/lib/jsdoc/tag/dictionary/definitions.js b/lib/jsdoc/tag/dictionary/definitions.js index d1476613..42bfbeb7 100644 --- a/lib/jsdoc/tag/dictionary/definitions.js +++ b/lib/jsdoc/tag/dictionary/definitions.js @@ -819,6 +819,15 @@ var baseTags = exports.baseTags = { onTagged: function(doclet, tag) { doclet.version = tag.value; } + }, + yields: { + mustHaveValue: true, + canHaveType: true, + onTagged: function(doclet, tag) { + doclet.yields = doclet.yields || []; + doclet.yields.push(tag.value); + }, + synonyms: ['yield'] } }; diff --git a/lib/jsdoc/util/templateHelper.js b/lib/jsdoc/util/templateHelper.js index b312d1c5..1ff985db 100644 --- a/lib/jsdoc/util/templateHelper.js +++ b/lib/jsdoc/util/templateHelper.js @@ -751,17 +751,17 @@ exports.getSignatureParams = function(d, optClass) { }; /** - * Retrieve links to types that the member can return. + * Retrieve links to types that the member can return or yield. * * @param {Object} d - The doclet whose types will be retrieved. * @param {string} [cssClass] - The CSS class to include in the `class` attribute for each link. - * @return {Array.} HTML links to types that the member can return. + * @return {Array.} HTML links to types that the member can return or yield. */ exports.getSignatureReturns = function(d, cssClass) { var returnTypes = []; - if (d.returns) { - d.returns.forEach(function(r) { + if (d.yields || d.returns) { + (d.yields || d.returns).forEach(function(r) { if (r && r.type && r.type.names) { if (!returnTypes.length) { returnTypes = r.type.names; diff --git a/templates/default/publish.js b/templates/default/publish.js index d62c8a47..3913ff30 100644 --- a/templates/default/publish.js +++ b/templates/default/publish.js @@ -158,12 +158,13 @@ function addSignatureReturns(f) { var attribsString = ''; var returnTypes = []; var returnTypesString = ''; + var source = f.yields || f.returns; // jam all the return-type attributes into an array. this could create odd results (for example, // if there are both nullable and non-nullable return types), but let's assume that most people // who use multiple @return tags aren't using Closure Compiler type annotations, and vice-versa. - if (f.returns) { - f.returns.forEach(function(item) { + if (source) { + source.forEach(function(item) { helper.getAttribs(item).forEach(function(attrib) { if (attribs.indexOf(attrib) === -1) { attribs.push(attrib); @@ -174,8 +175,8 @@ function addSignatureReturns(f) { attribsString = buildAttribsString(attribs); } - if (f.returns) { - returnTypes = addNonParamAttributes(f.returns); + if (source) { + returnTypes = addNonParamAttributes(source); } if (returnTypes.length) { returnTypesString = util.format( ' → %s{%s}', attribsString, returnTypes.join('|') ); diff --git a/templates/default/tmpl/method.tmpl b/templates/default/tmpl/method.tmpl index 4dd6e0b0..bb7a8ac4 100644 --- a/templates/default/tmpl/method.tmpl +++ b/templates/default/tmpl/method.tmpl @@ -101,6 +101,18 @@ var self = this; + +
Yields:
+ 1) { ?> + + +
Example 1? 's':'' ?>
diff --git a/test/fixtures/yieldstag.js b/test/fixtures/yieldstag.js new file mode 100644 index 00000000..c7799943 --- /dev/null +++ b/test/fixtures/yieldstag.js @@ -0,0 +1,22 @@ +'use strict'; + +/** + * Generate the Fibonacci sequence of numbers. + * + * @yields {number} The next number in the Fibonacci sequence. + */ +function* fibonacci() {} + +/** + * Generate the Fibonacci sequence of numbers. + * + * @yields The next number in the Fibonacci sequence. + */ +function* fibonacci2() {} + +/** + * Generate the Fibonacci sequence of numbers. + * + * @yields {number} + */ +function* fibonacci3() {} diff --git a/test/specs/jsdoc/util/templateHelper.js b/test/specs/jsdoc/util/templateHelper.js index eb369459..cc8d6e73 100644 --- a/test/specs/jsdoc/util/templateHelper.js +++ b/test/specs/jsdoc/util/templateHelper.js @@ -956,8 +956,6 @@ describe("jsdoc/util/templateHelper", function() { }); describe("getSignatureReturns", function() { - // retrieves links to types that the member can return. - it("returns a value with correctly escaped HTML", function() { var mockDoclet = { returns: [ @@ -992,6 +990,21 @@ describe("jsdoc/util/templateHelper", function() { expect(returns.length).toBe(0); }); + it('uses the value of the `yields` property', function() { + var doc = new doclet.Doclet('/** @yields {string} A string. */', {}); + var html = helper.getSignatureReturns(doc); + + expect(html).toContain('string'); + }); + + it('prefers `yields` over `returns`', function() { + var doc = new doclet.Doclet('/** @yields {string}\n@returns {number} */', {}); + var html = helper.getSignatureReturns(doc); + + expect(html).toContain('string'); + expect(html).not.toContain('number'); + }); + it("creates links for return types if relevant", function() { var doc; var returns; diff --git a/test/specs/tags/yieldstag.js b/test/specs/tags/yieldstag.js new file mode 100644 index 00000000..43259575 --- /dev/null +++ b/test/specs/tags/yieldstag.js @@ -0,0 +1,29 @@ +'use strict'; + +describe('@yields tag', function() { + var docSet = jasmine.getDocSetFromFile('test/fixtures/yieldstag.js'); + var fibonacci = docSet.getByLongname('fibonacci')[0]; + var fibonacci2 = docSet.getByLongname('fibonacci2')[0]; + var fibonacci3 = docSet.getByLongname('fibonacci3')[0]; + + it('should add the type and description to the doclet\'s `yields` property', function() { + expect(Array.isArray(fibonacci.yields)).toBe(true); + expect(fibonacci.yields.length).toBe(1); + expect(fibonacci.yields[0].type.names.join(', ')).toBe('number'); + expect(fibonacci.yields[0].description).toBe('The next number in the Fibonacci sequence.'); + }); + + it('should work when only a description is present', function() { + expect(Array.isArray(fibonacci2.yields)).toBe(true); + expect(fibonacci2.yields.length).toBe(1); + expect(fibonacci2.yields[0].type).not.toBeDefined(); + expect(fibonacci2.yields[0].description).toBe('The next number in the Fibonacci sequence.'); + }); + + it('should work when only a type is present', function() { + expect(Array.isArray(fibonacci3.yields)).toBe(true); + expect(fibonacci3.yields.length).toBe(1); + expect(fibonacci3.yields[0].type.names.join(', ')).toBe('number'); + expect(fibonacci3.yields[0].description).not.toBeDefined(); + }); +});