UNPKG

dgeni-packages

Version:

A collection of dgeni packages for generating documentation from source code

113 lines (101 loc) 3.16 kB
// Much of this code was inspired by or simply copied from the JSDOC project. // See https://github.com/jsdoc3/jsdoc/blob/c9b0237c12144cfa48abe5fccd73ba2a1d46553a/lib/jsdoc/tag/type.js const catharsis = require('catharsis'); var TYPE_EXPRESSION_START = /^\s*\{[^@]/; /** * Extract a type expression from the tag text. * * @private * @param {Tag} tag The tag whose type should be extracted */ module.exports = function extractTypeTransform() { return (doc, tag, value) => { let start, position, count, length, expression; const match = TYPE_EXPRESSION_START.exec(value); if (match) { length = value.length; // the start is the beginning of the `{` start = match[0].length - 2; // advance to the first character in the type expression position = match[0].length - 1; count = 1; while (position < length) { switch (value[position]) { case '\\': // backslash is an escape character, so skip the next character position++; break; case '{': count++; break; case '}': count--; break; default: // do nothing } if (count === 0) { break; } position++; } tag.typeExpression = value.slice(start+1, position).trim().replace('\\}', '}').replace('\\{', '{'); try { tag.type = catharsis.parse(tag.typeExpression, {jsdoc: true}); tag.typeList = getTypeStrings(tag.type); if ( tag.type.optional ) { tag.optional = true; } tag.description = (value.substring(0, start) + value.substring(position+1)).trim(); } catch(x) { console.log(tag); throw new Error('Error parsing the jsdoc type expression "{' + tag.typeExpression + '}"', x); } return tag.description; } else { return value; } }; /** @private */ function getTypeStrings(parsedType) { const types = []; const TYPES = catharsis.Types; const util = require('util'); switch(parsedType.type) { case TYPES.AllLiteral: types.push('*'); break; case TYPES.FunctionType: types.push(catharsis.stringify(parsedType)); break; case TYPES.NameExpression: types.push(parsedType.name); break; case TYPES.NullLiteral: types.push('null'); break; case TYPES.RecordType: types.push(catharsis.stringify(parsedType)); break; case TYPES.TypeApplication: types.push( catharsis.stringify(parsedType) ); break; case TYPES.TypeUnion: parsedType.elements.forEach(element => { types.push(...getTypeStrings(element)); }); break; case TYPES.UndefinedLiteral: types.push('undefined'); break; case TYPES.UnknownLiteral: types.push('?'); break; default: // this shouldn't happen throw new Error( util.format('unrecognized type %s in parsed type: %j', parsedType.type, parsedType) ); } return types; } };