UNPKG

nimma

Version:

Scalable JSONPath engine.

139 lines (122 loc) 4.28 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var builders = require('../ast/builders.cjs'); var dump = require('../dump.cjs'); var allocState = require('../templates/alloc-state.cjs'); var internalScope = require('../templates/internal-scope.cjs'); var scope = require('../templates/scope.cjs'); var treeMethod = require('../templates/tree-method.cjs'); var treeMethodCall = require('../templates/tree-method-call.cjs'); var consts = require('./consts.cjs'); var commonjs = require('./modules/commonjs.cjs'); var esm = require('./modules/esm.cjs'); var traversalZones = require('./traversal-zones.cjs'); const DEFAULT_PARAMS = [builders.identifier('input'), builders.identifier('callbacks')]; const NEW_SCOPE_VARIABLE_DECLARATION = builders.variableDeclaration('const', [ builders.variableDeclarator( scope.default._, builders.newExpression(builders.identifier('Scope'), DEFAULT_PARAMS), ), ]); class ESTree { #tree = builders.objectExpression([]); #hasShorthands = false; #runtimeDependencies; #traverse = []; #states = -1; constructor() { this.body = []; this.traversalZones = new traversalZones.default(); this.#runtimeDependencies = new Map([['Scope', 'Scope']]); } /** * @param {string} specifier */ addRuntimeDependency(specifier) { this.#runtimeDependencies.set(specifier, specifier); } /** * @param hash * @returns {*} */ getMethodByHash(hash) { return this.#tree.properties.find(prop => prop.key.value === hash); } /** * @param {Object} id * @param {'StringLiteral'} id.type * @param {string} id.value * @param {Object} block * @param {number} feedback */ addTreeMethod(id, block, feedback) { let state; if ((feedback & consts.NEEDS_STATE) > 0) { state = allocState.default(++this.#states); this.body.push(state); } else { state = null; } const needsShorthands = (feedback & consts.NEEDS_SHORTHANDS) > 0; this.#hasShorthands ||= needsShorthands; this.#tree.properties.push(treeMethod.default(id, block, feedback)); const call = treeMethodCall.generateTreeMethodCall(id, state, needsShorthands); ((feedback & consts.NEEDS_TRAVERSAL) > 0 ? this.#traverse : this.body).push(call); } /** * Generates JS code based on the underlying ESTree * @param {'esm'|'commonjs'} format * @returns {string} */ export(format) { const traversalZones = this.traversalZones.build(); const params = this.#hasShorthands ? [...DEFAULT_PARAMS, internalScope.default.shorthands] : DEFAULT_PARAMS; const program = builders.program( [ traversalZones, this.#tree.properties.length === 0 ? null : builders.variableDeclaration('const', [ builders.variableDeclarator(internalScope.default.tree, this.#tree), ]), builders.functionDeclaration( null, params, builders.blockStatement([ NEW_SCOPE_VARIABLE_DECLARATION, builders.tryStatement( builders.blockStatement( [ ...this.body, this.#traverse.length === 0 ? null : builders.expressionStatement( builders.callExpression(scope.default.traverse, [ builders.arrowFunctionExpression( [], builders.blockStatement(Array.from(this.#traverse)), ), traversalZones === null ? builders.nullLiteral() : traversalZones.declarations[0].id, ]), ), ].filter(Boolean), ), null, builders.blockStatement([ builders.expressionStatement(builders.callExpression(scope.default.destroy, [])), ]), ), ]), ), ].filter(Boolean), ); const mod = format === 'esm' ? esm.default : commonjs.default; mod(Array.from(this.#runtimeDependencies), program); return dump.default(program); } } exports.default = ESTree;