Added support for names in modules that are not safe variable names in JS.

This commit is contained in:
Michael Mathews 2010-12-18 16:26:33 +00:00
parent bae5b6d03b
commit 7fecfa0717
5 changed files with 93 additions and 27 deletions

View File

@ -43,7 +43,9 @@
name = name.replace(/^exports\.(?=.+$)/, currentModule + '.');
}
path = name = name? (''+name).replace(/\.prototype\.?/g, '#') : '';
name = name? (''+name).replace(/\.prototype\.?/g, '#') : '';
name = name;
path = quoteUnsafe(name, kind);
if (memberof) { // @memberof tag given
memberof = memberof.replace(/\.prototype\.?/g, '#');
@ -61,6 +63,7 @@
doclet.setTag('memberof', memberof);
}
else {
scope = doclet.tagValue('scope');
if (!scope) {
@ -74,32 +77,37 @@
}
}
}
else if (kind !== 'file') { // which don't have scopes or memberof
[prefix, scope, name] = exports.shorten(name);
var taggedScope;
if ( taggedScope = doclet.tagValue('scope') ) {
scope = scopeToPunc[taggedScope];
if (prefix) { path = prefix + scope + name; }
}
if (prefix) {
doclet.setTag('memberof', prefix);
if (name) {
doclet.addTag('scope', puncToScope[scope]);
}
}
else if (name) {
// global symbol?
doclet.addTag('scope', 'global');
}
else {
if (kind !== 'file' && kind !== 'module') { // which don't have scopes or memberof
[prefix, scope, name] = exports.shorten(name);
var taggedScope;
if ( taggedScope = doclet.tagValue('scope') ) {
scope = scopeToPunc[taggedScope];
if (prefix) { path = prefix + scope + name; }
}
if (prefix) {
doclet.setTag('memberof', prefix);
if (name) {
doclet.addTag('scope', puncToScope[scope]);
}
}
else if (name) {
// global symbol?
doclet.addTag('scope', 'global');
}
}
else {
}
}
// if name doesn't already have a docspace and needs one
if (jsdoc.tagDictionary.lookUp(kind).setsDocletDocspace) {
// the namespace should appear in the path but not the name
if ( /^[a-z_$-]+:(\S+)/i.test(name) ) {
if ( /^[a-z_$-\/]+:"?(\S+)"?/i.test(name) ) {
name = RegExp.$1;
}
@ -110,10 +118,10 @@
if (name) doclet.setTag('name', name);
if (!path && memberof && name.indexOf(memberof) !== 0) {
path = memberof + (scope? scope : '') + ns + name;
path = memberof + (scope? scope : '') + ns + name;
}
else if (ns) {
path = ns + name
path = ns + quoteUnsafe(name, kind)
};
if (path) {
@ -123,6 +131,16 @@
return path;
}
function quoteUnsafe(name, kind) { // docspaced names may have unsafe characters which need to be quoted by us
if ( (jsdoc.tagDictionary.lookUp(kind).setsDocletDocspace) && /[^$_a-zA-Z0-9]/.test(name) ) {
if (!/^[a-z_$-\/]+:\"/i.test(name)) {
return '"' + name.replace(/\"/g, '"') + '"'
}
}
return name;
}
/**
Given a path like "a.b#c", slice it up into ["a.b", "#", 'c'],
representing the memberof, the scope, and the name.

View File

@ -28,7 +28,7 @@
if ( thisDoclet.hasTag('name') && thisDoclet.hasTag('kind') ) {
jsdoc.doclets.addDoclet(thisDoclet);
if (thisDoclet.tagValue('kind') === 'module') {
jsdoc.name.setCurrentModule( thisDoclet.tagValue('path') );
jsdoc.name.setCurrentModule( thisDoclet.tagValue('path') );
}
}
}

View File

@ -26,6 +26,7 @@ load(BASEDIR + '/test/tests/23_tag_fires.js');
load(BASEDIR + '/test/tests/24_tag_exception.js');
load(BASEDIR + '/test/tests/25_tag_scope.js');
load(BASEDIR + '/test/tests/26_tag_tag.js');
load(BASEDIR + '/test/tests/27_tag_module.js');
// see http://visionmedia.github.com/jspec/
JSpec.run({

View File

@ -1,7 +1,7 @@
/**
* @module webui/utils
* @module ./webui/utils.strings
*/
/** @method */
exports.twiddle = function() {
}
}

View File

@ -0,0 +1,47 @@
(function() {
var jsdoc,
doclets;
JSpec.describe('@module', function() {
before(function() {
// docsets can only be created by parsers
jsdoc = {
tag: require('jsdoc/tag'),
parser: require('jsdoc/parser')
};
jsdoc.parser.parseFiles(BASEDIR + 'test/samples/tag_module.js');
doclets = jsdoc.parser.result.map(function($){ return $.toObject(); });
});
describe('A doclet that lists a module', function() {
it('should have an `kind` property set to "module"', function() {
var doclet = doclets[0];
expect(doclet).to(have_property, 'kind');
expect(doclet.kind).to(eql, 'module');
});
it('should have a `name` property set to the given name"', function() {
var doclet = doclets[0];
expect(doclet).to(have_property, 'name');
expect(doclet.name).to(eql, './webui/utils.strings');
expect(doclet).to(have_property, 'path');
expect(doclet.path).to(eql, 'module:"./webui/utils.strings"');
});
});
describe('A function exported by a moduke', function() {
it('should a path that includes the name of the module', function() {
var doclet = doclets[1];
expect(doclet).to(have_property, 'name');
expect(doclet.name).to(eql, 'twiddle');
expect(doclet).to(have_property, 'path');
expect(doclet.path).to(eql, 'module:"./webui/utils.strings".twiddle');
});
});
});
})();