Files
openlayers/config/jsdoc/info/module-plugin.js
2018-06-12 07:59:20 -06:00

136 lines
3.4 KiB
JavaScript

const path = require('path');
const exportLookup = {};
const moduleLookup = {};
const MODULE_PATH = /^module:(.*)~(\w+)$/;
/**
* Add exports to modules.
*/
exports.handlers = {
symbolFound(event) {
const filename = event.filename;
const node = event.astnode;
let local, exported;
switch (node.type) {
case 'ExportDefaultDeclaration': {
exported = 'default';
switch (node.declaration.type) {
case 'Identifier': {
// export default foo;
local = node.declaration.name;
break;
}
case 'FunctionDeclaration': {
if (!node.declaration.id) {
// export default function() {}
local = '';
} else {
// export default function foo() {}
local = node.declaration.id.name;
}
break;
}
default: {
local = '';
}
}
break;
}
case 'ExportNamedDeclaration': {
if (!node.declaration) {
// export {foo}
// export {foo as bar}
// handled below in ExportSpecifier
return;
}
switch (node.declaration.type) {
case 'FunctionDeclaration': {
if (!node.declaration.id) {
throw new Error(`Expected function declaration to have an id in ${filename}`);
}
const name = node.declaration.id.name;
local = name;
exported = name;
break;
}
default: {
return;
}
}
break;
}
case 'ExportSpecifier': {
if (node.exported.type === 'Identifier') {
exported = node.exported.name;
if (node.local.type === 'Identifier') {
local = node.local.name;
if (node.parent.source) {
const resolved = path.resolve(path.dirname(filename), node.parent.source.value);
local = `module:${resolved}~${local}`;
}
} else {
local = '';
}
} else {
return;
}
break;
}
default: {
return;
}
}
if (!(filename in exportLookup)) {
exportLookup[filename] = {};
}
const exports = exportLookup[filename];
if (exports.hasOwnProperty(exported)) {
throw new Error(`Duplicate export {${local} as ${exported}} in ${filename}`);
}
exports[exported] = local;
},
newDoclet(event) {
const doclet = event.doclet;
if (doclet.kind === 'module') {
const filepath = path.join(doclet.meta.path, doclet.meta.filename);
if (filepath in moduleLookup) {
throw new Error(`Duplicate @module annotation in ${filepath}`);
}
moduleLookup[filepath] = doclet;
}
},
parseComplete(event) {
for (const filepath in moduleLookup) {
const doclet = moduleLookup[filepath];
const exports = exportLookup[filepath];
for (const exported in exports) {
const local = exports[exported];
const match = local.match(MODULE_PATH);
if (match) {
const filepath = match[1];
const mod = moduleLookup[filepath];
if (mod) {
exports[exported] = `module:${mod.name}~${match[2]}`;
}
}
}
doclet.exports = exports; // undefined if no exports
}
}
};