mirror of
https://github.com/jsdoc/jsdoc.git
synced 2026-02-01 16:45:41 +00:00
support arrow function expressions (#555)
This commit is contained in:
parent
ebee2014ad
commit
5a58bdf5a5
@ -22,6 +22,7 @@ var acceptsLeadingComments = (function() {
|
||||
|
||||
// these nodes always accept leading comments
|
||||
var commentable = [
|
||||
Syntax.ArrowFunctionExpression,
|
||||
Syntax.AssignmentExpression,
|
||||
Syntax.CallExpression,
|
||||
Syntax.ClassDeclaration,
|
||||
@ -46,17 +47,20 @@ var acceptsLeadingComments = (function() {
|
||||
// these nodes accept leading comments if they have specific types of parent nodes
|
||||
// like: function foo(/** @type {string} */ bar) {}
|
||||
accepts[Syntax.Identifier] = [
|
||||
Syntax.ArrowFunctionExpression,
|
||||
Syntax.CatchClause,
|
||||
Syntax.FunctionDeclaration,
|
||||
Syntax.FunctionExpression
|
||||
];
|
||||
// like: function foo(/** @type {string} */ bar='baz') {}
|
||||
accepts[Syntax.AssignmentPattern] = [
|
||||
Syntax.ArrowFunctionExpression,
|
||||
Syntax.FunctionDeclaration,
|
||||
Syntax.FunctionExpression
|
||||
];
|
||||
// like: function foo(/** @type {string} */ ...bar) {}
|
||||
accepts[Syntax.RestElement] = [
|
||||
Syntax.ArrowFunctionExpression,
|
||||
Syntax.FunctionDeclaration,
|
||||
Syntax.FunctionExpression
|
||||
];
|
||||
|
||||
@ -33,7 +33,7 @@ var isFunction = exports.isFunction = function(node) {
|
||||
}
|
||||
|
||||
return type === Syntax.FunctionDeclaration || type === Syntax.FunctionExpression ||
|
||||
type === Syntax.MethodDefinition;
|
||||
type === Syntax.MethodDefinition || type === Syntax.ArrowFunctionExpression;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -160,6 +160,9 @@ var nodeToValue = exports.nodeToValue = function(node) {
|
||||
str = 'exports.' + nodeToValue(node.exported);
|
||||
break;
|
||||
|
||||
case Syntax.ArrowFunctionExpression:
|
||||
// falls through
|
||||
|
||||
case Syntax.FunctionDeclaration:
|
||||
// falls through
|
||||
|
||||
@ -295,6 +298,14 @@ var getInfo = exports.getInfo = function(node) {
|
||||
var info = {};
|
||||
|
||||
switch (node.type) {
|
||||
// like the function in: "var foo = () => {}"
|
||||
case Syntax.ArrowFunctionExpression:
|
||||
info.node = node;
|
||||
info.name = '';
|
||||
info.type = info.node.type;
|
||||
info.paramnames = getParamNames(node);
|
||||
break;
|
||||
|
||||
// like: "foo = 'bar'" (after declaring foo)
|
||||
// like: "MyClass.prototype.myMethod = function() {}" (after declaring MyClass)
|
||||
case Syntax.AssignmentExpression:
|
||||
|
||||
@ -282,8 +282,9 @@ Parser.prototype.addDocletRef = function(e) {
|
||||
}
|
||||
// keep references to undocumented anonymous functions, too, as they might have scoped vars
|
||||
else if (
|
||||
(node.type === Syntax.FunctionDeclaration || node.type === Syntax.FunctionExpression) &&
|
||||
!this._getDocletById(node.nodeId) ) {
|
||||
(node.type === Syntax.FunctionDeclaration || node.type === Syntax.FunctionExpression ||
|
||||
node.type === Syntax.ArrowFunctionExpression) &&
|
||||
!this._getDocletById(node.nodeId) ) {
|
||||
fakeDoclet = {
|
||||
longname: jsdoc.name.LONGNAMES.ANONYMOUS,
|
||||
meta: {
|
||||
@ -343,7 +344,8 @@ Parser.prototype.astnodeToMemberof = function(node) {
|
||||
var type = node.type;
|
||||
|
||||
if ( (type === Syntax.FunctionDeclaration || type === Syntax.FunctionExpression ||
|
||||
type === Syntax.VariableDeclarator) && node.enclosingScope ) {
|
||||
type === Syntax.ArrowFunctionExpression || type === Syntax.VariableDeclarator) &&
|
||||
node.enclosingScope ) {
|
||||
doclet = this._getDocletById(node.enclosingScope.nodeId);
|
||||
|
||||
if (!doclet) {
|
||||
|
||||
@ -566,6 +566,10 @@ Visitor.prototype.makeSymbolFoundEvent = function(node, parser, filename) {
|
||||
|
||||
break;
|
||||
|
||||
// like: var foo = () => {};
|
||||
case Syntax.ArrowFunctionExpression:
|
||||
// falls through
|
||||
|
||||
// like: function foo() {}
|
||||
case Syntax.FunctionDeclaration:
|
||||
// falls through
|
||||
@ -671,13 +675,6 @@ Visitor.prototype.makeSymbolFoundEvent = function(node, parser, filename) {
|
||||
|
||||
break;
|
||||
|
||||
// log a warning for ES 2015 nodes that are not currently handled
|
||||
case Syntax.ArrowFunctionExpression:
|
||||
logger.warn('JSDoc does not currently handle %s nodes. Source file: %s, line %s',
|
||||
node.type, filename, (node.loc && node.loc.start) ? node.loc.start.line : '??');
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
// ignore
|
||||
}
|
||||
|
||||
@ -21,7 +21,8 @@ var Syntax = require('jsdoc/src/syntax').Syntax;
|
||||
function isScopeNode(node) {
|
||||
// TODO: handle blocks with "let" declarations
|
||||
return node && typeof node === 'object' && (node.type === Syntax.CatchClause ||
|
||||
node.type === Syntax.FunctionDeclaration || node.type === Syntax.FunctionExpression);
|
||||
node.type === Syntax.FunctionDeclaration || node.type === Syntax.FunctionExpression ||
|
||||
node.type === Syntax.ArrowFunctionExpression);
|
||||
}
|
||||
|
||||
// TODO: docs
|
||||
@ -66,7 +67,6 @@ walkers[Syntax.ArrowFunctionExpression] = function(node, parent, state, cb) {
|
||||
var i;
|
||||
var l;
|
||||
|
||||
// used for function declarations, so we include it here
|
||||
if (node.id) {
|
||||
cb(node.id, node, state);
|
||||
}
|
||||
|
||||
11
test/fixtures/arrowfunction.js
vendored
Normal file
11
test/fixtures/arrowfunction.js
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Increment a number by 1.
|
||||
*
|
||||
* @param {number} n - The number to increment.
|
||||
*/
|
||||
var increment = n => n + 1;
|
||||
|
||||
/**
|
||||
* Print a value to the console.
|
||||
*/
|
||||
var print = (/** @type {*} */ val) => console.log(val);
|
||||
24
test/specs/documentation/arrowfunction.js
Normal file
24
test/specs/documentation/arrowfunction.js
Normal file
@ -0,0 +1,24 @@
|
||||
'use strict';
|
||||
|
||||
if (jasmine.jsParser !== 'rhino') {
|
||||
describe('arrow functions', function() {
|
||||
var docSet = jasmine.getDocSetFromFile('test/fixtures/arrowfunction.js');
|
||||
var increment = docSet.getByLongname('increment')[0];
|
||||
var print = docSet.getByLongname('print')[0];
|
||||
|
||||
it('should use the correct name and longname', function() {
|
||||
expect(increment).toBeDefined();
|
||||
expect(increment.name).toBe('increment');
|
||||
});
|
||||
|
||||
it('should allow function parameters to be documented', function() {
|
||||
expect(increment.params.length).toBe(1);
|
||||
expect(increment.params[0].name).toBe('n');
|
||||
});
|
||||
|
||||
it('should support inline comments on parameters', function() {
|
||||
expect(print.params.length).toBe(1);
|
||||
expect(print.params[0].type.names[0]).toBe('*');
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -14,6 +14,7 @@ describe('jsdoc/src/astNode', function() {
|
||||
|
||||
// create the AST nodes we'll be testing
|
||||
var arrayExpression = parse('[,]').body[0].expression;
|
||||
var arrowFunctionExpression = parse('var foo = () => {};').body[0].declarations[0].init;
|
||||
var assignmentExpression = parse('foo = 1;').body[0].expression;
|
||||
var binaryExpression = parse('foo & foo;').body[0].expression;
|
||||
var functionDeclaration1 = parse('function foo() {}').body[0];
|
||||
@ -28,6 +29,7 @@ describe('jsdoc/src/astNode', function() {
|
||||
var memberExpression = parse('foo.bar;').body[0].expression;
|
||||
var memberExpressionComputed1 = parse('foo["bar"];').body[0].expression;
|
||||
var memberExpressionComputed2 = parse('foo[\'bar\'];').body[0].expression;
|
||||
var methodDefinition = parse('class Foo { bar() {} }').body[0].body.body[0];
|
||||
var propertyGet = parse('var foo = { get bar() {} };').body[0].declarations[0].init
|
||||
.properties[0];
|
||||
var propertyInit = parse('var foo = { bar: {} };').body[0].declarations[0].init.properties[0];
|
||||
@ -65,6 +67,10 @@ describe('jsdoc/src/astNode', function() {
|
||||
expect(typeof astNode.isAssignment).toBe('function');
|
||||
});
|
||||
|
||||
it('should export an isFunction method', function() {
|
||||
expect(typeof astNode.isFunction).toBe('function');
|
||||
});
|
||||
|
||||
it('should export an isScope method', function() {
|
||||
expect(typeof astNode.isScope).toBe('function');
|
||||
});
|
||||
@ -489,6 +495,28 @@ describe('jsdoc/src/astNode', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('isFunction', function() {
|
||||
it('should recognize function declarations as functions', function() {
|
||||
expect( astNode.isFunction(functionDeclaration1) ).toBe(true);
|
||||
});
|
||||
|
||||
it('should recognize function expressions as functions', function() {
|
||||
expect( astNode.isFunction(functionExpression1) ).toBe(true);
|
||||
});
|
||||
|
||||
it('should recognize method definitions as functions', function() {
|
||||
expect( astNode.isFunction(methodDefinition) ).toBe(true);
|
||||
});
|
||||
|
||||
it('should recognize arrow function expressions as functions', function() {
|
||||
expect( astNode.isFunction(arrowFunctionExpression) ).toBe(true);
|
||||
});
|
||||
|
||||
it('should recognize non-functions', function() {
|
||||
expect( astNode.isFunction(arrayExpression) ).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('isScope', function() {
|
||||
it('should return false for undefined values', function() {
|
||||
expect( astNode.isScope() ).toBe(false);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user