support class expressions (#555)

This commit is contained in:
Jeff Williams 2015-04-10 16:02:27 -07:00
parent dcb327605e
commit fe9407cd71
8 changed files with 70 additions and 9 deletions

View File

@ -58,7 +58,7 @@ function codeToKind(code) {
kind = 'function';
}
}
else if (code.type === Syntax.ClassDeclaration) {
else if (code.type === Syntax.ClassDeclaration || code.type === Syntax.ClassExpression) {
kind = 'class';
}
else if ( code.node && code.node.parent && isFunction(code.node.parent) ) {
@ -123,9 +123,14 @@ function toTags(docletSrc) {
}
function fixDescription(docletSrc, meta) {
var isClass;
if (!/^\s*@/.test(docletSrc) && docletSrc.replace(/\s/g, '').length) {
docletSrc = (meta.code && meta.code.type === Syntax.ClassDeclaration ? '@classdesc' :
'@description') + ' ' + docletSrc;
isClass = meta.code &&
(meta.code.type === Syntax.ClassDeclaration ||
meta.code.type === Syntax.ClassExpression);
docletSrc = (isClass ? '@classdesc' : '@description') + ' ' + docletSrc;
}
return docletSrc;
}

View File

@ -106,6 +106,7 @@ var addNodeProperties = exports.addNodeProperties = function(node) {
// TODO: docs
var nodeToValue = exports.nodeToValue = function(node) {
var parent;
var str;
var tempObject;
@ -157,7 +158,13 @@ var nodeToValue = exports.nodeToValue = function(node) {
break;
case Syntax.MethodDefinition:
str = nodeToValue(node.parent.parent.id);
parent = node.parent.parent;
// for class expressions, we want the name of the variable the class is assigned to
if (parent.type === Syntax.ClassExpression) {
parent = parent.parent;
}
str = nodeToValue(parent.id);
if (node.kind !== 'constructor') {
str += node.static ? name.SCOPE.PUNC.STATIC : name.SCOPE.PUNC.INSTANCE;
str += nodeToValue(node.key);
@ -264,7 +271,7 @@ var getInfo = exports.getInfo = function(node) {
info.paramnames = getParamNames(node.right);
break;
// like: "class Foo { }"
// like: "class Foo {}"
case Syntax.ClassDeclaration:
info.node = node;
info.name = nodeToValue(node.id);

View File

@ -282,7 +282,7 @@ function newSymbolDoclet(parser, docletSrc, e) {
}
// handle cases where the doclet kind is auto-detected from the node type
if (e.code.kind) {
if (e.code.kind && newDoclet.kind === 'member') {
newDoclet.kind = e.code.kind;
}

View File

@ -458,6 +458,10 @@ Visitor.prototype.makeSymbolFoundEvent = function(node, parser, filename) {
// like: class foo {}
case Syntax.ClassDeclaration:
// falls through
// like: let MyClass = class {}
case Syntax.ClassExpression:
e = new SymbolFound(node, filename, extras);
trackVars(parser, node, e);
@ -564,7 +568,6 @@ Visitor.prototype.makeSymbolFoundEvent = function(node, parser, filename) {
// for now, log a warning for all ES6 nodes, since we don't do anything useful with them
case Syntax.ArrowFunctionExpression:
case Syntax.ClassExpression:
case Syntax.ExportAllDeclaration:
case Syntax.ExportDefaultDeclaration:
case Syntax.ExportNamedDeclaration:

View File

@ -1,5 +1,15 @@
/**
Describe the Subscription class here.
* Describe the Subscription class here.
*/
class Subscription {
/** Force the subscription to expire. */
expire() {}
}
/**
* Describe the Subscriber class here.
*/
const Subscriber = class Foo {
/** Check whether the subscriber has a callback. */
hasCallback() {}
}

4
test/fixtures/constanttag2.js vendored Normal file
View File

@ -0,0 +1,4 @@
/**
* ES 2015 class assigned to a const
*/
const Foo = class bar {}

View File

@ -7,4 +7,15 @@ describe('const declarations', function() {
expect(myPocket.kind).toBe('constant');
});
if (jasmine.jsParser !== 'rhino') {
describe('ES 2015 only', function() {
it('should not override kind="class" when a const is autodetected', function() {
var docSet = jasmine.getDocSetFromFile('test/fixtures/constanttag2.js');
var foo = docSet.getByLongname('Foo')[0];
expect(foo.kind).toBe('class');
});
});
}
});

View File

@ -18,12 +18,33 @@ describe('@class tag', function() {
describe('ES 2015 classes', function() {
var docSet2 = jasmine.getDocSetFromFile('test/fixtures/classtag2.js');
var subscription = docSet2.getByLongname('Subscription')[0];
var expire = docSet2.getByLongname('Subscription#expire')[0];
var subscriber = docSet2.getByLongname('Subscriber')[0];
var hasCallback = docSet2.getByLongname('Subscriber#hasCallback')[0];
it('When a symbol is a class declaration, the doclet does not require the @class tag', function() {
expect(subscription.kind).toBe('class');
expect(subscription.longname).toBe('Subscription');
expect(subscription.name).toBe('Subscription');
expect(subscription.classdesc).toBe('Describe the Subscription class here.');
});
it('When a symbol is a class declaration, its members get the correct longname and memberof', function() {
expect(expire.kind).toBe('function');
expect(expire.name).toBe('expire');
expect(expire.memberof).toBe('Subscription');
});
it('When a symbol is a class expression, the doclet does not require the @class tag', function() {
expect(subscriber.kind).toBe('class');
expect(subscriber.name).toBe('Subscriber');
expect(subscriber.classdesc).toBe('Describe the Subscriber class here.');
});
it('When a symbol is a class expression, its members get the correct longname and memberof', function() {
expect(hasCallback.kind).toBe('function');
expect(hasCallback.name).toBe('hasCallback');
expect(hasCallback.memberof).toBe('Subscriber');
});
});
}
});