Merge pull request #139 from hegemonic/77f505f2a16b3cde0c9cad966b610abfac111b29

Make JSDoc JSHint-clean (part 1)
This commit is contained in:
Michael Mathews 2012-07-04 16:10:15 -07:00
commit 5321ee903f
27 changed files with 4966 additions and 269 deletions

60
.jshintrc Normal file
View File

@ -0,0 +1,60 @@
{
"bitwise": false,
"curly": false,
"eqeqeq": false,
"forin": false,
"immed": false,
"latedef": false,
"newcap": false,
"noarg": false,
"noempty": false,
"nonew": false,
"plusplus": false,
"regexp": false,
"undef": false,
"strict": false,
"trailing": false,
"asi": true,
"boss": true,
"debug": true,
"eqnull": true,
"es5": true,
"esnext": true,
"evil": true,
"expr": true,
"funcscope": true,
"globalstrict": true,
"iterator": true,
"lastsemic": true,
"laxbreak": true,
"laxcomma": true,
"loopfunc": true,
"multistr": true,
"onecase": true,
"proto": true,
"regexdash": true,
"scripturl": true,
"shadow": true,
"smarttabs": true,
"sub": true,
"supernew": true,
"validthis": true,
"browser": false,
"couch": false,
"devel": false,
"dojo": false,
"jquery": false,
"mootools": false,
"node": true,
"nonstandard": false,
"prototypejs": false,
"rhino": true,
"wsh": false,
"nomen": false,
"onevar": false,
"passfail": false,
"white": false
}

View File

