123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- /**
- * Catharsis
- * A parser for Google Closure Compiler type expressions, powered by PEG.js.
- *
- * @author Jeff Williams <jeffrey.l.williams@gmail.com>
- * @license MIT
- */
- const describe = require('./lib/describe');
- const { parse } = require('./lib/parser');
- const stringify = require('./lib/stringify');
- const typeExpressionCache = {
- normal: new Map(),
- jsdoc: new Map()
- };
- const parsedTypeCache = {
- normal: new Map(),
- htmlSafe: new Map()
- };
- const descriptionCache = {
- normal: new Map()
- };
- function getTypeExpressionCache({useCache, jsdoc}) {
- if (useCache === false) {
- return null;
- } else if (jsdoc === true) {
- return typeExpressionCache.jsdoc;
- } else {
- return typeExpressionCache.normal;
- }
- }
- function getParsedTypeCache({useCache, links, htmlSafe}) {
- if (useCache === false || links !== null || links !== undefined) {
- return null;
- } else if (htmlSafe === true) {
- return parsedTypeCache.htmlSafe;
- } else {
- return parsedTypeCache.normal;
- }
- }
- function getDescriptionCache({useCache, links}) {
- if (useCache === false || links !== null || links !== undefined) {
- return null;
- } else {
- return descriptionCache.normal;
- }
- }
- // can't return the original if any of the following are true:
- // 1. restringification was requested
- // 2. htmlSafe option was requested
- // 3. links option was provided
- // 4. typeExpression property is missing
- function canReturnOriginalExpression(parsedType, {restringify, htmlSafe, links}) {
- return restringify !== true && htmlSafe !== true &&
- (links === null || links === undefined) &&
- Object.prototype.hasOwnProperty.call(parsedType, 'typeExpression');
- }
- // Add non-enumerable properties to a result object, then freeze it.
- function prepareFrozenObject(obj, expr, {jsdoc}) {
- Object.defineProperty(obj, 'jsdoc', {
- value: jsdoc === true ? jsdoc : false
- });
- if (expr) {
- Object.defineProperty(obj, 'typeExpression', {
- value: expr
- });
- }
- return Object.freeze(obj);
- }
- function cachedParse(expr, options) {
- const cache = getTypeExpressionCache(options);
- let parsedType = cache ? cache.get(expr) : null;
- if (parsedType) {
- return parsedType;
- } else {
- parsedType = parse(expr, options);
- parsedType = prepareFrozenObject(parsedType, expr, options);
- if (cache) {
- cache.set(expr, parsedType);
- }
- return parsedType;
- }
- }
- function cachedStringify(parsedType, options) {
- const cache = getParsedTypeCache(options);
- let stringified;
- if (canReturnOriginalExpression(parsedType, options)) {
- return parsedType.typeExpression;
- } else if (cache) {
- stringified = cache.get(parsedType);
- if (!stringified) {
- stringified = stringify(parsedType, options);
- cache.set(parsedType, stringified);
- }
- return stringified;
- } else {
- return stringify(parsedType, options);
- }
- }
- function cachedDescribe(parsedType, options) {
- const cache = getDescriptionCache(options);
- let description = cache ? cache.get(parsedType) : null;
- if (description) {
- return description;
- } else {
- description = describe(parsedType, options);
- description = prepareFrozenObject(description, null, options);
- if (cache) {
- cache.set(parsedType, description);
- }
- return description;
- }
- }
- /* eslint-disable class-methods-use-this */
- class Catharsis {
- constructor() {
- this.Types = require('./lib/types');
- }
- parse(typeExpr, options = {}) {
- typeExpr = typeExpr.replace(/[\r\n]/g, '')
- .replace(/\s+/g, ' ')
- .trim();
- return cachedParse(typeExpr, options);
- }
- stringify(parsedType, options) {
- let result;
- options = options || {};
- result = cachedStringify(parsedType, options);
- if (options.validate) {
- this.parse(result, options);
- }
- return result;
- }
- describe(parsedType, options = {}) {
- return cachedDescribe(parsedType, options);
- }
- }
- /* eslint-enable class-methods-use-this */
- module.exports = new Catharsis();
|