Added isScalar attribute of tag.

This commit is contained in:
Michael Mathews 2010-07-24 12:02:13 +01:00
parent e8bbaef861
commit 15cc0e57ca
4 changed files with 102 additions and 55 deletions

View File

@ -85,8 +85,12 @@
@returns {*} The value of the found tag.
*/
Doclet.prototype.tagValue = function(tagName) {
var tagAbout = tagDictionary.lookUp(tagName);
for (var i = 0, leni = this.tags.length; i < leni; i++) {
if (this.tags[i].name === tagName) {
if (tagAbout.isScalar && this.tags[i].value.push) {
return this.tags[i].value[0];
}
return this.tags[i].value;
}
}
@ -109,7 +113,7 @@
}
}
this.tags[this.tags.length] = parse_tag.fromText(tagName + ' ' + tagValue);
this.addTag(tagName, tagValue);
}
/**
@ -120,7 +124,7 @@
@returns {Tag} The new tag.
*/
Doclet.prototype.addTag = function(tagName, tagValue) {
this.tags[this.tags.length] = parse_tag.fromText(tagName + ' ' + tagValue);
return this.tags.addTag(tagName, tagValue);
}
/**
@ -146,13 +150,7 @@
@returns {boolean} True if the tag is found, false otherwise.
*/
Doclet.prototype.hasTag = function(tagName) {
var i = this.tags.length;
while(i--) {
if (this.tags[i].name === tagName) {
return true;
}
}
return false;
return this.tags.hasTag(tagName);
}
/**
@ -212,23 +210,23 @@
}
return o;
}
// TODO need to simplify this string or array business. maybe define some props as scalar?
Doclet.prototype.getScope = function() {
var scope = this.tagValue('scope');
if (!scope) {
return '';
}
else if (typeof scope === 'string' && ['inner', 'static', 'instance'].indexOf(scope) > -1) {
return scope;
}
else {
if (scope.indexOf('instance') > -1) { return 'instance'; }
else if (scope.indexOf('inner') > -1) { return 'inner'; }
else if (scope.indexOf('static') > -1) { return 'static'; }
}
}
//
// // TODO need to simplify this string or array business. maybe define some props as scalar?
// Doclet.prototype.getScope = function() {
// var scope = this.tagValue('scope');
//
// if (!scope) {
// return '';
// }
// else if (typeof scope === 'string' && ['inner', 'static', 'instance'].indexOf(scope) > -1) {
// return scope;
// }
// else {
// if (scope.indexOf('instance') > -1) { return 'instance'; }
// else if (scope.indexOf('inner') > -1) { return 'inner'; }
// else if (scope.indexOf('static') > -1) { return 'static'; }
// }
// }
/**
Remove JsDoc comment slash-stars. Trims white space.
@ -288,23 +286,23 @@
tagAbout = tagDictionary.lookUp(tags[i].name);
if (tagAbout.setsDocletAttrib) {
tags[tags.length] = parse_tag.fromText('attrib '+tags[i].name);
tags.addTag('attrib', tags[i].name);
}
if (tagAbout.setsDocletAccess) {
tags[tags.length] = parse_tag.fromText('access '+tags[i].name);
tags.addTag('access', tags[i].name);
}
if (tagAbout.setsDocletScope) {
tags[tags.length] = parse_tag.fromText('scope '+tags[i].name);
tags.addTag('scope', tags[i].name);
}
if (tagAbout.impliesTag) { // TODO allow a template string?
tags[tags.length] = parse_tag.fromText(tagAbout.impliesTag);
tags.addTag(tagAbout.impliesTag);
}
if (tagAbout.setsDocletDesc) {
tags[tags.length] = parse_tag.fromText('desc '+tags[i].value);
tags.addTag('desc', tags[i].value);
}
if (tags[i].name === 'name') {
@ -343,7 +341,7 @@
}
if (tags[i].pdesc) {
tags[tags.length] = parse_tag.fromText('desc ' + tags[i].pdesc);
tags.addTag('desc', tags[i].pdesc);
}
if (kind && kind !== tags[i].name) {
@ -355,19 +353,19 @@
}
if (name && !taggedName) {
tags[tags.length] = parse_tag.fromText('name ' + name);
tags.addTag('name', name);
}
if ( isFile && !(name || taggedName) ) {
tags[tags.length] = parse_tag.fromText('name file:'+meta.file+'');
tags.addTag('name', 'file:'+meta.file);
}
if (kind && !taggedIsa) {
tags[tags.length] = parse_tag.fromText('kind ' + kind);
tags.addTag('kind', kind);
}
if (memberof && !taggedMemberof) {
tags[tags.length] = parse_tag.fromText('memberof ' + memberof);
tags.addTag('memberof', memberof);
}
}
@ -384,13 +382,13 @@
// class tags imply a constructor tag
if (tags[i].name === 'class' && !doclet.hasTag('constructor') ) {
doclet.tags[doclet.tags.length] = parse_tag.fromText('kind constructor');
tags.addTag('kind', 'constructor');
}
// enums have a defualt type of number
if (tags[i].name === 'enum') {
if ( !doclet.hasTag('type') ) {
doclet.tags[doclet.tags.length] = parse_tag.fromText('type number');
tags.addTag('type', 'number');
}
}
@ -404,7 +402,7 @@
else docletTypes = tags[i].type;
for (var i = 0, leni = docletTypes.length; i < leni; i++) {
doclet.tags[doclet.tags.length] = parse_tag.fromText('type '+docletTypes[i]);
tags.addTag('type', docletTypes[i]);
}
}
}

View File

@ -55,7 +55,7 @@
if (name) { doclet.addTag('scope', puncToScope[scope]); }
}
else {
scope = doclet.getScope();
scope = doclet.tagValue('scope');
if (!scope) {
scope = 'static'; // default scope is static
@ -168,7 +168,7 @@
enclosingDoc = exports.docFromNode(enclosing);
if (enclosingDoc) {
if (enclosingDoc.getScope() === 'inner') memberof = ''; // inner functions have `this` scope of global
if (enclosingDoc.tagValue('scope') === 'inner') memberof = ''; // inner functions have `this` scope of global
else memberof = enclosingDoc.tagValue('path');
}
else {

View File

@ -98,6 +98,41 @@
}
}
/**
@param {string|Tag} tagOrTagName
@param {*} [tagValue]
*/
function addTag(tagName, tagValue) {
var tag;
if (tagName.name) {
tag = tagName;
tagName = tagName.name;
}
var tagAbout = tagDictionary.lookUp(tagName);
if (tagAbout.isScalar && this.hasTag(tagName)) {
return false;
}
if (typeof tagValue === 'undefined') {
// TODO this could obviously be more efficient
this[this.length] = tag || exports.fromText(tagName);
}
else {
this[this.length] = tag || exports.fromText(tagName + ' ' + tagValue);
}
return true;
}
function hasTag(tagName, tagValue) {
var i = this.length;
while(i--) {
if (this[i].name === tagName) {
return true;
}
}
return false;
}
/**
Given the source of a jsdoc comment, finds the tags.
@private
@ -107,6 +142,8 @@
*/
exports.parse = function(commentSrc) {
var tags = [];
tags.addTag = addTag;
tags.hasTag = hasTag;
// split out the basic tags, keep surrounding whitespace
commentSrc
@ -115,7 +152,7 @@
.forEach(function($) {
var newTag = exports.fromText($);
if (newTag.name) { tags.push(newTag); }
if (newTag.name) { tags.addTag(newTag); }
});
return tags;

View File

@ -65,7 +65,7 @@
// 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
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
@ -76,7 +76,8 @@
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
impliesTag : false, // this tag implies another tag
isScalar : false // can only have a single value (first wins)
};
/** Syntax: @access <text> (private|public|protected)
@ -86,7 +87,8 @@
@memberOf module:jsdoc/tagdictionary.tagDefinitions
*/
new TagDefinition('access', {
isExported: true
isExported: true,
isScalar: true
});
/** Syntax: @scope <text> (global|static|inner|instance)
@ -96,7 +98,8 @@
@memberOf module:jsdoc/tagdictionary.tagDefinitions
*/
new TagDefinition('scope', {
isExported: true
isExported: true,
isScalar: true
});
/** Syntax: @desc <text>
@ -105,7 +108,8 @@
@memberOf module:jsdoc/tagdictionary.tagDefinitions
*/
new TagDefinition('desc', { // t
isExported: true
isExported: true,
isScalar: true
});
/** Syntax: @kind <text>
@ -115,7 +119,8 @@
@memberOf module:jsdoc/tagdictionary.tagDefinitions
*/
new TagDefinition('kind', {
isExported: true
isExported: true,
isScalar: true
});
/** Syntax: @name <docletName>
@ -124,7 +129,8 @@
@memberOf module:jsdoc/tagdictionary.tagDefinitions
*/
new TagDefinition('name', {
isExported: true
isExported: true,
isScalar: true
});
/** Syntax: @path <text>
@ -134,7 +140,8 @@
@memberOf module:jsdoc/tagdictionary.tagDefinitions
*/
new TagDefinition('path', {
isExported: true
isExported: true,
isScalar: true
});
/** Syntax: @memberOf <text>
@ -175,7 +182,8 @@
*/
new TagDefinition('classdesc', { //t
isExported: true,
impliesTag: 'constructor'
impliesTag: 'constructor',
isScalar: true
});
/** Syntax: @constant|const <docletType> <docletName>
@ -313,7 +321,8 @@
new TagDefinition('thisobj', { //t
isExported: true,
canHaveType: true,
canHavePdesc: true
canHavePdesc: true,
isScalar: true
});
/** Syntax: @attrib <docletAttrib> (readonly)
@ -442,7 +451,8 @@
@memberOf module:jsdoc/tagdictionary.tagDefinitions
*/
new TagDefinition('since', {
isExported: true
isExported: true,
isScalar: true
});
/** Syntax: @version <text>
@ -451,7 +461,8 @@
@memberOf module:jsdoc/tagdictionary.tagDefinitions
*/
new TagDefinition('version', {
isExported: true
isExported: true,
isScalar: true
});
/** Syntax: @requires <text>
@ -480,7 +491,8 @@
@memberOf module:jsdoc/tagdictionary.tagDefinitions
*/
new TagDefinition('deprecated', {
isExported: true
isExported: true,
isScalar: true
});
/** Syntax: @see <text>