From 5c69bbd28924bbd140c8649297b921394eb5be7e Mon Sep 17 00:00:00 2001 From: Jeff Williams Date: Thu, 18 Apr 2013 16:13:34 -0700 Subject: [PATCH] cleanup --- lib/jsdoc/src/parser.js | 180 ++++++++++++++++++++++++++-------------- 1 file changed, 116 insertions(+), 64 deletions(-) diff --git a/lib/jsdoc/src/parser.js b/lib/jsdoc/src/parser.js index 4d5dca04..4bfec760 100644 --- a/lib/jsdoc/src/parser.js +++ b/lib/jsdoc/src/parser.js @@ -53,13 +53,15 @@ exports.Parser.prototype.parse = function(sourceFiles, encoding) { var parsedFiles = []; var e = {}; - if (typeof sourceFiles === 'string') { sourceFiles = [sourceFiles]; } + if (typeof sourceFiles === 'string') { + sourceFiles = [sourceFiles]; + } e.sourcefiles = sourceFiles; this.emit('parseBegin', e); - for (var i = 0, leni = sourceFiles.length; i < leni; i++) { + for (var i = 0, l = sourceFiles.length; i < l; i++) { sourceCode = ''; if (sourceFiles[i].indexOf(SCHEMA) === 0) { @@ -72,7 +74,8 @@ exports.Parser.prototype.parse = function(sourceFiles, encoding) { sourceCode = require('jsdoc/fs').readFileSync(filename, encoding); } catch(e) { - console.log('FILE READ ERROR: in module:jsdoc/parser.parseFiles: "' + filename + '" ' + e); + console.log('FILE READ ERROR: in module:jsdoc/parser.parseFiles: "' + filename + + '" ' + e); continue; } } @@ -83,7 +86,9 @@ exports.Parser.prototype.parse = function(sourceFiles, encoding) { } } - this.emit('parseComplete', {sourcefiles: parsedFiles}); + this.emit('parseComplete', { + sourcefiles: parsedFiles + }); return this._resultBuffer; }; @@ -131,12 +136,17 @@ function pretreat(code) { // merge adjacent doclets .replace(/\*\/\/\*\*+/g, '@also') - // make lent objectliterals documentable by giving them a dummy name - .replace(/(\/\*\*[^\*\/]*?[\*\s]*@lends\s(?:[^\*]|\*(?!\/))*\*\/\s*)\{/g, '$1 ____ = {') // like return @lends { - .replace(/(\/\*\*[^\*\/]*?@lends\b[^\*\/]*?\*\/)(\s*)return(\s*)\{/g, '$2$3 return $1 ____ = {'); // like @lends return { + // make lent object literals documentable by giving them a dummy name + // like return @lends { + .replace(/(\/\*\*[^\*\/]*?[\*\s]*@lends\s(?:[^\*]|\*(?!\/))*\*\/\s*)\{/g, '$1 ____ = {') + // like @lends return { + .replace(/(\/\*\*[^\*\/]*?@lends\b[^\*\/]*?\*\/)(\s*)return(\s*)\{/g, + '$2$3 return $1 ____ = {'); } -var tkn = { NAMEDFUNCTIONSTATEMENT: -1001 }; +var tkn = { + NAMEDFUNCTIONSTATEMENT: -1001 +}; exports.Parser.tkn = tkn; /** @private */ @@ -159,7 +169,7 @@ function getTypeName(node) { var type = ''; if (node) { - type = ''+ Packages.org.mozilla.javascript.Token.typeToName(node.getType()); + type = '' + Packages.org.mozilla.javascript.Token.typeToName(node.getType()); } return type; @@ -171,7 +181,9 @@ function getTypeName(node) { function nodeToString(node) { var str; - if (!node) { return; } + if (!node) { + return; + } if (node.type === Token.GETPROP) { str = [nodeToString(node.target), node.property.string].join('.'); @@ -276,8 +288,8 @@ function aboutNode(node) { if (typeof paramCount === 'number') { about.node.flattenSymbolTable(true); var paramNames = []; - for (var i = 0, len = paramCount; i < len; i++) { - paramNames.push(''+about.node.getParamOrVarName(i)); + for (var i = 0, l = paramCount; i < l; i++) { + paramNames.push( '' + about.node.getParamOrVarName(i) ); } about.paramnames = paramNames; } @@ -290,20 +302,20 @@ function aboutNode(node) { @memberof module:src/parser.Parser */ function isValidJsdoc(commentSrc) { - return commentSrc && commentSrc.indexOf('/***') !== 0; /*** ignore comments that start with many stars ***/ + /*** ignore comments that start with many stars ***/ + return commentSrc && commentSrc.indexOf('/***') !== 0; } /** @private * @memberof module:src/parser.Parser */ function makeVarsFinisher(funcDoc) { - var func = function(e) { + return function(e) { //no need to evaluate all things related to funcDoc again, just use it if (funcDoc && e.doclet && e.doclet.alias) { funcDoc.meta.vars[e.code.name] = e.doclet.longname; } }; - return func; } /** @private @@ -373,11 +385,13 @@ exports.Parser.prototype._makeEvent = function(node, comments, extras) { */ exports.Parser.prototype._trackVars = function(node, e) { // keep track of vars in a function or global scope - var func = "__global__"; + var func = '__global__'; var funcDoc = null; + if (node.enclosingFunction) { - func = 'astnode'+node.enclosingFunction.hashCode(); + func = 'astnode' + node.enclosingFunction.hashCode(); } + funcDoc = this.refs[func]; if (funcDoc) { funcDoc.meta.vars = funcDoc.meta.vars || {}; @@ -448,7 +462,7 @@ exports.Parser.prototype._visitNode = function(comments, node) { } else if (node.type === Token.GETPROP) { // like 'obj.prop' in '/** @typedef {string} */ obj.prop;' // this COULD be a Closure Compiler-style typedef, but it's probably not; to avoid filling - // the parse tree with junk, only fire an event if there's a JSDoc comment attached + // the parse results with junk, only fire an event if there's a JSDoc comment attached extras = { lineno: node.getLineno() }; @@ -465,7 +479,6 @@ exports.Parser.prototype._visitNode = function(comments, node) { if (node.parent.variables.toArray()[0] === node) { // like /** blah */ var a=1, b=2, c=3; // the first var assignment gets any jsDoc before the whole var series if (typeof node.setJsDoc !== 'undefined') { node.setJsDoc( node.parent.getJsDoc() ); } - //node.jsDoc = node.parent.jsDoc; } extras = { @@ -489,8 +502,13 @@ exports.Parser.prototype._visitNode = function(comments, node) { e.code.funcscope = this.resolveVar(node, basename); } - if (!e) { e = {finishers: []}; } - for(i = 0, l = this._visitors.length; i < l; i++) { + if (!e) { + e = { + finishers: [] + }; + } + + for (i = 0, l = this._visitors.length; i < l; i++) { this._visitors[i].visitNode(node, e, this, this._currentSourceName); if (e.stopPropagation) { break; } } @@ -511,13 +529,21 @@ exports.Parser.prototype._parseSourceCode = function(sourceCode, sourceName) { var NodeVisitor = Packages.org.mozilla.javascript.ast.NodeVisitor; var ast; - var comments = {original: [], modified: []}; - var e = {filename: sourceName}; + var comments = { + original: [], + modified: [] + }; + var e = { + filename: sourceName + }; this.emit('fileBegin', e); if (!e.defaultPrevented) { - e = {filename: sourceName, source: sourceCode}; + e = { + filename: sourceName, + source: sourceCode + }; this.emit('beforeParse', e); sourceCode = e.source; this._currentSourceName = sourceName = e.filename; @@ -554,25 +580,27 @@ exports.Parser.prototype.astnodeToMemberof = function(node) { doclet, alias; - if (node.type === Token.VAR || node.type === Token.FUNCTION || node.type == tkn.NAMEDFUNCTIONSTATEMENT) { + if (node.type === Token.VAR || node.type === Token.FUNCTION || + node.type == tkn.NAMEDFUNCTIONSTATEMENT) { if (node.enclosingFunction) { // an inner var or func - id = 'astnode'+node.enclosingFunction.hashCode(); + id = 'astnode' + node.enclosingFunction.hashCode(); doclet = this.refs[id]; if (!doclet) { return '~'; } - return (doclet.longname||doclet.name) + '~'; + return (doclet.longname || doclet.name) + '~'; } } else { - //check local references for aliases + // check local references for aliases var scope = node, basename = getBasename(nodeToString(node.left)); while(scope.enclosingFunction) { - id = 'astnode'+scope.enclosingFunction.hashCode(); + id = 'astnode' + scope.enclosingFunction.hashCode(); doclet = this.refs[id]; if (doclet && doclet.meta.vars && basename in doclet.meta.vars) { - alias = hasOwnProp.call(doclet.meta.vars, basename)? doclet.meta.vars[basename] : false; + alias = hasOwnProp.call(doclet.meta.vars, basename) ? + doclet.meta.vars[basename] : false; if (alias !== false) { return [alias, basename]; } @@ -580,35 +608,36 @@ exports.Parser.prototype.astnodeToMemberof = function(node) { // move up scope = scope.enclosingFunction; } - //First check to see if we have a global scope alias + // First check to see if we have a global scope alias doclet = this.refs.__global__; - if (doclet && doclet.meta.vars && hasOwnProp.call(doclet.meta.vars, basename)) { + if ( doclet && doclet.meta.vars && hasOwnProp.call(doclet.meta.vars, basename) ) { alias = doclet.meta.vars[basename]; if (alias !== false) { return [alias, basename]; } } - id = 'astnode'+node.parent.hashCode(); + id = 'astnode' + node.parent.hashCode(); doclet = this.refs[id]; if (!doclet) { return ''; // global? } - return doclet.longname||doclet.name; + return doclet.longname || doclet.name; } }; /** - * Resolve what "this" refers too, relative to a node. + * Resolve what "this" refers to relative to a node. * @param {astnode} node - The "this" node * @returns {string} The longname of the enclosing node. */ exports.Parser.prototype.resolveThis = function(node) { var memberof = {}; + var parent; if (node.type !== Token.COLON && node.enclosingFunction) { // get documentation for the enclosing function - memberof.id = 'astnode'+node.enclosingFunction.hashCode(); + memberof.id = 'astnode' + node.enclosingFunction.hashCode(); memberof.doclet = this.refs[memberof.id]; if (!memberof.doclet) { @@ -624,7 +653,7 @@ exports.Parser.prototype.resolveThis = function(node) { } // walk up to the closest class we can find else if (memberof.doclet.kind === 'class' || memberof.doclet.kind === 'module') { - return memberof.doclet.longname||memberof.doclet.name; + return memberof.doclet.longname || memberof.doclet.name; } else { if (node.enclosingFunction){ @@ -637,18 +666,21 @@ exports.Parser.prototype.resolveThis = function(node) { } } else if (node.parent) { - var parent = node.parent; - if (parent.type === Token.COLON) { - parent = parent.parent; // go up one more + if (node.parent.type === Token.COLON) { + parent = node.parent.parent; + } + else { + parent = node.parent; } - memberof.id = 'astnode'+parent.hashCode(); + memberof.id = 'astnode' + parent.hashCode(); memberof.doclet = this.refs[memberof.id]; + if (!memberof.doclet) { return ''; // global? } - return memberof.doclet.longname||memberof.doclet.name; + return memberof.doclet.longname || memberof.doclet.name; } else { return ''; // global? @@ -656,21 +688,26 @@ exports.Parser.prototype.resolveThis = function(node) { }; /** - Given: foo = { x:1 }, find foo from x. + * Given 'var foo = { x: 1 }', find foo from x. */ exports.Parser.prototype.resolvePropertyParent = function(node) { var memberof = {}; + var parent; - if (node.parent) { - var parent = node.parent; - if (parent.type === Token.COLON) { - parent = parent.parent; // go up one more - } + if (node.parent && node.parent.type === Token.COLON) { + parent = node.parent.parent; + } + else { + parent = node.parent; + } - memberof.id = 'astnode'+parent.hashCode(); + if (parent) { + memberof.id = 'astnode' + parent.hashCode(); memberof.doclet = this.refs[memberof.id]; - if (memberof.doclet) { return memberof; } + if (memberof.doclet) { + return memberof; + } } }; @@ -680,13 +717,15 @@ exports.Parser.prototype.resolvePropertyParent = function(node) { * @param {string} basename The leftmost name in the long name: in foo.bar.zip the basename is foo. */ exports.Parser.prototype.resolveVar = function(node, basename) { - var doclet, - enclosingFunction = node.enclosingFunction; + var doclet; + var enclosingFunction = node.enclosingFunction; + + if (!enclosingFunction) { + return ''; // global + } - if (!enclosingFunction) { return ''; } // global doclet = this.refs['astnode'+enclosingFunction.hashCode()]; - - if ( doclet && doclet.meta.vars && basename in doclet.meta.vars ) { + if (doclet && doclet.meta.vars && basename in doclet.meta.vars) { return doclet.longname; } @@ -695,29 +734,42 @@ exports.Parser.prototype.resolveVar = function(node, basename) { exports.Parser.prototype.addDocletRef = function(e) { var node = e.code.node; + // allow lookup from value => doclet if (e.doclet) { - this.refs['astnode'+node.hashCode()] = e.doclet; // allow lookup from value => doclet + this.refs['astnode' + node.hashCode()] = e.doclet; } - else if ((node.type == Token.FUNCTION || node.type == tkn.NAMEDFUNCTIONSTATEMENT) && !this.refs['astnode'+node.hashCode()]) { // keep references to undocumented anonymous functions too as they might have scoped vars - this.refs['astnode'+node.hashCode()] = { + // keep references to undocumented anonymous functions, too, as they might have scoped vars + else if ((node.type == Token.FUNCTION || node.type == tkn.NAMEDFUNCTIONSTATEMENT) && + !this.refs['astnode' + node.hashCode()]) { + this.refs['astnode' + node.hashCode()] = { longname: '', - meta: { code: e.code } + meta: { + code: e.code + } }; } }; exports.Parser.prototype.resolveEnum = function(e) { - var doop = require("jsdoc/util/doop").doop, - parent = this.resolvePropertyParent(e.code.node); + var parent = this.resolvePropertyParent(e.code.node); + if (parent && parent.doclet.isEnum) { - if (!parent.doclet.properties) { parent.doclet.properties = []; } + if (!parent.doclet.properties) { + parent.doclet.properties = []; + } + // members of an enum inherit the enum's type - if (parent.doclet.type && !e.doclet.type) { e.doclet.type = doop(parent.doclet.type); } + if (parent.doclet.type && !e.doclet.type) { + e.doclet.type = parent.doclet.type; + + } + delete e.doclet.undocumented; e.doclet.defaultvalue = e.doclet.meta.code.value; + // add the doclet to the parent's properties // use a copy of the doclet to avoid circular references - parent.doclet.properties.push( doop(e.doclet) ); + parent.doclet.properties.push( require('jsdoc/util/doop').doop(e.doclet) ); } };