From 6275e69e8560a525b0c5d7382c5a610b4a019bbb Mon Sep 17 00:00:00 2001 From: Jeff Williams Date: Fri, 7 Jul 2017 13:24:19 -0700 Subject: [PATCH] autodetect default and repeatable parameters when a function is assigned to a variable (#1054) --- lib/jsdoc/src/parser.js | 5 ++++- lib/jsdoc/src/visitor.js | 13 ++++++++++--- test/fixtures/defaultparams.js | 7 +++++++ test/fixtures/restparams.js | 7 +++++++ test/specs/documentation/defaultparams.js | 5 +++++ test/specs/documentation/restparams.js | 8 ++++++++ 6 files changed, 41 insertions(+), 4 deletions(-) diff --git a/lib/jsdoc/src/parser.js b/lib/jsdoc/src/parser.js index c269d407..f397d077 100644 --- a/lib/jsdoc/src/parser.js +++ b/lib/jsdoc/src/parser.js @@ -362,7 +362,10 @@ Parser.prototype.astnodeToMemberof = function(node) { else if (type === Syntax.MethodDefinition && node.kind === 'constructor') { doclet = this._getDocletById(node.enclosingScope.nodeId); - result.memberof = doclet.memberof + jsdoc.name.SCOPE.PUNC.INNER; + // global classes aren't a member of anything + if (doclet.memberof) { + result.memberof = doclet.memberof + jsdoc.name.SCOPE.PUNC.INNER; + } } else { // check local references for aliases diff --git a/lib/jsdoc/src/visitor.js b/lib/jsdoc/src/visitor.js index 1bbb41c0..f313ad7a 100644 --- a/lib/jsdoc/src/visitor.js +++ b/lib/jsdoc/src/visitor.js @@ -184,7 +184,10 @@ function makeRestParamFinisher() { } documentedParams = doclet.params = doclet.params || []; - restNode = findRestParam(e.code.node.params || e.code.node.value.params); + restNode = findRestParam(e.code.node.params || + (e.code.node.value && e.code.node.value.params) || + (e.code.node.init && e.code.node.init.params) || + []); if (restNode) { for (var i = documentedParams.length - 1; i >= 0; i--) { @@ -247,7 +250,7 @@ function makeDefaultParamFinisher() { } documentedParams = doclet.params = doclet.params || []; - params = e.code.node.params || e.code.node.value.params; + params = e.code.node.params || (e.code.node.value && e.code.node.value.params) || []; defaultValues = findDefaultParams(params); for (var i = 0, j = 0, l = params.length; i < l; i++) { @@ -314,7 +317,7 @@ function makeConstructorFinisher(parser) { if (!parentDoclet.description && doclet.description) { parentDoclet.description = doclet.description; } - if (!parentDoclet.params && doclet.params) { + if ( (!parentDoclet.params || !parentDoclet.params.length) && doclet.params) { parentDoclet.params = doclet.params.slice(0); } @@ -794,6 +797,10 @@ Visitor.prototype.makeSymbolFoundEvent = function(node, parser, filename) { // like: var i = 0; case Syntax.VariableDeclarator: extras.finishers = [ + // handle cases where at least one parameter has a default value + makeDefaultParamFinisher(), + // handle rest parameters + makeRestParamFinisher(), // handle async functions makeAsyncFunctionFinisher(), // handle generator functions diff --git a/test/fixtures/defaultparams.js b/test/fixtures/defaultparams.js index e50c4c2a..a4408a2e 100644 --- a/test/fixtures/defaultparams.js +++ b/test/fixtures/defaultparams.js @@ -62,3 +62,10 @@ function setDogName(dogName = '') {} * @param {PizzaToppings} toppings - The user's favorite toppings. */ function setPizzaToppings(toppings = PIZZA_TOPPING_DEFAULTS) {} + +/** + * Set whether the user is a ninja. + * + * @param {boolean} isNinja - Set to `true` if the user is a ninja; otherwise, `false`. + */ +var setIsNinja = function(isNinja = true) {}; diff --git a/test/fixtures/restparams.js b/test/fixtures/restparams.js index 62805964..299e0f5f 100644 --- a/test/fixtures/restparams.js +++ b/test/fixtures/restparams.js @@ -14,3 +14,10 @@ function setAdmins(...users) {} * @param {User} users - The users who will receive rights to access the widget. */ function setWidgetAccess(widget, ...users) {} + +/** + * Set the list of users who are managers. + * + * @param {User} users - The users who are managers. + */ +var setManagers = function(...users) {}; diff --git a/test/specs/documentation/defaultparams.js b/test/specs/documentation/defaultparams.js index 521818b1..2f0fa74e 100644 --- a/test/specs/documentation/defaultparams.js +++ b/test/specs/documentation/defaultparams.js @@ -7,6 +7,7 @@ describe('default parameters', function() { var setBirthYear = docSet.getByLongname('setBirthYear')[0]; var setDogName = docSet.getByLongname('setDogName')[0]; var setFirstName = docSet.getByLongname('setFirstName')[0]; + var setIsNinja = docSet.getByLongname('setIsNinja')[0]; var setLastName = docSet.getByLongname('setLastName')[0]; var setName = docSet.getByLongname('setName')[0]; var setPizzaToppings = docSet.getByLongname('setPizzaToppings')[0]; @@ -49,6 +50,10 @@ describe('default parameters', function() { expect(setPizzaToppings.params[0].defaultvalue).toBeUndefined(); }); + it('should work when the function is assigned to a variable', function() { + expect(setIsNinja.params[0].defaultvalue).toBe(true); + }); + describe('ES2015 methods', function() { var docSet2 = jasmine.getDocSetFromFile('test/fixtures/defaultparams2.js'); diff --git a/test/specs/documentation/restparams.js b/test/specs/documentation/restparams.js index fc4ed6d0..af25f1b2 100644 --- a/test/specs/documentation/restparams.js +++ b/test/specs/documentation/restparams.js @@ -3,6 +3,7 @@ describe('rest parameters', function() { var docSet = jasmine.getDocSetFromFile('test/fixtures/restparams.js'); var setAdmins = docSet.getByLongname('setAdmins')[0]; + var setManagers = docSet.getByLongname('setManagers')[0]; var setWidgetAccess = docSet.getByLongname('setWidgetAccess')[0]; it('should automatically mark standalone rest parameters as repeatable', function() { @@ -19,6 +20,13 @@ describe('rest parameters', function() { expect(restParam.variable).toBe(true); }); + it('should automatically mark rest parameters as repeatable when the function is assigned to a variable', function() { + var restParam = setManagers.params[0]; + + expect(restParam.name).toBe('users'); + expect(restParam.variable).toBe(true); + }); + describe('ES2015 methods', function() { var docSet2 = jasmine.getDocSetFromFile('test/fixtures/restparams2.js');