Greatly simplify and document the usage of JSDoc
This commit simplifies the exports.js plugin so it only relies on the stability notes to generate the documentation, which completely decouples it from the exportable API. As a rule of thumb, whenever something has an 'api' annotation, it should also have a 'stability' annotation. A more verbose documentation of ol3 specific annotation usage is available in the new 'apidoc/readme.md' file. This commit also modifies all source files to implement these usage suggestions.
This commit is contained in:
committed by
Tim Schaub
parent
aaf6101d0f
commit
c17ac0cae3
51
apidoc/plugins/api.js
Normal file
51
apidoc/plugins/api.js
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Based on @stability annotations, and assuming that items with no @stability
|
||||
* annotation should not be documented, this plugin removes undocumented symbols
|
||||
* from the documentation. Undocumented classes with documented members get a
|
||||
* 'hideConstructur' property, which is read by the template so it can hide the
|
||||
* constructor.
|
||||
*/
|
||||
|
||||
function hasApiMembers(doclet) {
|
||||
return doclet.longname.split('#')[0] == this.longname;
|
||||
}
|
||||
|
||||
var api = [];
|
||||
|
||||
exports.handlers = {
|
||||
|
||||
newDoclet: function(e) {
|
||||
var doclet = e.doclet;
|
||||
// Keep track of api items - needed in parseComplete to determine classes
|
||||
// with api members.
|
||||
if (doclet.stability) {
|
||||
api.push(doclet);
|
||||
}
|
||||
// Mark explicity defined namespaces - needed in parseComplete to keep
|
||||
// namespaces that we need as containers for api items.
|
||||
if (/.*\.jsdoc$/.test(doclet.meta.filename) && doclet.kind == 'namespace') {
|
||||
doclet.namespace_ = true;
|
||||
}
|
||||
},
|
||||
|
||||
parseComplete: function(e) {
|
||||
var doclets = e.doclets;
|
||||
for (var i = doclets.length - 1; i >= 0; --i) {
|
||||
var doclet = doclets[i];
|
||||
// Always document namespaces and items with stability annotation
|
||||
if (doclet.stability || doclet.namespace_) {
|
||||
continue;
|
||||
}
|
||||
if (doclet.kind == 'class' && api.some(hasApiMembers, doclet)) {
|
||||
// Mark undocumented classes with documented members as unexported.
|
||||
// This is used in ../template/tmpl/container.tmpl to hide the
|
||||
// constructor from the docs.
|
||||
doclet.hideConstructor = true;
|
||||
} else {
|
||||
// Remove all other undocumented symbols
|
||||
doclets.splice(i, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
@@ -1,109 +0,0 @@
|
||||
/*
|
||||
* This plugin removes unexported symbols from the documentation.
|
||||
* Unexported modules linked from @param or @fires will be marked unexported,
|
||||
* and the documentation will not contain the constructor. Everything else is
|
||||
* marked undocumented, which will remove it from the docs.
|
||||
*/
|
||||
|
||||
var api = [];
|
||||
var unexported = [];
|
||||
var observablesByClass = {};
|
||||
|
||||
function collectExports(source) {
|
||||
var symbols = JSON.parse(source).symbols;
|
||||
for (var i = 0, ii = symbols.length; i < ii; ++i) {
|
||||
api.push(symbols[i].name);
|
||||
}
|
||||
}
|
||||
|
||||
var encoding = env.conf.encoding || 'utf8';
|
||||
var fs = require('jsdoc/fs');
|
||||
collectExports(fs.readFileSync('build/symbols.json', encoding));
|
||||
|
||||
|
||||
exports.handlers = {
|
||||
|
||||
newDoclet: function(e) {
|
||||
var i, ii, j, jj;
|
||||
if (e.doclet.meta.filename == "olx.js" && e.doclet.longname != 'olx') {
|
||||
api.push(e.doclet.longname);
|
||||
}
|
||||
if (e.doclet.longname.indexOf('oli.') === 0) {
|
||||
unexported.push(e.doclet.longname.replace(/^oli\./, 'ol.'));
|
||||
}
|
||||
if (api.indexOf(e.doclet.longname) > -1) {
|
||||
var names, name;
|
||||
var params = e.doclet.params;
|
||||
if (params) {
|
||||
for (i = 0, ii = params.length; i < ii; ++i) {
|
||||
names = params[i].type.names;
|
||||
if (names) {
|
||||
for (j = 0, jj=names.length; j < jj; ++j) {
|
||||
name = names[j];
|
||||
if (unexported.indexOf(name) === -1) {
|
||||
unexported.push(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var links = e.doclet.comment.match(/\{@link ([^\}]*)\}/g);
|
||||
if (links) {
|
||||
for (i=0, ii=links.length; i < ii; ++i) {
|
||||
var link = links[i].match(/\{@link (.*)\}/)[1];
|
||||
if (unexported.indexOf(link) === -1) {
|
||||
unexported.push(link);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (e.doclet.observables) {
|
||||
var observables = observablesByClass[e.doclet.longname] = [];
|
||||
for (i = e.doclet.observables.length - 1; i >= 0; --i) {
|
||||
observables.push(e.doclet.observables[i].name);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
parseComplete: function(e) {
|
||||
for (var j = e.doclets.length - 1; j >= 0; --j) {
|
||||
var doclet = e.doclets[j];
|
||||
if (doclet.meta.filename == 'olx.js' && doclet.kind == 'typedef') {
|
||||
for (var i = e.doclets.length - 1; i >= 0; --i) {
|
||||
var propertyDoclet = e.doclets[i];
|
||||
if (propertyDoclet.memberof == doclet.longname) {
|
||||
if (!doclet.properties) {
|
||||
doclet.properties = [];
|
||||
}
|
||||
doclet.properties.unshift(propertyDoclet);
|
||||
e.doclets.splice(i, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (doclet.kind == 'namespace' || doclet.kind == 'event' || doclet.fires) {
|
||||
continue;
|
||||
}
|
||||
var fqn = doclet.longname;
|
||||
if (fqn) {
|
||||
var getterOrSetter = fqn.match(/([^#]*)#[gs]et(.*)/);
|
||||
if (getterOrSetter) {
|
||||
var observables = observablesByClass[getterOrSetter[1]];
|
||||
if (observables && observables.indexOf(getterOrSetter[2].toLowerCase()) > -1) {
|
||||
// Always document getters/setters of observables
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (doclet.memberof && doclet.memberof.indexOf('oli.') === 0 &&
|
||||
unexported.indexOf(doclet.memberof) > -1) {
|
||||
// Always document members of referenced oli interfaces
|
||||
continue;
|
||||
}
|
||||
doclet.unexported = (api.indexOf(fqn) === -1 && unexported.indexOf(fqn) !== -1);
|
||||
if (api.indexOf(fqn) === -1 && unexported.indexOf(fqn) === -1) {
|
||||
e.doclets.splice(j, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
@@ -10,13 +10,16 @@ exports.defineTags = function(dictionary) {
|
||||
}
|
||||
});
|
||||
|
||||
var augmentsTag = dictionary.lookUp('augments');
|
||||
dictionary.defineTag('implements', {
|
||||
mustHaveValue: true,
|
||||
onTagged: function(doclet, tag) {
|
||||
tag.value = tag.value.match(/^\{?([^\}]*)\}?$/)[1];
|
||||
augmentsTag.onTagged.apply(this, arguments);
|
||||
if (!doclet.implements) {
|
||||
doclet.implements = [];
|
||||
}
|
||||
doclet.implements.push(tag.value.match(/^{(.*)}$/)[1]);
|
||||
doclet.implements.push(tag.value);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
23
apidoc/plugins/olx-typedefs.js
Normal file
23
apidoc/plugins/olx-typedefs.js
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Converts olx.js @type annotations into properties of the previous @typedef.
|
||||
*/
|
||||
|
||||
var olxTypedef = null;
|
||||
|
||||
exports.handlers = {
|
||||
|
||||
newDoclet: function(e) {
|
||||
var doclet = e.doclet;
|
||||
if (doclet.meta.filename == 'olx.js') {
|
||||
if (doclet.kind == 'typedef') {
|
||||
olxTypedef = doclet;
|
||||
doclet.properties = [];
|
||||
} else if (olxTypedef && doclet.memberof == olxTypedef.longname) {
|
||||
olxTypedef.properties.push(doclet);
|
||||
} else {
|
||||
olxTypedef = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
Reference in New Issue
Block a user