@ -8,33 +8,6 @@
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
/** The absolute path to the base directory of the jsdoc application.
@type string
@global
*/
__dirname = '.',
args = Array.prototype.slice.call(arguments, 0);
// rhino has no native way to get the base dirname of the currently running script
// so this information must be manually passed in from the command line
for (var i = 0; i < args.length; i++) {
if ( /^--dirname(?:=(.+?)(\/|\/\.)?)?$/i.test(args[i]) ) {
if (RegExp.$1) {
__dirname = RegExp.$1; // last wins
args.splice(i--, 1); // remove --dirname opt from arguments
}
else {
__dirname = args[i + 1];
args.splice(i--, 2);
}
}
}
load(__dirname + '/lib/rhino-shim.js');
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
/** Data representing the environment in which this app is running.
@namespace
*/
@ -49,8 +22,7 @@ env = {
The command line arguments passed into jsdoc.
@type Array
*/
args: Array.prototype.slice.call(args, 0),
args: [],
/**
The parsed JSON data from the configuration file.
@ -58,6 +30,12 @@ env = {
*/
conf: {},
/**
The absolute path to the base directory of the jsdoc application.
@type string
*/
dirname: '.',
/**
The command line arguments, parsed into a key/value hash.
@type Object
@ -66,6 +44,29 @@ env = {
opts: {}
};
args = Array.prototype.slice.call(arguments, 0);
// rhino has no native way to get the base dirname of the currently running script
// so this information must be manually passed in from the command line
for (var i = 0; i < args.length; i++) {
if ( /^--dirname(?:=(.+?)(\/|\/\.)?)?$/i.test(args[i]) ) {
if (RegExp.$1) {
env.dirname = RegExp.$1; // last wins
args.splice(i--, 1); // remove --dirname opt from arguments
}
else {
env.dirname = args[i + 1];
args.splice(i--, 2);
}
}
}
env.args = args;
load(env.dirname + '/lib/rhino-shim.js');
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
/** @global
@param {string} filepath The path to the script file to include (read and execute).
@ -76,7 +77,7 @@ function include(filepath) {
load(filepath);
}
catch (e) {
console.log('Cannot include "' + __dirname + '/' + filepath + '": '+e);
console.log('Cannot include "' + env.dirname + '/' + filepath + '": '+e);
}
}
include.resolve = function(filepath) {
@ -84,7 +85,7 @@ include.resolve = function(filepath) {
return filepath;
}
return __dirname + '/' + filepath;
return env.dirname + '/' + filepath;
}
@ -166,6 +167,20 @@ function installPlugins(plugins, p) {
}
}
function indexAll(docs) {
var lookupTable = {},
hasOwnProp = Object.prototype.hasOwnProperty;
docs.forEach(function(doc) {
if ( !hasOwnProp.call(lookupTable, doc.longname) ) {
lookupTable[doc.longname] = [];
}
lookupTable[doc.longname].push(doc);
});
docs.index = lookupTable;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
@ -188,13 +203,13 @@ function main() {
env.opts = jsdoc.opts.parser.parse(env.args);
try {
env.conf = new Config( fs.readFileSync( env.opts.configure || __dirname + '/conf.json' ) ).get();
env.conf = new Config( fs.readFileSync( env.opts.configure || env.dirname + '/conf.json' ) ).get();
}
catch (e) {
try {
//Try to copy over the example conf
var example = fs.readFileSync(__dirname + '/conf.json.EXAMPLE', 'utf8');
fs.writeFileSync(__dirname + '/conf.json', example, 'utf8');
var example = fs.readFileSync(env.dirname + '/conf.json.EXAMPLE', 'utf8');
fs.writeFileSync(env.dirname + '/conf.json', example, 'utf8');
env.conf = JSON.parse(example);
}
catch(e) {
@ -270,19 +285,6 @@ function main() {
packageDocs.files = sourceFiles || [];
docs.push(packageDocs);
function indexAll(docs) {
var lookupTable = {},
hasOwnProperty = Object.prototype.hasOwnProperty;
docs.forEach(function(doc) {
if ( !hasOwnProperty.call(lookupTable, doc.longname) ) {
lookupTable[doc.longname] = [];
}
lookupTable[doc.longname].push(doc);
});
docs.index = lookupTable;
}
indexAll(docs);
require('jsdoc/augment').addInherited(docs);

View File

@ -31,5 +31,5 @@ process = {
n = n || 0;
java.lang.System.exit(n);
},
argv: [__dirname + '/jsdoc.js'].concat(Array.prototype.slice.call(arguments, 0))
argv: [env.dirname + '/jsdoc.js'].concat(Array.prototype.slice.call(arguments, 0))
};

4557
node_modules/jshint/jshint.js generated vendored Executable file

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,7 @@ describe("railsTemplate plugin", function() {
it("should remove <% %> rails template tags from the source of *.erb files", function() {
var path = require("path"),
docSet = parser.parse([path.join(__dirname, "plugins/test/fixtures/railsTemplate.js.erb")]);
docSet = parser.parse([path.join(env.dirname, "plugins/test/fixtures/railsTemplate.js.erb")]);
expect(docSet[2].description).toEqual("Remove rails tags from the source input (e.g. )");
});

View File

@ -1,7 +1,7 @@
var doop = require("jsdoc/util/doop").doop;
(function() {
var hasOwnProperty = Object.prototype.hasOwnProperty;
var hasOwnProp = Object.prototype.hasOwnProperty;
exports.addInherited = function(docs) {
var dependencies = mapDependencies(docs.index);
@ -11,7 +11,7 @@ var doop = require("jsdoc/util/doop").doop;
var additions = getAdditions(doclets, docs);
additions.forEach(function(doc) {
var name = doc.longname;
if ( !hasOwnProperty.call(docs.index, name) ) {
if ( !hasOwnProp.call(docs.index, name) ) {
docs.index[name] = [];
}
docs.index[name].push(doc);
@ -104,7 +104,7 @@ var doop = require("jsdoc/util/doop").doop;
function sort(dependencies) {
var sorter = new Sorter(dependencies);
return sorter.sort();
};
}
})();

View File

@ -269,8 +269,8 @@ function toTags(docletSrc) {
docletSrc = unwrap(docletSrc);
tagSrcs = split(docletSrc);
for each(tagSrc in tagSrcs) {
tags.push( {title: tagSrc.title, text: tagSrc.text} );
for (var i = 0, l = tagSrcs.length; i < l; i++) {
tags.push( {title: tagSrcs[i].title, text: tagSrcs[i].text} );
}
return tags;
@ -312,7 +312,9 @@ function split(docletSrc) {
var parsedTag = $.match(/^(\S+)(:?\s+(\S[\s\S]*))?/);
if (parsedTag) {
var [, tagTitle, tagText] = parsedTag;
// we don't need parsedTag[0]
tagTitle = parsedTag[1];
tagText = parsedTag[2];
if (tagTitle) {
tagSrcs.push({

View File

@ -228,7 +228,7 @@ exports.splitName = function(nameDesc) {
if (!inQuote) {
if ( /\s/.test(thisChar) ) {
desc = nameDesc.substr(i);
desc = desc.replace(/^[\s-\s]+/, '').trim();
desc = desc.replace(/^[\s\-\s]+/, '').trim();
break;
}
else {

View File

@ -17,7 +17,7 @@ var argParser = new common.args.ArgParser(),
};
argParser.addOption('t', 'template', true, 'The name of the template to use. Default: the "default" template');
argParser.addOption('c', 'configure', true, 'The path to the configuration file. Default: jsdoc __dirname + /conf.json');
argParser.addOption('c', 'configure', true, 'The path to the configuration file. Default: jsdoc env.dirname + /conf.json');
argParser.addOption('e', 'encoding', true, 'Assume this encoding when reading all source files. Default: utf-8');
argParser.addOption('T', 'test', false, 'Run all tests and quit.');
argParser.addOption('d', 'destination', true, 'The path to the output folder. Use "console" to dump data to the console. Default: console');

View File

@ -1,8 +1,8 @@
/**
@overview Schema for validating JSON produced by JSDoc Toolkit.
@author Michael Mathews <micmath@gmail.com>
@license Apache License 2.0 - See file 'LICENSE.md' in this project.
@see <http://tools.ietf.org/html/draft-zyp-json-schema-02>
@overview Schema for validating JSON produced by JSDoc Toolkit.
@author Michael Mathews <micmath@gmail.com>
@license Apache License 2.0 - See file 'LICENSE.md' in this project.
@see <http://tools.ietf.org/html/draft-zyp-json-schema-02>
*/
exports.jsdocSchema = {
@ -11,9 +11,9 @@ exports.jsdocSchema = {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"additionalProperties": false,
"properties": {
"author": {
"author": {
"type": ["string", "array"],
"optional": true,
"items": {
@ -62,10 +62,10 @@ exports.jsdocSchema = {
"type": "string"
}
},
"deprecated": { // is usage of this symbol deprecated?
"type": ["string", "boolean"],
"optional": true
},
"deprecated": { // is usage of this symbol deprecated?
"type": ["string", "boolean"],
"optional": true
},
"scope": { // how is this symbol attached to it's enclosing scope?
"type": "string",
"maxItems": 1,
@ -98,7 +98,7 @@ exports.jsdocSchema = {
}
},
"implements": {
"type": ["string", "array"],
"type": ["string", "array"],
"optional": true,
"items": {
"type": "string"
@ -137,40 +137,40 @@ exports.jsdocSchema = {
}
},
"exception" : {
"optional": true,
"type": "object",
"properties": {
"type": { // what is the type of the value thrown?
"type": "array",
"optional": true,
"items": {
"type": "string"
}
},
"description": { // a description of the thrown value
"type": "string",
"optional": true
}
},
"additionalProperties": false
"optional": true,
"type": "object",
"properties": {
"type": { // what is the type of the value thrown?
"type": "array",
"optional": true,
"items": {
"type": "string"
}
},
"description": { // a description of the thrown value
"type": "string",
"optional": true
}
},
"additionalProperties": false
},
"returns" : {
"optional": true,
"type": "object",
"properties": {
"type": { // what is the type of the value returned?
"type": ["string", "array"],
"optional": true,
"items": {
"type": "string"
}
},
"description": { // a description of the returned value
"type": "string",
"optional": true
}
},
"additionalProperties": false
"optional": true,
"type": "object",
"properties": {
"type": { // what is the type of the value returned?
"type": ["string", "array"],
"optional": true,
"items": {
"type": "string"
}
},
"description": { // a description of the returned value
"type": "string",
"optional": true
}
},
"additionalProperties": false
},
"param" : { // are there function parameters associated with this doc?
"type": "array",
@ -207,11 +207,11 @@ exports.jsdocSchema = {
"optional": true
}
},
"additionalProperties": false
"additionalProperties": false
}
},
"thisobj": {
"type": ["string", "array"],
"type": ["string", "array"],
"optional": true,
"items": {
"type": "string"
@ -237,18 +237,18 @@ exports.jsdocSchema = {
"optional": true,
"maxItems": 1,
"properties": {
"file": { // what is the name of the file this doc appears in?
"type": "string",
"optional": true,
"maxItems": 1
},
"line": { // on what line of the file does this doc appear?
"type": "number",
"optional": true,
"maxItems": 1
}
},
"additionalProperties": false
"file": { // what is the name of the file this doc appears in?
"type": "string",
"optional": true,
"maxItems": 1
},
"line": { // on what line of the file does this doc appear?
"type": "number",
"optional": true,
"maxItems": 1
}
},
"additionalProperties": false
}
}
}
@ -258,51 +258,51 @@ exports.jsdocSchema = {
"optional": true,
"maxItems": 1,
"properties": {
"project": { // to what project does this doc belong?
"type": "object",
"optional": true,
"maxItems": 1,
"properties": {
"name": { // the name of the project
"type": "string",
"maxItems": 1
},
"uri": { // the URI of the project
"type": "string",
"maxItems": 1,
"format": "uri"
},
"version": { // the version of the project
"type": "string",
"maxItems": 1
},
"lang": { // the programming language used in the project
"type": "string",
"maxItems": 1
}
},
"additionalProperties": false
},
"generated": { // some information about the running of the doc generator
"type": "object",
"optional": true,
"maxItems": 1,
"properties": {
"date": { // on what date and time was the doc generated?
"type": "string",
"maxItems": 1,
"optional": true,
"format": "date-time"
},
"parser": { // what tool was used to generate the doc?
"type": "string",
"maxItems": 1,
"optional": true
}
},
"additionalProperties": false
}
}
"project": { // to what project does this doc belong?
"type": "object",
"optional": true,
"maxItems": 1,
"properties": {
"name": { // the name of the project
"type": "string",
"maxItems": 1
},
"uri": { // the URI of the project
"type": "string",
"maxItems": 1,
"format": "uri"
},
"version": { // the version of the project
"type": "string",
"maxItems": 1
},
"lang": { // the programming language used in the project
"type": "string",
"maxItems": 1
}
},
"additionalProperties": false
},
"generated": { // some information about the running of the doc generator
"type": "object",
"optional": true,
"maxItems": 1,
"properties": {
"date": { // on what date and time was the doc generated?
"type": "string",
"maxItems": 1,
"optional": true,
"format": "date-time"
},
"parser": { // what tool was used to generate the doc?
"type": "string",
"maxItems": 1,
"optional": true
}
},
"additionalProperties": false
}
}
}
}
};

View File

@ -8,7 +8,7 @@
var Token = Packages.org.mozilla.javascript.Token,
currentParser = null,
currentSourceName = '',
hasOwnProperty = Object.prototype.hasOwnProperty;
hasOwnProp = Object.prototype.hasOwnProperty;
/**
* @class
@ -180,7 +180,7 @@ exports.Parser.prototype.astnodeToMemberof = function(node) {
id = 'astnode'+scope.enclosingFunction.hashCode();
doclet = this.refs[id];
if (doclet && doclet.meta.vars && basename in doclet.meta.vars) {
var alias = hasOwnProperty.call(doclet.meta.vars, basename)? doclet.meta.vars[basename] : false;
var alias = hasOwnProp.call(doclet.meta.vars, basename)? doclet.meta.vars[basename] : false;
if (alias !== false) {
return [alias, basename];
}
@ -190,7 +190,7 @@ exports.Parser.prototype.astnodeToMemberof = function(node) {
}
//First check to see if we have a global scope alias
doclet = this.refs["__global__"];
if (doclet && doclet.meta.vars && hasOwnProperty.call(doclet.meta.vars, basename)) {
if (doclet && doclet.meta.vars && hasOwnProp.call(doclet.meta.vars, basename)) {
var alias = doclet.meta.vars[basename];
if (alias !== false) {
return [alias, basename];
@ -234,7 +234,7 @@ exports.Parser.prototype.resolveThis = function(node) {
}
else {
if (node.enclosingFunction){
return this.resolveThis(node.enclosingFunction/*memberof.doclet.meta.code.val*/);
return this.resolveThis(node.enclosingFunction/* memberof.doclet.meta.code.val */);
}
else return ''; // TODO handle global this?
}
@ -321,12 +321,18 @@ exports.Parser.prototype.resolveEnum = function(e) {
/** @private */
function visitNode(node) {
var e,
commentSrc;
nodeComments,
comment,
commentSrc,
i,
l;
// look for stand-alone doc comments
if (node.type === Token.SCRIPT && node.comments) {
// note: ALL comments are seen in this block...
for each(var comment in node.comments.toArray()) {
nodeComments = node.comments.toArray();
for (i = 0, l = nodeComments.length; i < l; i++) {
comment = nodeComments[i];
if (comment.commentType !== Token.CommentType.JSDOC) {
continue;
}
@ -578,7 +584,7 @@ function nodeToString(node) {
}
return '' + str;
};
}
/** @private
@memberof module:src/parser.Parser

View File

@ -1,18 +1,18 @@
/**
@overview
@author Michael Mathews <micmath@gmail.com>
@license Apache License 2.0 - See file 'LICENSE.md' in this project.
@license Apache License 2.0 - See file 'LICENSE.md' in this project.
*/
/**
Functionality related to JSDoc tags.
@module jsdoc/tag
@requires jsdoc/tag/dictionary
@requires jsdoc/tag/validator
@requires jsdoc/tag/type
@module jsdoc/tag
@requires jsdoc/tag/dictionary
@requires jsdoc/tag/validator
@requires jsdoc/tag/type
*/
var jsdoc = {
tag: {
dictionary: require('jsdoc/tag/dictionary'),
@ -32,7 +32,7 @@ var jsdoc = {
exports.Tag = function(tagTitle, tagBody, meta) {
var tagDef = jsdoc.tag.dictionary.lookUp(tagTitle),
meta = meta || {};
this.originalTitle = trim(tagTitle);
/** The title part of the tag: @title text */
@ -52,34 +52,29 @@ exports.Tag = function(tagTitle, tagBody, meta) {
/** The value property represents the result of parsing the tag text. */
this.value = {};
var [
/*Array.<string>*/ typeNames,
/*any*/ remainingText,
/*?boolean*/ optional,
/*?boolean*/ nullable,
/*?boolean*/ variable
] = jsdoc.tag.type.parse(this.text);
var tagType = jsdoc.tag.type.parse(this.text);
if (typeNames.length) {
if (tagType.type && tagType.type.length) {
this.value.type = {
names: typeNames,
optional: optional,
nullable: nullable,
variable: variable
names: tagType.type,
optional: tagType.optional,
nullable: tagType.nullable,
variable: tagType.variable
};
}
var remainingText = tagType.text;
if (remainingText) {
if (tagDef.canHaveName) {
var [paramName, paramDesc, paramOptional, paramDefault]
= parseParamText(remainingText);
var paramInfo = parseParamText(remainingText);
// note the dash is a special case: as a param name it means "no name"
if (paramName && paramName !== '-') { this.value.name = paramName; }
if (paramInfo.name && paramInfo.name !== '-') { this.value.name = paramInfo.name; }
if (paramDesc) { this.value.description = paramDesc; }
if (paramOptional) { this.value.optional = paramOptional; }
if (paramDefault) { this.value.defaultvalue = paramDefault; }
if (paramInfo.desc) { this.value.description = paramInfo.desc; }
if (paramInfo.optional) { this.value.optional = paramInfo.optional; }
if (paramInfo.default) { this.value.defaultvalue = paramInfo.default; }
}
else {
this.value.description = remainingText;
@ -105,40 +100,40 @@ exports.Tag = function(tagTitle, tagBody, meta) {
}
function trim(text, newlines) {
if (!text) { return ''; }
if (newlines) {
return text.replace(/^[\n\r\f]+|[\n\r\f]+$/g, '');
}
else {
return text.replace(/^\s+|\s+$/g, '');
}
if (!text) { return ''; }
if (newlines) {
return text.replace(/^[\n\r\f]+|[\n\r\f]+$/g, '');
}
else {
return text.replace(/^\s+|\s+$/g, '');
}
}
/**
Parse the parameter name and parameter desc from the tag text.
@inner
@method parseParamText
@memberof module:jsdoc/tag
@param {string} tagText
@returns {Array.<string, string, boolean, boolean>} [pname, pdesc, poptional, pdefault].
Parse the parameter name and parameter desc from the tag text.
@inner
@method parseParamText
@memberof module:jsdoc/tag
@param {string} tagText
@returns {Array.<string, string, boolean, boolean>} [pname, pdesc, poptional, pdefault].
*/
function parseParamText(tagText) {
var pname, pdesc, poptional, pdefault;
// like: pname, pname pdesc, or name - pdesc
tagText.match(/^(\[[^\]]+\]|\S+)((?:\s*\-\s*|\s+)(\S[\s\S]*))?$/);
pname = RegExp.$1;
pdesc = RegExp.$3;
var pname, pdesc, poptional, pdefault;
if ( /^\[\s*(.+?)\s*\]$/.test(pname) ) {
pname = RegExp.$1;
poptional = true;
if ( /^(.+?)\s*=\s*(.+)$/.test(pname) ) {
pname = RegExp.$1;
pdefault = RegExp.$2;
}
}
return [pname, pdesc, poptional, pdefault];
// like: pname, pname pdesc, or name - pdesc
tagText.match(/^(\[[^\]]+\]|\S+)((?:\s*\-\s*|\s+)(\S[\s\S]*))?$/);
pname = RegExp.$1;
pdesc = RegExp.$3;
if ( /^\[\s*(.+?)\s*\]$/.test(pname) ) {
pname = RegExp.$1;
poptional = true;
if ( /^(.+?)\s*=\s*(.+)$/.test(pname) ) {
pname = RegExp.$1;
pdefault = RegExp.$2;
}
}
return { name: pname, desc: pdesc, optional: poptional, default: pdefault };
}

View File

@ -7,7 +7,7 @@
var _synonyms = {},
_definitions = {},
_namespaces = [],
hasOwnProperty = Object.prototype.hasOwnProperty;
hasOwnProp = Object.prototype.hasOwnProperty;
function _TagDefinition(title, etc) {
etc = etc || {};
@ -15,7 +15,7 @@ function _TagDefinition(title, etc) {
this.title = dictionary.normalise(title);
for (var p in etc) {
if ( hasOwnProperty.call(etc, p) ) {
if ( hasOwnProp.call(etc, p) ) {
this[p] = etc[p];
}
}
@ -43,7 +43,7 @@ var dictionary = {
lookUp: function(title) {
title = dictionary.normalise(title);
if ( hasOwnProperty.call(_definitions, title) ) {
if ( hasOwnProp.call(_definitions, title) ) {
return _definitions[title];
}
@ -59,7 +59,7 @@ var dictionary = {
normalise: function(title) {
canonicalName = title.toLowerCase();
if ( hasOwnProperty.call(_synonyms, canonicalName) ) {
if ( hasOwnProp.call(_synonyms, canonicalName) ) {
return _synonyms[canonicalName];
}
@ -70,7 +70,7 @@ var dictionary = {
require('jsdoc/tag/dictionary/definitions').defineTags(dictionary);
for (var prop in dictionary) {
if ( hasOwnProperty.call(dictionary, prop) ) {
if ( hasOwnProp.call(dictionary, prop) ) {
exports[prop] = dictionary[prop];
}
}

View File

@ -54,8 +54,8 @@ exports.defineTags = function(dictionary) {
// Allow augments value to be specified as a normal type, e.g. {Type}
onTagText: function(text) {
var type = require('jsdoc/tag/type'),
[tp, tx] = type.getTagType(text);
return tp || text;
tagType = type.getTagType(text);
return tagType.type || text;
},
onTagged: function(doclet, tag) {
doclet.augment( firstWordOf(tag.value) );
@ -67,8 +67,8 @@ exports.defineTags = function(dictionary) {
dictionary.defineTag('borrows', {
mustHaveValue: true,
onTagged: function(doclet, tag) {
var [target, source] = parseBorrows(doclet, tag);
doclet.borrow(target, source);
var borrows = parseBorrows(doclet, tag);
doclet.borrow(borrows.target, borrows.source);
}
});
@ -625,11 +625,13 @@ function parseBorrows(doclet, tag) {
var m = /^(\S+)(?:\s+as\s+(\S+))?$/.exec(tag.text);
if (m) {
if (m[1] && m[2]) {
return [ m[1], m[2] ];
return { target: m[1], source: m[2] };
}
else if (m[1]) {
return [ m[1] ];
return { target: m[1] };
}
} else {
return {};
}
}

View File

@ -8,27 +8,39 @@
/**
@param {string} tagValue
@returns {Array.<string>}
@returns {object} Hash with type, text, optional, nullable, and variable properties
*/
exports.parse = function(tagValue) {
if (typeof tagValue !== 'string') { tagValue = ''; }
var type = '',
text = '',
count = 0,
tagType,
optional,
nullable,
variable;
[type, text] = getTagType(tagValue);
if (type === '') { text = tagValue; }
tagType = getTagType(tagValue);
type = tagType.type;
if (tagType.type === '') {
text = tagValue;
} else {
text = tagType.text;
}
[type, optional] = parseOptional(type);
[type, nullable] = parseNullable(type);
[type, variable] = parseVariable(type);
optional = parseOptional(type);
nullable = parseNullable(type);
variable = parseVariable(type);
type = variable.type || nullable.type || optional.type;
type = parseTypes(type); // make it into an array
return [type, text, optional, nullable, variable];
return {
type: type,
text: text,
optional: optional.optional,
nullable: nullable.nullable,
variable: variable.variable
};
}
function parseOptional(type) {
@ -40,7 +52,7 @@ function parseOptional(type) {
optional = true;
}
return [type, optional];
return { type: type, optional: optional };
}
function parseNullable(type) {
@ -52,7 +64,7 @@ function parseNullable(type) {
nullable = (RegExp.$1 === '?')? true : false;
}
return [type, nullable];
return { type: type, nullable: nullable };
}
function parseVariable(type) {
@ -64,7 +76,7 @@ function parseVariable(type) {
variable = true;
}
return [type, variable];
return { type: type, variable: variable };
}
function parseTypes(type) {
@ -110,7 +122,7 @@ function getTagType(tagValue) {
}
}
}
return [type, text];
return { type: type, text: text };
}
exports.getTagType = getTagType;

View File

@ -1,6 +1,6 @@
/**
@overview
@author Rafał Wrzeszcz <rafal.wrzeszcz@wrzasq.pl>
@author Rafa&#322; Wrzeszcz <rafal.wrzeszcz@wrzasq.pl>
@license Apache License 2.0 - See file 'LICENSE.md' in this project.
*/
@ -75,6 +75,8 @@ exports.load = function(path) {
case 'js':
case 'json':
conf[name] = JSON.parse(content);
// don't add this as a tutorial
return;
// how can it be? check `finder' regexp
default:

View File

@ -4,7 +4,7 @@
fs = require('fs'),
helper = require('jsdoc/util/templateHelper'),
scopeToPunc = { 'static': '.', 'inner': '~', 'instance': '#' },
hasOwnProperty = Object.prototype.hasOwnProperty;
hasOwnProp = Object.prototype.hasOwnProperty;
/**
@global
@ -16,7 +16,7 @@
var defaultTemplatePath = 'templates/default';
var templatePath = (opts.template) ? opts.template : defaultTemplate;
var out = '',
view = new template.Template(__dirname + '/' + templatePath + '/tmpl');
view = new template.Template(env.dirname + '/' + templatePath + '/tmpl');
// set up templating
view.layout = 'layout.tmpl';
@ -177,7 +177,7 @@
fs.mkPath(outdir);
// copy static files to outdir
var fromDir = __dirname + '/' + templatePath + '/static',
var fromDir = env.dirname + '/' + templatePath + '/static',
staticFiles = fs.ls(fromDir, 3);
staticFiles.forEach(function(fileName) {
@ -246,7 +246,7 @@
if (moduleNames.length) {
nav += '<h3>Modules</h3><ul>';
moduleNames.forEach(function(m) {
if ( !hasOwnProperty.call(seen, m.longname) ) nav += '<li>'+linkto(m.longname, m.name)+'</li>';
if ( !hasOwnProp.call(seen, m.longname) ) nav += '<li>'+linkto(m.longname, m.name)+'</li>';
seen[m.longname] = true;
});
@ -260,7 +260,7 @@
if (externalNames.length) {
nav += '<h3>Externals</h3><ul>';
externalNames.forEach(function(e) {
if ( !hasOwnProperty.call(seen, e.longname) ) nav += '<li>'+linkto( e.longname, e.name.replace(/(^"|"$)/g, '') )+'</li>';
if ( !hasOwnProp.call(seen, e.longname) ) nav += '<li>'+linkto( e.longname, e.name.replace(/(^"|"$)/g, '') )+'</li>';
seen[e.longname] = true;
});
@ -284,7 +284,7 @@
nav += '<h3>Classes</h3><ul>';
moduleClasses = -1;
}
if ( !hasOwnProperty.call(seen, c.longname) ) nav += '<li>'+linkto(c.longname, c.name)+'</li>';
if ( !hasOwnProp.call(seen, c.longname) ) nav += '<li>'+linkto(c.longname, c.name)+'</li>';
seen[c.longname] = true;
});
@ -298,7 +298,7 @@
if (namespaceNames.length) {
nav += '<h3>Namespaces</h3><ul>';
namespaceNames.forEach(function(n) {
if ( !hasOwnProperty.call(seen, n.longname) ) nav += '<li>'+linkto(n.longname, n.name)+'</li>';
if ( !hasOwnProp.call(seen, n.longname) ) nav += '<li>'+linkto(n.longname, n.name)+'</li>';
seen[n.longname] = true;
});
@ -309,7 +309,7 @@
// if (constantNames.length) {
// nav += '<h3>Constants</h3><ul>';
// constantNames.forEach(function(c) {
// if ( !hasOwnProperty.call(seen, c.longname) ) nav += '<li>'+linkto(c.longname, c.name)+'</li>';
// if ( !hasOwnProp.call(seen, c.longname) ) nav += '<li>'+linkto(c.longname, c.name)+'</li>';
// seen[c.longname] = true;
// });
//
@ -323,7 +323,7 @@
if (mixinNames.length) {
nav += '<h3>Mixins</h3><ul>';
mixinNames.forEach(function(m) {
if ( !hasOwnProperty.call(seen, m.longname) ) nav += '<li>'+linkto(m.longname, m.name)+'</li>';
if ( !hasOwnProp.call(seen, m.longname) ) nav += '<li>'+linkto(m.longname, m.name)+'</li>';
seen[m.longname] = true;
});
@ -347,7 +347,7 @@
nav += '<h3>Global</h3><ul>';
globalNames.forEach(function(g) {
if ( g.kind !== 'typedef' && !hasOwnProperty.call(seen, g.longname) ) nav += '<li>'+linkto(g.longname, g.name)+'</li>';
if ( g.kind !== 'typedef' && !hasOwnProp.call(seen, g.longname) ) nav += '<li>'+linkto(g.longname, g.name)+'</li>';
seen[g.longname] = true;
});

View File

@ -8,7 +8,7 @@ module.exports = require('connect').createServer(
Connect.favicon(),
Connect.cache(),
Connect.gzip(),
require('wheat')(__dirname)
require('wheat')(env.dirname)
);
/**

View File

@ -15,7 +15,7 @@ jasmine.loadHelpersInFolder = function(folder, matcher) {
helpers = helperCollection.getSpecs();
for ( var i = 0, len = helpers.length; i < len; ++i) {
var file = helpers[i].path();
var helper = require(file.replace(/\\/g, '/').replace(new RegExp('^' + __dirname + '/'), "").replace(/\.*$/, ""));
var helper = require(file.replace(/\\/g, '/').replace(new RegExp('^' + env.dirname + '/'), "").replace(/\.*$/, ""));
for (var key in helper) {
this[key] = helper[key];
@ -79,7 +79,7 @@ jasmine.executeSpecsInFolder = function(folder, done, verbose, matcher) {
var specsList = specs.getSpecs();
for ( var i = 0, len = specsList.length; i < len; ++i) {
var filename = specsList[i];
require(filename.path().replace(/\\/g, '/').replace(new RegExp('^' + __dirname + '/'), "").replace(/\.\w+$/, ""));
require(filename.path().replace(/\\/g, '/').replace(new RegExp('^' + env.dirname + '/'), "").replace(/\.\w+$/, ""));
}
//Run Jasmine

View File

@ -33,7 +33,7 @@ exports.load = function(loadpath, matcher, clear) {
}
var wannaBeSpecs = wrench.readdirSyncRecursive(loadpath);
for (var i = 0; i < wannaBeSpecs.length; i++) {
var file = path.join(__dirname, loadpath, wannaBeSpecs[i]);
var file = path.join(env.dirname, loadpath, wannaBeSpecs[i]);
try {
if (fs.statSync(file).isFile()) {
if (!/.*node_modules.*/.test(file) && matcher.test(path.filename(file))) {

View File

@ -3,19 +3,19 @@ describe("module names", function() {
srcParser = null, doclets;
beforeEach(function() {
env.opts._ = [__dirname + '/test/fixtures/modules/'];
env.opts._ = [env.dirname + '/test/fixtures/modules/'];
srcParser = new parser.Parser();
require('jsdoc/src/handlers').attachTo(srcParser);
});
it("should create a name from the file path when no documented module name exists", function() {
doclets = srcParser.parse(__dirname + '/test/fixtures/modules/data/mod-1.js');
doclets = srcParser.parse(env.dirname + '/test/fixtures/modules/data/mod-1.js');
expect(doclets.length).toBeGreaterThan(1);
expect(doclets[0].longname).toEqual('module:data/mod-1');
});
it("should use the documented module name if available", function() {
doclets = srcParser.parse(__dirname + '/test/fixtures/modules/data/mod-2.js');
doclets = srcParser.parse(env.dirname + '/test/fixtures/modules/data/mod-2.js');
expect(doclets.length).toBeGreaterThan(1);
expect(doclets[0].longname).toEqual('module:my/module/name');
});

View File

@ -1,7 +1,7 @@
var hasOwnProperty = Object.prototype.hasOwnProperty;
exports.getDocSetFromFile = function(filename, parser) {
var sourceCode = readFile(__dirname + '/' + filename),
var sourceCode = readFile(env.dirname + '/' + filename),
testParser = parser || new (require('jsdoc/src/parser')).Parser(),
doclets;

View File

@ -15,8 +15,8 @@ describe("include", function() {
expect( include.resolve('/a/b/c.js') ).toEqual('/a/b/c.js');
});
it("should resolve relative filepaths relative to the __dirname", function() {
expect( include.resolve('a/b/c') ).toEqual(__dirname+'/'+'a/b/c');
it("should resolve relative filepaths relative to the env.dirname", function() {
expect( include.resolve('a/b/c') ).toEqual(env.dirname+'/'+'a/b/c');
});
});

View File

@ -43,7 +43,7 @@ describe("jsdoc/src/parser", function() {
it("should be able to parse its own source file", function() {
var fs = require("fs"),
path = require("path"),
parserSrc = "javascript:" + fs.readFileSync( path.join(__dirname,
parserSrc = "javascript:" + fs.readFileSync( path.join(env.dirname,
"rhino_modules", "jsdoc", "src", "parser.js") ),
parse = function() {
parser.parse(parserSrc);

View File

@ -4,10 +4,10 @@ describe("jsdoc/src/scanner", function() {
includePattern: new RegExp(".+\\.js(doc)?$"),
excludePattern: new RegExp("(^|\\/)_")
}),
sourceFiles = scanner.scan([__dirname+'/test/fixtures/src/'], 3, filter);
sourceFiles = scanner.scan([env.dirname+'/test/fixtures/src/'], 3, filter);
sourceFiles = sourceFiles.map(function($) {
return $.replace(__dirname, '');
return $.replace(env.dirname, '');
});
it("should return the correct source files", function() {

View File

@ -0,0 +1,59 @@
/*global app: true, describe: true, env: true, expect: true, it: true */
var fs = require("fs"),
path = require("path");
var config = JSON.parse( fs.readFileSync( path.join(env.dirname, ".jshintrc"), "utf-8" ) );
function jsHintCheck(filename, source, conf) {
var JSHINT = require("jshint/jshint").JSHINT;
source = source || fs.readFileSync(filename, "utf-8");
conf = conf || config;
JSHINT(source, conf);
if (JSHINT.errors.length) {
throw new Error( filename + " is not JSHint clean: " + JSON.stringify(JSHINT.errors) );
}
}
describe("jshint-clean", function() {
it("should generate JSHint errors for bad code", function() {
var check = function() {
jsHintCheck("dummyFile.js", "hasOwnProperty = 0");
};
expect(check).toThrow();
});
it("should not generate JSHint errors for good code", function() {
var check = function() {
jsHintCheck("dummyFile.js", "var foo = 0;");
};
expect(check).not.toThrow();
});
it("should not find JSHint errors in JSDoc", function() {
var check,
files,
filter,
source,
i,
l;
// check all .js files unless they're tests; rhino shim files that probably can't be
// delinted; or third-party modules
source = {
includePattern: ".+\\.js$",
excludePattern: ".+[\\\\|/]test[\\\\|/].+|.+rhino-shim\\.js|.+[\\\\|/]Jake[\\\\|/].+|.+[\\\\|/]node_modules[\\\\|/].+"
};
filter = new (require('jsdoc/src/filter').Filter)(source);
files = app.jsdoc.scanner.scan([env.dirname], 10, filter);
check = function() {
jsHintCheck(files[i]);
};
for (i = 0, l = files.length; i < l; i++) {
expect(check).not.toThrow();
}
});
});

View File

@ -4,7 +4,7 @@ describe("@overview tag", function() {
doclets;
require('jsdoc/src/handlers').attachTo(srcParser);
doclets = srcParser.parse(__dirname + '/test/fixtures/file.js');
doclets = srcParser.parse(env.dirname + '/test/fixtures/file.js');
it('When a file overview tag appears in a doclet, the name of the doclet should start with file: and should end with the path to the file.', function() {
expect(doclets[0].name).toMatch(/^.*([\/\\]fixtures[\/\\]file\.js)$/);