From d7c7fea3588b7d678e16f57f9dc43b01efa47e7c Mon Sep 17 00:00:00 2001 From: Jeff Williams Date: Thu, 13 Jul 2017 17:09:07 -0700 Subject: [PATCH] use the correct longname for constructors of ES2015 classes with `@alias` tags (#1395) --- lib/jsdoc/src/handlers.js | 32 ++++++++++++++++++++++++------- test/fixtures/alias6.js | 8 ++++++++ test/specs/documentation/alias.js | 9 +++++++++ 3 files changed, 42 insertions(+), 7 deletions(-) create mode 100644 test/fixtures/alias6.js diff --git a/lib/jsdoc/src/handlers.js b/lib/jsdoc/src/handlers.js index f85b8941..6968afab 100644 --- a/lib/jsdoc/src/handlers.js +++ b/lib/jsdoc/src/handlers.js @@ -90,14 +90,32 @@ function setCurrentModule(doclet) { } } -function setModuleScopeMemberOf(doclet) { +function setModuleScopeMemberOf(parser, doclet) { + var parentDoclet; + var skipMemberof; + // handle module symbols that are _not_ assigned to module.exports if (currentModule && currentModule.longname !== doclet.name) { if (!doclet.scope) { - // is this a method definition? if so, get the scope from the node directly + // is this a method definition? if so, we usually get the scope from the node directly if (doclet.meta && doclet.meta.code && doclet.meta.code.node && doclet.meta.code.node.type === Syntax.MethodDefinition) { - if (doclet.meta.code.node.static) { + // special case for constructors of classes that have @alias tags + if (doclet.meta.code.node.kind === 'constructor') { + parentDoclet = parser._getDocletById( + doclet.meta.code.node.parent.parent.nodeId + ); + + if (parentDoclet && parentDoclet.alias) { + // the constructor should use the same name as the class + doclet.addTag('alias', parentDoclet.alias); + doclet.addTag('name', parentDoclet.alias); + + // and we shouldn't try to set a memberof value + skipMemberof = true; + } + } + else if (doclet.meta.code.node.static) { doclet.addTag('static'); } else { @@ -117,8 +135,8 @@ function setModuleScopeMemberOf(doclet) { } // if the doclet isn't a memberof anything yet, and it's not a global, it must be a memberof - // the current module - if (!doclet.memberof && doclet.scope !== SCOPE_NAMES.GLOBAL) { + // the current module (unless we were told to skip adding memberof) + if (!doclet.memberof && doclet.scope !== SCOPE_NAMES.GLOBAL && !skipMemberof) { doclet.addTag('memberof', currentModule.longname); } } @@ -264,7 +282,7 @@ function addSymbolMemberof(parser, doclet, astNode) { } // otherwise, add the defaults for a module (if we're currently in a module) else { - setModuleScopeMemberOf(doclet); + setModuleScopeMemberOf(parser, doclet); } } @@ -329,7 +347,7 @@ exports.attachTo = function(parser) { } // add the default scope/memberof for a module (if we're in a module) - setModuleScopeMemberOf(newDoclet); + setModuleScopeMemberOf(parser, newDoclet); newDoclet.postProcess(); // if we _still_ don't have a scope, use the default diff --git a/test/fixtures/alias6.js b/test/fixtures/alias6.js new file mode 100644 index 00000000..c90bf247 --- /dev/null +++ b/test/fixtures/alias6.js @@ -0,0 +1,8 @@ +'use strict'; + +/** @module example */ + +/** @alias module:example */ +class Foo { + constructor() {} +} diff --git a/test/specs/documentation/alias.js b/test/specs/documentation/alias.js index 55a244d9..78f72682 100644 --- a/test/specs/documentation/alias.js +++ b/test/specs/documentation/alias.js @@ -73,6 +73,15 @@ describe('aliases', function() { }); }); + it('When a symbol is a constructor of a class with an alias, the constructor should get the correct longname', function() { + var docSet = jasmine.getDocSetFromFile('test/fixtures/alias6.js'); + var constructor = docSet.getByLongname('module:example')[2]; + + expect(constructor.undocumented).toBe(true); + expect(constructor.name).toBe('module:example'); + expect(constructor.alias).toBe('module:example'); + }); + it('When a symbol is documented as a static member of , its scope is "global" and not "static".', function() { var docSet = jasmine.getDocSetFromFile('test/fixtures/aliasglobal.js'); var log = docSet.getByLongname('log')[0];