diff --git a/main.js b/main.js index f43a66a8..4960341b 100644 --- a/main.js +++ b/main.js @@ -109,8 +109,7 @@ function main() { jsdoc = { opts: { parser: require('jsdoc/opts/parser'), - }, - docset: require('jsdoc/docset') + } }; try { @@ -156,7 +155,7 @@ function main() { sourceFiles = app.jsdoc.scanner.scan(env.opts._, (env.opts.recurse? 10 : undefined)); - require('jsdoc/src/handlers'); + require('jsdoc/src/handlers').attachTo(app.jsdoc.parser); docs = app.jsdoc.parser.parse(sourceFiles, env.opts.encoding); diff --git a/modules/jsdoc/docset.js b/modules/jsdoc/docset.js deleted file mode 100644 index 2dc3a84c..00000000 --- a/modules/jsdoc/docset.js +++ /dev/null @@ -1,37 +0,0 @@ -/** @module jsdoc/docset */ - -// TODO: this module is currently only ever used as a helper in the test runner -// Can it be refactored a=out of the source code? - -(function() { - var DocSet = exports.DocSet = function(doclets) { - this.doclets = doclets; - } - - DocSet.prototype.getByLongname = function(longname) { - return this.doclets.filter(function(doclet) { - return (doclet.longname || doclet.name) === longname; - }); - } - - DocSet.prototype.getByMemberof = function(memberof) { - return this.doclets.filter(function(doclet) { - return doclet.memberof === memberof; - }); - } - - DocSet.prototype.sortByLongname = function() { - this.doclets.sort(function(a, b) { - if(a.longname == b.longname) { - return 0; - } - - return (a.longname < b.longname)? -1 : 1; - }); - } - - DocSet.prototype.hasDoc = function(longname) { - return !! (this.getByLongname(longname)).length; - } - -})(); \ No newline at end of file diff --git a/modules/jsdoc/src/handlers.js b/modules/jsdoc/src/handlers.js index ba22c0ca..5de680d7 100644 --- a/modules/jsdoc/src/handlers.js +++ b/modules/jsdoc/src/handlers.js @@ -1,70 +1,74 @@ (function() { - var jsdoc = {doclet: require('jsdoc/doclet')}; - - // handles JSDoc comments that include a @name tag -- the code is ignored in such a case - app.jsdoc.parser.on('jsdocCommentFound', function(e) { - var newDoclet = new jsdoc.doclet.Doclet(e.comment, e); - if (!newDoclet.name) { - return false; // only interested in virtual comments (with a @name) here - } + exports.attachTo = function(parser) { + var jsdoc = {doclet: require('jsdoc/doclet')}; - addDoclet.call(this, newDoclet); - e.doclet = newDoclet; - }); - - // handles named symbols in the code, may or may not have a JSDoc comment attached - app.jsdoc.parser.on('symbolFound', function(e) { - var newDoclet = new jsdoc.doclet.Doclet(e.comment, e); - - // an undocumented symbol right after a virtual comment? rhino mistakenly connected the two - if (newDoclet.name) { // there was a @name in comment - // try again, without the comment - e.comment = '@undocumented'; - newDoclet = new jsdoc.doclet.Doclet(e.comment, e); - } - - // we need to get the symbol name from code - if (e.code && e.code.name) { - newDoclet.addTag('name', e.code.name); - - if (!newDoclet.memberof && e.astnode) { - var memberofName = this.astnodeToMemberof(e.astnode); - - if ( /^this\./.test(newDoclet.name) ) { - newDoclet.name = newDoclet.name.replace('this.', ''); - memberofName = this.resolveThis(e.astnode); - if (memberofName) { - newDoclet.name = memberofName + '#' + newDoclet.name; - } - } - - if (memberofName) newDoclet.addTag( 'memberof', memberofName); + // handles JSDoc comments that include a @name tag -- the code is ignored in such a case + parser.on('jsdocCommentFound', function(e) { + var newDoclet = new jsdoc.doclet.Doclet(e.comment, e); + if (!newDoclet.name) { + return false; // only interested in virtual comments (with a @name) here } - newDoclet.postProcess(); - } - else { - return false; - } + addDoclet.call(this, newDoclet); + e.doclet = newDoclet; + }); - addDoclet.call(this, newDoclet); - e.doclet = newDoclet; - }); - - //app.jsdoc.parser.on('fileBegin', function(e) { }); - - //app.jsdoc.parser.on('fileComplete', function(e) { }); - - function addDoclet(newDoclet) { - if (newDoclet) { - e = { doclet: newDoclet }; - this.fire('newDoclet', e); + // handles named symbols in the code, may or may not have a JSDoc comment attached + parser.on('symbolFound', function(e) { + var newDoclet = new jsdoc.doclet.Doclet(e.comment, e); - if (!e.defaultPrevented) { - this.addResult(newDoclet); + // an undocumented symbol right after a virtual comment? rhino mistakenly connected the two + if (newDoclet.name) { // there was a @name in comment + // try again, without the comment + e.comment = '@undocumented'; + newDoclet = new jsdoc.doclet.Doclet(e.comment, e); + } + + // we need to get the symbol name from code + if (e.code && e.code.name) { + newDoclet.addTag('name', e.code.name); + + if (!newDoclet.memberof && e.astnode) { + var memberofName; + + if ( /^this\./.test(newDoclet.name) ) { + newDoclet.name = newDoclet.name.replace('this.', ''); + memberofName = this.resolveThis(e.astnode); + if (memberofName) { + newDoclet.name = memberofName + '#' + newDoclet.name; + } + } + else { + memberofName = this.astnodeToMemberof(e.astnode); + } + + if (memberofName) { newDoclet.addTag( 'memberof', memberofName); } + } + + newDoclet.postProcess(); + } + else { + return false; + } + + addDoclet.call(this, newDoclet); + e.doclet = newDoclet; + }); + + //parser.on('fileBegin', function(e) { }); + + //parser.on('fileComplete', function(e) { }); + + function addDoclet(newDoclet) { + if (newDoclet) { + e = { doclet: newDoclet }; + this.fire('newDoclet', e); + + if (!e.defaultPrevented) { + this.addResult(newDoclet); + } } } } - })(); \ No newline at end of file diff --git a/modules/jsdoc/tagdictionary.js b/modules/jsdoc/tagdictionary.js deleted file mode 100644 index 3f5e5dca..00000000 --- a/modules/jsdoc/tagdictionary.js +++ /dev/null @@ -1,523 +0,0 @@ -/** - @overview Defines the various different types of tags recognized by JSDoc. - */ - -(function() { - /** - @module jsdoc/tagdictionary - */ - - /** @namespace - @inner - @member module:jsdoc/tagdictionary - */ - var tagDefinitions = {}; - - /** - Return a tag definition for the tag with the given title. - @param tagTitle Like "param" or "desc" - @returns {TagDefinition} The definition for that tag or an empty object. - */ - exports.lookUp = function(tagTitle) { - return tagDefinitions['@'+tagTitle] || {}; - } - - exports.synonyms = { - /*synonym => canonical*/ - 'desc': 'description', - 'function': 'method', - 'var': 'property', - 'field': 'property', - 'return': 'returns', - 'member': 'memberof', - 'overview': 'file', - 'fileoverview':'file', - 'const': 'constant', - 'augments': 'extends', - 'throws': 'exception', - 'class': 'classdesc', - 'this': 'thisobj', - 'preserve': 'ignore' - }; - - exports.resolveSynonyms = function(name) { - if ( exports.synonyms.hasOwnProperty(name) ) { - return exports.synonyms[name]; - } - else { - return name; - } - } - - /** - @deprecated - @memberOf module:jsdoc/tagdictionary - */ - function TagDefinition(title, opts) { - this.title = title; - - for (var p in opts) { - if (typeof opts[p] !== 'undefined') { - this[p] = opts[p]; - } - } - - tagDefinitions['@'+title] = this; - } - - // default properties of all tags - TagDefinition.prototype = { - isExported : false, // this tag should appear as a top level property in the doclet? - setsDocletKind : false, // the name of this tag is used to define the doclet's kind property - setsDocletDesc : false, - setsDocletName : false, // this tag can be used to name the doclet - setsDocletAttrib : false, // the name of this tag becomes the attribute of the doclet - setsDocletScope : false, - setsDocletType : false, // the type of this tag becomes th type of the doclet - setsDocletDocspace: false, // the name of this tag becomes the docspace for the doclet name, like "event:" - canHaveType : false, // this tag can have a {type} - canHavePname : false, // this tag can have a parameter-type name - canHavePdesc : false, // this tag can have a parameter-type desc - keepsWhitespace : false, // don't try to tidy up the whitespace in this tag? - impliesTag : false, // this tag implies another tag - isScalar : false, // can only have a single value (first wins) - forceArray : false, // must always be an array, - typeIsValue : false, - exportName : '' // what name will this tag be exported as (defaults to tag name) - }; - - /** Syntax: @access (private|public|protected) - @private - @property {module:jsdoc/tagdictionary~TagDefinition} access - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('access', { - isExported: true, - isScalar: true - }); - - /** Syntax: @scope (global|static|inner|instance) - @private - @property {module:jsdoc/tagdictionary~TagDefinition} scope - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('scope', { - isExported: true, - isScalar: true - }); - - /** Syntax: @description - @property {module:jsdoc/tagdictionary~TagDefinition} desc - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('description', { // t - isExported: true, - isScalar: true - }); - - /** Syntax: @kind - @private - @property {module:jsdoc/tagdictionary~TagDefinition} kind - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('kind', { - isExported: true, - isScalar: true - }); - - /** Syntax: @name - @property {module:jsdoc/tagdictionary~TagDefinition} name - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('name', { - isExported: true, - isScalar: true - }); - - /** Syntax: @path - @private - @property {module:jsdoc/tagdictionary~TagDefinition} path - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('path', { - isExported: true, - isScalar: true - }); - - /** Syntax: @memberOf - @property {module:jsdoc/tagdictionary~TagDefinition} memberof - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('memberof', { - isExported: true, - isScalar: true - }); - - /** Syntax: @namespace - @property {module:jsdoc/tagdictionary~TagDefinition} namespace - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('namespace', { - canHaveType: true, - setsDocletType: true, - setsDocletKind: true, - setsDocletName: true - }); - - /** Syntax: @constructor - @property {module:jsdoc/tagdictionary~TagDefinition} constructor - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('constructor', { - setsDocletKind: true, - setsDocletName: true - }); - - /** Syntax: @classdesc|class - @property {module:jsdoc/tagdictionary~TagDefinition} classdesc - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('classdesc', { - isExported: true, - impliesTag: 'constructor', - isScalar: true - }); - - /** Syntax: @constant|const - @property {module:jsdoc/tagdictionary~TagDefinition} constant - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('constant', { - canHaveType: true, - setsDocletType: true, - setsDocletKind: true, - setsDocletName: true - }); - - /** Syntax: @enum - @property {module:jsdoc/tagdictionary~TagDefinition} enum - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('enum', { - canHaveType: true, - setsDocletType: true, - setsDocletKind: true, - setsDocletName: true - }); - - /** Syntax: @file|overview|fileoverview - @property {module:jsdoc/tagdictionary~TagDefinition} file - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('file', { - setsDocletKind: true, - setsDocletDesc: true, - setsDocletName: true, - setsDocletDocspace: true, - impliesTag: 'scope global' - }); - - /** Syntax: @method|function - @property {module:jsdoc/tagdictionary~TagDefinition} method - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('method', { - canHaveType: true, - setsDocletKind: true, - canHavePname: true, - canHavePdesc: true, - setsDocletName: true - }); - - /** Syntax: @mixin - @property {module:jsdoc/tagdictionary~TagDefinition} mixin - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('mixin', { - setsDocletKind: true, - canHaveType: true, - canHavePname: true, - canHavePdesc: true, - setsDocletName: true, - setsDocletType: true - }); - - /** Syntax: @property|field|var - @property {module:jsdoc/tagdictionary~TagDefinition} property - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('property', { - setsDocletKind: true, - canHaveType: true, - canHavePname: true, - canHavePdesc: true, - setsDocletName: true, - setsDocletType: true - }); - - /** Syntax: @interface - @property {module:jsdoc/tagdictionary~TagDefinition} interface - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('interface', { - setsDocletKind: true, - canHaveType: true, - canHavePname: true, - canHavePdesc: true, - setsDocletName: true, - setsDocletType: true - }); - - /** Syntax: @event - @property {module:jsdoc/tagdictionary~TagDefinition} event - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('event', { - setsDocletKind: true, - setsDocletName: true, - setsDocletDocspace: true - }); - - /** Syntax: @module - @property {module:jsdoc/tagdictionary~TagDefinition} module - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('module', { - setsDocletKind: true, - setsDocletName: true, - setsDocletDocspace: true - }); - - /** Syntax: @example - @property {module:jsdoc/tagdictionary~TagDefinition} example - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('example', { - isExported: true, - keepsWhitespace: true - }); - - /** Syntax: @param - @property {module:jsdoc/tagdictionary~TagDefinition} param - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('param', { - isExported: true, - canHaveType: true, - canHavePname: true, - canHavePdesc: true, - forceArray: true - }); - - /** Syntax: @type - @property {module:jsdoc/tagdictionary~TagDefinition} type - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('type', { - isExported: true, - canHaveType: true, - typeIsValue: true - }); - - /** Syntax: @returns|return - @property {module:jsdoc/tagdictionary~TagDefinition} returns - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('returns', { - isExported: true, - canHaveType: true, - canHavePdesc: true, - isScalar: true - }); - - /** Syntax: @thisobj|this - @property {module:jsdoc/tagdictionary~TagDefinition} thisobj - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('thisobj', { - isExported: true, - canHaveType: true, - typeIsValue: true, - isScalar: true - }); - - /** Syntax: @attrib (readonly) - @private - @property {module:jsdoc/tagdictionary~TagDefinition} attrib - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('attrib', { - isExported: true - }); - - /** Syntax: @private - @property {module:jsdoc/tagdictionary~TagDefinition} private - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('private', { - setsDocletAccess: true - }); - - /** Syntax: @protected - @property {module:jsdoc/tagdictionary~TagDefinition} protected - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('protected', { - setsDocletAccess: true - }); - - /** Syntax: @public - @property {module:jsdoc/tagdictionary~TagDefinition} public - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('public', { - setsDocletAccess: true - }); - - /** Syntax: @readonly - @property {module:jsdoc/tagdictionary~TagDefinition} readonly - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('readonly', { - setsDocletAttrib: true - }); - - /** Syntax: @inner - @property {module:jsdoc/tagdictionary~TagDefinition} inner - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('inner', { - setsDocletScope: true - }); - - /** Syntax: @static - @property {module:jsdoc/tagdictionary~TagDefinition} static - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('static', { - setsDocletScope: true - }); - - /** Syntax: @global - @property {module:jsdoc/tagdictionary~TagDefinition} global - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('global', { - setsDocletScope: true - }); - - /** Syntax: @instance - @property {module:jsdoc/tagdictionary~TagDefinition} instance - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('instance', { - setsDocletScope: true - }); - - /** Syntax: @exception|throws {type} - @property {module:jsdoc/tagdictionary~TagDefinition} exception - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('exception', { - isExported: true, - canHaveType: true, - canHavePdesc: true - }); - - /** Syntax: @fires - @property {module:jsdoc/tagdictionary~TagDefinition} fires - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('fires', { - isExported: true - }); - - /** Syntax: @extends|augments - @property {module:jsdoc/tagdictionary~TagDefinition} extends - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('extends', { - isExported: true - }); - - /** Syntax: @author - @property {module:jsdoc/tagdictionary~TagDefinition} author - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('author', { - isExported: true - }); - - /** Syntax: @since - @property {module:jsdoc/tagdictionary~TagDefinition} since - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('since', { - isExported: true, - isScalar: true - }); - - /** Syntax: @version - - @property {module:jsdoc/tagdictionary~TagDefinition} version - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('version', { - isExported: true, - isScalar: true - }); - - /** Syntax: @requires - @property {module:jsdoc/tagdictionary~TagDefinition} requires - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('requires', { - isExported: true - }); - - /** Syntax: @tag - @property {module:jsdoc/tagdictionary~TagDefinition} tag - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('tag', { - isExported: true, - exportName: 'tags', - forceArray: true - }); - - /** Syntax: @deprecated - @property {module:jsdoc/tagdictionary~TagDefinition} deprecated - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('deprecated', { - isExported: true, - isScalar: true - }); - - /** Syntax: @see - @property {module:jsdoc/tagdictionary~TagDefinition} see - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('see', { - isExported: true - }); - - /** Syntax: @refersto - @property {module:jsdoc/tagdictionary~TagDefinition} refersto - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('refersto', { - isExported: true, - isScalar: true - }); - - /** Syntax: @implements - @property {module:jsdoc/tagdictionary~TagDefinition} implements - @memberOf module:jsdoc/tagdictionary~tagDefinitions - */ - new TagDefinition('implements', { - isExported: true, - canHaveType: true, - typeIsValue: true - }); -})(); \ No newline at end of file diff --git a/test/runner.js b/test/runner.js index 5ff0f37b..14e21e56 100644 --- a/test/runner.js +++ b/test/runner.js @@ -36,13 +36,23 @@ function report() { var testhelpers = { getDocSetFromFile: function(filename) { var sourceCode = readFile(BASEDIR + filename), - docs; + testParser, + doclets; - app.jsdoc.parser = new (require('jsdoc/src/parser')).Parser(); - require('jsdoc/src/handlers'); - docs = app.jsdoc.parser.parse('javascript:' + sourceCode); + testParser = new (require('jsdoc/src/parser')).Parser(); + require('jsdoc/src/handlers').attachTo(testParser); - return new (require('jsdoc/docset')).DocSet(docs); + doclets = testParser.parse('javascript:' + sourceCode); + + + return { + doclets: doclets, + getByLongname: function(longname) { + return doclets.filter(function(doclet) { + return (doclet.longname || doclet.name) === longname; + }); + } + }; } }; @@ -53,6 +63,7 @@ testFile('test/t/common/query.js'); testFile('test/t/jsdoc/opts/parser.js'); testFile('test/t/jsdoc/src/parser.js'); +testFile('test/t/jsdoc/src/handlers.js'); testFile('test/t/jsdoc/name.js'); testFile('test/t/cases/file.js'); diff --git a/test/t/cases/file.js b/test/t/cases/file.js index 12002e47..94fd7e66 100644 --- a/test/t/cases/file.js +++ b/test/t/cases/file.js @@ -4,7 +4,7 @@ app.jsdoc.parser = new srcParser.Parser(); - require('jsdoc/src/handlers'); + require('jsdoc/src/handlers').attachTo(app.jsdoc.parser); doclets = app.jsdoc.parser.parse(BASEDIR + 'test/cases/file.js') diff --git a/test/t/jsdoc/src/handlers.js b/test/t/jsdoc/src/handlers.js new file mode 100644 index 00000000..7121d605 --- /dev/null +++ b/test/t/jsdoc/src/handlers.js @@ -0,0 +1,16 @@ +(function() { + + var jsdoc = {src: { parser: require('jsdoc/src/parser')}}, + testParser = new jsdoc.src.parser.Parser(); + + require('jsdoc/src/handlers').attachTo(testParser); + + test('A jsdoc comment with a @name and no code is turned into a doclet object.', function() { + var sourceCode = 'javascript:/** @name bar */', + result = testParser.parse(sourceCode); + + assert.equal(result.length, 1); + assert.equal(result[0].name, 'bar'); + }); + +})(); \ No newline at end of file