mirror of
https://github.com/jsdoc/jsdoc.git
synced 2025-12-08 19:46:11 +00:00
Added support for @mixin tag.
This commit is contained in:
parent
6d3143143e
commit
cad6e9c01a
@ -261,7 +261,7 @@
|
||||
var name = '',
|
||||
taggedName = '',
|
||||
kind = '',
|
||||
taggedIsa = '',
|
||||
taggedKind = '',
|
||||
memberof = '',
|
||||
taggedMemberof = '',
|
||||
isFile = false, // TODO this should be handled by an event handler in tag dictionary
|
||||
@ -300,7 +300,7 @@
|
||||
if (kind && kind !== tags[i].value) {
|
||||
throw new DocTagConflictError('Symbol has too many isas, cannot be both: ' + kind + ' and ' + tags[i].value);
|
||||
}
|
||||
taggedIsa = kind = tags[i].value;
|
||||
taggedKind = kind = tags[i].value;
|
||||
}
|
||||
else if (tags[i].name === 'memberof') {
|
||||
if (memberof) {
|
||||
@ -337,6 +337,19 @@
|
||||
}
|
||||
}
|
||||
|
||||
if ( /^\s*(\S+)\s*=>\s*(\S+)/.test(taggedName) ) {
|
||||
taggedName = RegExp.$1;
|
||||
var refersto = RegExp.$2;
|
||||
|
||||
tags.setTag('name', taggedName);
|
||||
|
||||
taggedKind = 'mixin';
|
||||
tags.setTag('kind', taggedKind);
|
||||
|
||||
tags.addTag('refersto', refersto);
|
||||
|
||||
}
|
||||
|
||||
if (name && !taggedName) {
|
||||
tags.addTag('name', name);
|
||||
}
|
||||
@ -345,7 +358,7 @@
|
||||
tags.addTag('name', 'file:'+meta.file);
|
||||
}
|
||||
|
||||
if (kind && !taggedIsa) {
|
||||
if (kind && !taggedKind) {
|
||||
tags.addTag('kind', kind);
|
||||
}
|
||||
|
||||
|
||||
@ -11,9 +11,8 @@
|
||||
(function() {
|
||||
|
||||
var Token = Packages.org.mozilla.javascript.Token,
|
||||
currentModule = '';
|
||||
|
||||
var jsdoc = {
|
||||
currentModule = '',
|
||||
jsdoc = {
|
||||
tagDictionary: require('jsdoc/tagdictionary')
|
||||
};
|
||||
|
||||
@ -54,7 +53,7 @@
|
||||
[prefix, scope, name] = exports.shorten(name);
|
||||
}
|
||||
else { // like @name bar, @memberof foo
|
||||
if ( /([.~#])$/.test(memberof) ) { // like @memberof foo# or @memberof foo~
|
||||
if ( /([#.~])$/.test(memberof) ) { // like @memberof foo# or @memberof foo~
|
||||
path = memberof + name;
|
||||
scope = RegExp.$1;
|
||||
doclet.setTag('scope', puncToScope[scope]);
|
||||
@ -153,77 +152,65 @@
|
||||
return [prefix, scope, name];
|
||||
}
|
||||
|
||||
/** Given an AST node, return the path to the enclosing node. */
|
||||
function getEnclosingPath(node) {
|
||||
var enclosingNode,
|
||||
enclosingDoc;
|
||||
|
||||
if (node.parent && node.parent.type === Token.OBJECTLIT) {
|
||||
if (enclosingNode = node.parent) {
|
||||
enclosingDoc = exports.docFromNode(enclosingNode);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( enclosingNode = node.getEnclosingFunction() ) {
|
||||
enclosingDoc = exports.docFromNode(enclosingNode);
|
||||
}
|
||||
}
|
||||
|
||||
if (enclosingDoc) {
|
||||
return (enclosingDoc.tagValue('path') || '').replace(/\.prototype\.?/g, '#');
|
||||
}
|
||||
function docToPath(doclet, tagName) {
|
||||
// TODO protect quoted parts of the path that may contain the string "prototype"
|
||||
return (doclet.tagValue(tagName) || '').replace(/\.prototype\.?/g, '#');
|
||||
}
|
||||
|
||||
/**
|
||||
Resolve how to document the `this.` portion of a symbol name.
|
||||
Apply information about how nested this AST node is to what we know about
|
||||
the name.
|
||||
*/
|
||||
exports.resolveThis = function(name, node, doclet) {
|
||||
|
||||
exports.resolvePath = function(name, node, doclet) {
|
||||
var enclosing,
|
||||
enclosingDoc,
|
||||
enclosingPath,
|
||||
memberof = (doclet.tagValue('memberof') || '').replace(/\.prototype\.?/g, '#');
|
||||
memberof;
|
||||
|
||||
// documented member of an undocumented object literal?
|
||||
// like foo = { /** a bar. */ bar: 1};
|
||||
if (node.parent && node.parent.type === Token.OBJECTLIT) {
|
||||
if ( enclosingPath = getEnclosingPath(node) ) {
|
||||
if ( enclosingDoc = exports.docFromNode(node.parent) ) {
|
||||
if ( enclosingPath = docToPath(enclosingDoc, 'path') ) {
|
||||
name = enclosingPath + (/([#.~])$/.test(enclosingPath) ? '' : '.') + name;
|
||||
}
|
||||
}
|
||||
}
|
||||
// what's all this then?
|
||||
else if ( name.indexOf('this.') === 0 ) {
|
||||
memberof = docToPath(doclet, 'memberof');
|
||||
|
||||
// need to examine the source code to determine the full path :(
|
||||
if (!memberof || memberof === 'this') {
|
||||
enclosing = node.getEnclosingFunction()
|
||||
|
||||
enclosingDoc = exports.docFromNode(enclosing);
|
||||
|
||||
if (enclosingDoc) {
|
||||
if (enclosingDoc) { // documented enclosing symbol
|
||||
if (enclosingDoc.tagValue('scope') === 'inner') {
|
||||
memberof = ''; // inner functions have `this` scope of global
|
||||
memberof = ''; // inner functions always have `this` resolve to the global object
|
||||
}
|
||||
else {
|
||||
memberof = enclosingDoc.tagValue('path');
|
||||
memberof = docToPath(enclosingDoc, 'path');
|
||||
}
|
||||
}
|
||||
else {
|
||||
memberof = '';
|
||||
}
|
||||
|
||||
if (enclosing && !memberof) {
|
||||
memberof = ''; // [[anonymousFunction]]
|
||||
if (enclosing && !memberof) { // inside an anonymous function, this resolves to the global object
|
||||
memberof = '';
|
||||
name = name.slice(5); // remove `this.`
|
||||
}
|
||||
else if (!enclosing) {
|
||||
memberof = ''; // [[globalObject]]
|
||||
memberof = ''; // no enclosing function, this resolves to the global object
|
||||
}
|
||||
|
||||
if (memberof || !enclosing) {
|
||||
// `this` refers to nearest non-inner member in the name path
|
||||
if (enclosingDoc && enclosingDoc.tagValue('kind') !== 'constructor') {
|
||||
var parts = memberof.split(/[#~.]/);
|
||||
var parts = memberof.split(/[#.~]/);
|
||||
var suffix = parts.pop();
|
||||
memberof = memberof.slice(0, -suffix.length); // remove suffix from memberof
|
||||
}
|
||||
|
||||
var joiner = (memberof === '')? '' : (/[#~.]$/.test(memberof))? '' : '#';
|
||||
var joiner = (memberof === '')? '' : (/[#.~]$/.test(memberof))? '' : '#';
|
||||
name = memberof + joiner + name.slice(5); // replace `this.` with memberof
|
||||
}
|
||||
}
|
||||
@ -276,7 +263,7 @@
|
||||
|
||||
return null;
|
||||
}
|
||||
// tuples, like [ [noderef, doclet], [noderef, doclet] ]
|
||||
// a linking map, like [ [noderef, doclet], [noderef, doclet] ]
|
||||
exports.refs = [];
|
||||
|
||||
function getTypeName(node) {
|
||||
|
||||
@ -62,7 +62,7 @@
|
||||
// this thing may have commented members, so keep a ref to the thing but don't add it to the doclets list
|
||||
thisDoclet = jsdoc.doclet.makeDoclet('[[undocumented]]', node, currentSourceName);
|
||||
|
||||
nodeName = jsdoc.name.resolveThis(node.name, node, thisDoclet);
|
||||
nodeName = jsdoc.name.resolvePath(node.name, node, thisDoclet);
|
||||
thisDoclet.setName(nodeName);
|
||||
jsdoc.name.refs.push([
|
||||
node,
|
||||
@ -97,7 +97,7 @@
|
||||
}
|
||||
|
||||
if (!thisDocletName) { // guess name from the source code
|
||||
nodeName = jsdoc.name.resolveThis(nodeName, node, thisDoclet);
|
||||
nodeName = jsdoc.name.resolvePath(nodeName, node, thisDoclet);
|
||||
|
||||
thisDoclet.setName(nodeName);
|
||||
jsdoc.doclets.addDoclet(thisDoclet);
|
||||
@ -109,7 +109,7 @@
|
||||
// this thing may have commented members, so keep a ref to the thing but don't add it to the doclets list
|
||||
|
||||
thisDoclet = jsdoc.doclet.makeDoclet('[[undocumented]]', node, currentSourceName);
|
||||
nodeName = jsdoc.name.resolveThis(nodeName, node, thisDoclet);
|
||||
nodeName = jsdoc.name.resolvePath(nodeName, node, thisDoclet);
|
||||
|
||||
thisDoclet.setName(nodeName);
|
||||
jsdoc.name.refs.push([
|
||||
|
||||
@ -33,7 +33,7 @@ exports.jsdocSchema = {
|
||||
"kind": {
|
||||
"type": "string",
|
||||
"maxItems": 1,
|
||||
"enum": ["constructor", "module", "event", "namespace", "method", "property", "enum", "class", "interface", "constant", "file", "version"]
|
||||
"enum": ["constructor", "module", "event", "namespace", "method", "property", "enum", "class", "interface", "constant", "mixin", "file", "version"]
|
||||
},
|
||||
"access": {
|
||||
"type": "string",
|
||||
|
||||
@ -135,6 +135,19 @@
|
||||
return false;
|
||||
}
|
||||
|
||||
function setTag(tagName, tagValue) {
|
||||
var i = this.length;
|
||||
while(i--) {
|
||||
if (this[i].name === tagName) {
|
||||
this[i].value = tagValue;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
this.addTag(tagName, tagValue);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
Given the source of a jsdoc comment, finds the tags.
|
||||
@private
|
||||
@ -146,6 +159,7 @@
|
||||
var tags = [];
|
||||
tags.addTag = addTag;
|
||||
tags.hasTag = hasTag;
|
||||
tags.setTag = setTag;
|
||||
|
||||
// split out the basic tags, keep surrounding whitespace
|
||||
commentSrc
|
||||
|
||||
@ -466,4 +466,12 @@
|
||||
new TagDefinition('see', {
|
||||
isExported: true
|
||||
});
|
||||
|
||||
/** Syntax: @refersto <text>
|
||||
@property {module:jsdoc/tagdictionary~TagDefinition} refersto
|
||||
@memberOf module:jsdoc/tagdictionary~tagDefinitions
|
||||
*/
|
||||
new TagDefinition('refersto', {
|
||||
isExported: true
|
||||
});
|
||||
})();
|
||||
19
test/samples/tag_name.js
Normal file
19
test/samples/tag_name.js
Normal file
@ -0,0 +1,19 @@
|
||||
/**
|
||||
@name Tipsy
|
||||
@kind property
|
||||
*/
|
||||
|
||||
/**
|
||||
@name Tubbie.LaLa
|
||||
@kind property
|
||||
*/
|
||||
|
||||
/**
|
||||
@name Tubbie."and.don't.forget#Po!"
|
||||
@kind property
|
||||
*/
|
||||
|
||||
/**
|
||||
@name Custards.0
|
||||
@kind property
|
||||
*/
|
||||
@ -10,7 +10,7 @@
|
||||
tag: require('jsdoc/tag'),
|
||||
parser: require('jsdoc/parser')
|
||||
};
|
||||
jsdoc.parser.parseFiles(BASEDIR + 'test/tests/08_tag_name.js');
|
||||
jsdoc.parser.parseFiles(BASEDIR + 'test/samples/tag_name.js');
|
||||
doclets = jsdoc.parser.result;
|
||||
});
|
||||
|
||||
@ -47,27 +47,3 @@
|
||||
});
|
||||
});
|
||||
})();
|
||||
|
||||
(function testarea() {
|
||||
|
||||
/**
|
||||
@name Tipsy
|
||||
@kind property
|
||||
*/
|
||||
|
||||
/**
|
||||
@name Tubbie.LaLa
|
||||
@kind property
|
||||
*/
|
||||
|
||||
/**
|
||||
@name Tubbie."and.don't.forget#Po!"
|
||||
@kind property
|
||||
*/
|
||||
|
||||
/**
|
||||
@name Custards.0
|
||||
@kind property
|
||||
*/
|
||||
|
||||
})();
|
||||
Loading…
x
Reference in New Issue
Block a user