131 lines
3.8 KiB
JavaScript
131 lines
3.8 KiB
JavaScript
/**
|
|
* @fileoverview Generates a closure compiler externs file for exportable
|
|
* symbols (those with an api tag) and boolean defines (with a define tag and a
|
|
* default value).
|
|
*/
|
|
var assert = require('assert');
|
|
var fs = require('fs');
|
|
var path = require('path');
|
|
|
|
|
|
/**
|
|
* Publish hook for the JSDoc template. Writes to stdout.
|
|
* @param {function} data The root of the Taffy DB containing doclet records.
|
|
* @param {Object} opts Options.
|
|
*/
|
|
exports.publish = function(data, opts) {
|
|
|
|
// get all doclets with the "api" property or define (excluding enums,
|
|
// typedefs and events)
|
|
var docs = data(
|
|
[{define: {isObject: true}}, {api: {isString: true}}],
|
|
{isEnum: {'!is': true}},
|
|
{kind: {'!is': 'typedef'}},
|
|
{kind: {'!is': 'event'}}).get();
|
|
|
|
// get symbols data, filter out those that are members of private classes
|
|
var output = [];
|
|
var namespaces = {};
|
|
var constructors = {};
|
|
docs.filter(function(doc) {
|
|
var include = true;
|
|
var constructor = doc.memberof;
|
|
if (constructor && constructor.substr(-1) === '_') {
|
|
assert.strictEqual(doc.inherited, true,
|
|
'Unexpected export on private class: ' + doc.longname);
|
|
include = false;
|
|
}
|
|
return include;
|
|
}).forEach(function(doc) {
|
|
|
|
var parts = doc.longname.split('#')[0].split('.');
|
|
parts.pop();
|
|
var namespace = [];
|
|
parts.forEach(function(part) {
|
|
namespace.push(part);
|
|
var partialNamespace = namespace.join('.');
|
|
if (!(partialNamespace in namespaces)) {
|
|
namespaces[partialNamespace] = true;
|
|
output.push('/**');
|
|
output.push(' * @type {Object}');
|
|
output.push(' */');
|
|
output.push(
|
|
(namespace.length == 1 ? 'var ' : '') + partialNamespace + ';');
|
|
output.push('');
|
|
}
|
|
});
|
|
|
|
var signature = doc.longname;
|
|
if (signature.indexOf('#') > 0) {
|
|
signature = doc.longname.replace('#', '.prototype.');
|
|
var constructor = doc.longname.split('#')[0];
|
|
if (!(constructor in constructors)) {
|
|
constructors[constructor] = true;
|
|
output.push('/**');
|
|
output.push(' * @constructor');
|
|
output.push(' */');
|
|
output.push(constructor + ' = function() {}');
|
|
output.push('');
|
|
}
|
|
}
|
|
|
|
output.push('/**');
|
|
if (doc.define) {
|
|
output.push(' * @define');
|
|
output.push(' * @type {boolean}');
|
|
output.push(' */');
|
|
output.push(doc.longname + ';');
|
|
} else {
|
|
if (doc.kind == 'class') {
|
|
output.push(' * @constructor');
|
|
}
|
|
if (doc.type) {
|
|
var types = [];
|
|
doc.type.names.forEach(function(name) {
|
|
types.push(name);
|
|
});
|
|
output.push(' * @type {' + types.join('|') + '}');
|
|
}
|
|
var args = [];
|
|
if (doc.params) {
|
|
doc.params.forEach(function(param) {
|
|
args.push(param.name);
|
|
var names = [];
|
|
param.type.names.forEach(function(name) {
|
|
names.push(name);
|
|
});
|
|
output.push(' * @param {' +
|
|
(param.variable ? '...' : '') +
|
|
names.join('|') +
|
|
(param.optional ? '=' : '') +
|
|
'} ' + param.name);
|
|
});
|
|
}
|
|
if (doc.returns) {
|
|
var returnTypes = [];
|
|
doc.returns[0].type.names.forEach(function(name) {
|
|
returnTypes.push(name);
|
|
});
|
|
output.push(' * @return {' + returnTypes.join('|') + '}');
|
|
}
|
|
if (doc.tags) {
|
|
doc.tags.forEach(function(tag) {
|
|
if (tag.title == 'template') {
|
|
output.push(' * @' + tag.title + ' ' + tag.value);
|
|
}
|
|
});
|
|
}
|
|
output.push(' */');
|
|
if (doc.kind == 'function' || doc.kind == 'class') {
|
|
output.push(signature + ' = function(' + args.join(', ') + ') {};');
|
|
} else {
|
|
output.push(signature);
|
|
}
|
|
}
|
|
output.push('');
|
|
});
|
|
|
|
process.stdout.write(output.join('\n'));
|
|
|
|
};
|