diff --git a/lib/jsdoc/name.js b/lib/jsdoc/name.js index b122b442..09554736 100644 --- a/lib/jsdoc/name.js +++ b/lib/jsdoc/name.js @@ -90,9 +90,11 @@ function prototypeToPunc(name) { exports.resolve = function(doclet) { var about = {}; var memberof = doclet.memberof || ''; + var metaName; var name = doclet.name ? String(doclet.name) : ''; - var parentDoc; + var puncAndName; + var puncAndNameIndex; // change MyClass.prototype.instanceMethod to MyClass#instanceMethod // (but not in function params, which lack doclet.kind) @@ -167,10 +169,21 @@ exports.resolve = function(doclet) { doclet.scope = puncToScope[RegExp.$1]; doclet.name = doclet.name.substr(1); } - else { - doclet.scope = DEFAULT_SCOPE; + else if (doclet.meta.code && doclet.meta.code.name) { + // HACK: Handle cases where an ES 2015 class is a static memberof something else, and + // the class has instance members. In these cases, we have to detect the instance + // members' scope by looking at the meta info. There's almost certainly a better way to + // do this... + metaName = String(doclet.meta.code.name); + puncAndName = SCOPE.PUNC.INSTANCE + doclet.name; + puncAndNameIndex = metaName.indexOf(puncAndName); + if ( puncAndNameIndex !== -1 && + (puncAndNameIndex === metaName.length - puncAndName.length) ) { + doclet.scope = SCOPE.NAMES.INSTANCE; + } } + doclet.scope = doclet.scope || DEFAULT_SCOPE; doclet.setLongname(doclet.memberof + scopeToPunc[doclet.scope] + doclet.name); } diff --git a/test/fixtures/classtag2.js b/test/fixtures/classtag2.js index 333b70b3..f2dd0f1f 100644 --- a/test/fixtures/classtag2.js +++ b/test/fixtures/classtag2.js @@ -46,3 +46,9 @@ subclasses.ExpiringSubscription = class ExpiringSubscription { */ constructor(name) {} } + +/** @memberof subclasses */ +class InvalidSubscription { + /** Instance method. */ + foo() {} +} diff --git a/test/specs/tags/classtag.js b/test/specs/tags/classtag.js index b5aa1e05..0dbad196 100644 --- a/test/specs/tags/classtag.js +++ b/test/specs/tags/classtag.js @@ -22,6 +22,7 @@ describe('@class tag', function() { var subscriber = docSet2.getByLongname('Subscriber')[0]; var hasCallback = docSet2.getByLongname('Subscriber#hasCallback')[0]; var expiringSubscription = docSet2.getByLongname('subclasses.ExpiringSubscription')[0]; + var invalidSubscriptionFoo = docSet2.getByLongname('subclasses.InvalidSubscription#foo')[0]; it('When a symbol is a class declaration, the doclet does not require the @class tag', function() { expect(subscription.kind).toBe('class'); @@ -64,6 +65,12 @@ describe('@class tag', function() { expect(expiringSubscription.name).toBe('ExpiringSubscription'); expect(expiringSubscription.params[0].name).toBe('name'); }); + + it('When a class is a static memberof something else, the class\' instance methods have the correct scope', function() { + expect(invalidSubscriptionFoo.kind).toBe('function'); + expect(invalidSubscriptionFoo.name).toBe('foo'); + expect(invalidSubscriptionFoo.scope).toBe('instance'); + }); }); } });