From f9ee68d6e26086c3406ae2d856dbf9304333bbd1 Mon Sep 17 00:00:00 2001 From: Michael Mathews Date: Sun, 8 May 2011 23:43:33 +0100 Subject: [PATCH] Added support for anonymous functions assigned to var. --- node_modules/jsdoc/parser.js | 19 ++++++++++++----- templates/default/index.js | 7 +++++-- test/jsdoc_parser_function.js | 39 +++++++++++++++++++++++++++++++++-- 3 files changed, 56 insertions(+), 9 deletions(-) diff --git a/node_modules/jsdoc/parser.js b/node_modules/jsdoc/parser.js index c62a4fd1..9fd6c2ca 100644 --- a/node_modules/jsdoc/parser.js +++ b/node_modules/jsdoc/parser.js @@ -53,13 +53,23 @@ varDoc = null; } + if (child.initializer ) { + // like var foo = function + if ( typeToName(child.initializer.type) === 'FUNCTION' ) { + // treat this var node as a function + child.initializer.name = child.name; + return handle.FUNCTION( child.initializer ); + } + } + var namePath = path.join('') + (path.length?'~':'') + child.name; + symbols.push( defined(child.jsdoc)? new Doclet(child.jsdoc, {longname: namePath, kind: 'var'}) : new Doclet('', {longname: namePath, kind: 'var'}) ); - //console.log( '>>> variable '+namePath+(defined(child.jsdoc)? ' "'+child.jsdoc+'"' : '') ); + var children = walkable(child); if (children) { walk(children); } } @@ -82,13 +92,12 @@ }; function walk(ast) { -//console.log('walk('+ast.length+')'); var node = null, nodeType = -1; while (node = ast.shift()) { nodeType = typeToName(node.type); -//console.log('~>>>> nodeType: '+nodeType+' '+node.name); + if (handle.hasOwnProperty(nodeType) && typeof handle[nodeType] === 'function') { handle[nodeType](node); } @@ -102,7 +111,7 @@ } function walkable(node) { - //console.log('>>> getting walkables of: '+typeToName(node.type)+' '+node.name); + //console.log('>>> getting walkables of: '+typeToName(node.type)+' '+node.name); if ( defined(node.body) && defined(node.body.children) && node.body.children !== null) { //console.log('- has body/children'); return node.body.children; @@ -116,7 +125,7 @@ //console.log('- has initializer'); if (typeToName(node.initializer.type) === 'FUNCTION') { //console.log('- has function value'); - path.push('~'+node.name); + path.push((path.length?'~':'')+node.name); return(node.initializer.body.children); } else if (typeToName(node.initializer.type) === 'OBJECT_INIT') { diff --git a/templates/default/index.js b/templates/default/index.js index 18e309e5..3b2566ce 100644 --- a/templates/default/index.js +++ b/templates/default/index.js @@ -8,11 +8,14 @@ exports.publish = function(docDb) { var functions = find({'kind': 'function'}); //console.log(functions); - var data = {title: 'All Functions', functions: functions}; + var data = { + title: 'All Functions', + functions: functions + }; var template = '

<%= title %>

\n'; var output = ejs.render(template, {locals: data}); - return 'Hello: '+output; + return output; } \ No newline at end of file diff --git a/test/jsdoc_parser_function.js b/test/jsdoc_parser_function.js index 4d33c18b..1bbc2986 100644 --- a/test/jsdoc_parser_function.js +++ b/test/jsdoc_parser_function.js @@ -14,8 +14,8 @@ exports['A documented named function.'] = function(t) { var docs = parser.parse('/**@desc a function*/ function foo() {}'); t.equal( docs.length, 1, 'should result in 1 doc' ); t.equal( docs[0].longname, 'foo', 'should have a longname equal to the function name' ); - t.equal( typeof docs[0].jsdoc, 'object', 'should have a jsdoc set' ); - t.equal( docs[0].jsdoc.src, '@desc a function', 'should have a jsdoc equal to the preceding doc comment' ); + t.equal( typeof docs[0], 'object', 'should have a jsdoc set' ); + t.equal( docs[0].jsdoc, '@desc a function', 'should have a jsdoc equal to the preceding doc comment' ); t.done(); }; @@ -27,3 +27,38 @@ exports['A nested documented named function.'] = function(t) { t.done(); }; +exports['A nested documented named function.'] = function(t) { + t.expect(2); + var docs = parser.parse('function foo() { /**@desc a function*/ function bar() {} }'); + t.equal( docs.length, 2, 'should result in 2 docs' ); + t.equal( docs[1].longname, 'foo~bar', 'the inner function should have a longname equal to ~' ); + t.done(); +}; + +exports['An undocumented anonymous function.'] = function(t) { + t.expect(4); + var docs = parser.parse('var foo = function() {}'); + t.equal( docs.length, 1, 'should result in 1 doc' ); + t.equal( docs[0].longname, 'foo', 'should have a longname set' ); + t.equal( docs[0].kind, 'function', 'should have a kind set to function' ); + t.equal( docs[0].longname, 'foo', 'should have a longname equal to the function name' ); + t.done(); +}; + +exports['An undocumented anonymous function nested inside an undocumented anonymous function.'] = function(t) { + t.expect(3); + var docs = parser.parse('var foo = function() { var bar = function() {} }'); + t.equal( docs.length, 2, 'should result in 2 docs' ); + t.equal( typeof docs[1].longname, 'string', 'the inner function doc should have a longname set' ); + t.equal( docs[1].longname, 'foo~bar', 'should have a longname equal to ~' ); + t.done(); +}; + +exports['An anonymous function as a child of a var.'] = function(t) { + t.expect(3); + var docs = parser.parse('var x, foo = function() {}'); + t.equal( docs.length, 2, 'should result in 3 docs' ); + t.equal( docs[1].longname, 'foo', 'the inner function doc should have a longname set' ); + t.equal( docs[1].kind, 'function', 'should have a kind set to function' ); + t.done(); +}; \ No newline at end of file