Spaces:
Paused
Paused
File size: 4,287 Bytes
e43bcd4 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
/**
* 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();
|