// Generated by generate-monoidal-reducer.js /** * Copyright 2018 Shape Security, Inc. * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ const Shift = require('shift-ast'); module.exports = class MonoidalReducer { constructor(monoid) { let identity = monoid.empty(); this.identity = identity; let concatThunk; if (monoid.prototype && typeof monoid.prototype.concatThunk === 'function') { concatThunk = Function.prototype.call.bind(monoid.prototype.concatThunk); } else if (typeof monoid.concatThunk === 'function') { concatThunk = monoid.concatThunk; } else { let concat; if (monoid.prototype && typeof monoid.prototype.concat === 'function') { concat = Function.prototype.call.bind(monoid.prototype.concat); } else if (typeof monoid.concat === 'function') { concat = monoid.concat; } else { throw new TypeError('Monoid must provide a `concatThunk` or `concat` method'); } if (typeof monoid.isAbsorbing === 'function') { let isAbsorbing = monoid.isAbsorbing; concatThunk = (a, b) => isAbsorbing(a) ? a : concat(a, b()); } else { concatThunk = (a, b) => concat(a, b()); } } this.append = (...args) => args.reduce(concatThunk, identity); } reduceArrayAssignmentTarget(node, { elements, rest }) { return this.append(...elements.filter(n => n != null), rest == null ? () => this.identity : rest); } reduceArrayBinding(node, { elements, rest }) { return this.append(...elements.filter(n => n != null), rest == null ? () => this.identity : rest); } reduceArrayExpression(node, { elements }) { return this.append(...elements.filter(n => n != null)); } reduceArrowExpression(node, { params, body }) { return this.append(params, body); } reduceAssignmentExpression(node, { binding, expression }) { return this.append(binding, expression); } reduceAssignmentTargetIdentifier(node) { return this.identity; } reduceAssignmentTargetPropertyIdentifier(node, { binding, init }) { return this.append(binding, init == null ? () => this.identity : init); } reduceAssignmentTargetPropertyProperty(node, { name, binding }) { return this.append(name, binding); } reduceAssignmentTargetWithDefault(node, { binding, init }) { return this.append(binding, init); } reduceAwaitExpression(node, { expression }) { return expression(); } reduceBinaryExpression(node, { left, right }) { return this.append(left, right); } reduceBindingIdentifier(node) { return this.identity; } reduceBindingPropertyIdentifier(node, { binding, init }) { return this.append(binding, init == null ? () => this.identity : init); } reduceBindingPropertyProperty(node, { name, binding }) { return this.append(name, binding); } reduceBindingWithDefault(node, { binding, init }) { return this.append(binding, init); } reduceBlock(node, { statements }) { return this.append(...statements); } reduceBlockStatement(node, { block }) { return block(); } reduceBreakStatement(node) { return this.identity; } reduceCallExpression(node, { callee, arguments: _arguments }) { return this.append(callee, ..._arguments); } reduceCatchClause(node, { binding, body }) { return this.append(binding == null ? () => this.identity : binding, body); } reduceClassDeclaration(node, { name, super: _super, elements }) { return this.append(name, _super == null ? () => this.identity : _super, ...elements); } reduceClassElement(node, { method }) { return method(); } reduceClassExpression(node, { name, super: _super, elements }) { return this.append(name == null ? () => this.identity : name, _super == null ? () => this.identity : _super, ...elements); } reduceCompoundAssignmentExpression(node, { binding, expression }) { return this.append(binding, expression); } reduceComputedMemberAssignmentTarget(node, { object, expression }) { return this.append(object, expression); } reduceComputedMemberExpression(node, { object, expression }) { return this.append(object, expression); } reduceComputedPropertyName(node, { expression }) { return expression(); } reduceConditionalExpression(node, { test, consequent, alternate }) { return this.append(test, consequent, alternate); } reduceContinueStatement(node) { return this.identity; } reduceDataProperty(node, { name, expression }) { return this.append(name, expression); } reduceDebuggerStatement(node) { return this.identity; } reduceDirective(node) { return this.identity; } reduceDoWhileStatement(node, { body, test }) { return this.append(body, test); } reduceEmptyStatement(node) { return this.identity; } reduceExport(node, { declaration }) { return declaration(); } reduceExportAllFrom(node) { return this.identity; } reduceExportDefault(node, { body }) { return body(); } reduceExportFrom(node, { namedExports }) { return this.append(...namedExports); } reduceExportFromSpecifier(node) { return this.identity; } reduceExportLocalSpecifier(node, { name }) { return name(); } reduceExportLocals(node, { namedExports }) { return this.append(...namedExports); } reduceExpressionStatement(node, { expression }) { return expression(); } reduceForAwaitStatement(node, { left, right, body }) { return this.append(left, right, body); } reduceForInStatement(node, { left, right, body }) { return this.append(left, right, body); } reduceForOfStatement(node, { left, right, body }) { return this.append(left, right, body); } reduceForStatement(node, { init, test, update, body }) { return this.append(init == null ? () => this.identity : init, test == null ? () => this.identity : test, update == null ? () => this.identity : update, body); } reduceFormalParameters(node, { items, rest }) { return this.append(...items, rest == null ? () => this.identity : rest); } reduceFunctionBody(node, { directives, statements }) { return this.append(...directives, ...statements); } reduceFunctionDeclaration(node, { name, params, body }) { return this.append(name, params, body); } reduceFunctionExpression(node, { name, params, body }) { return this.append(name == null ? () => this.identity : name, params, body); } reduceGetter(node, { name, body }) { return this.append(name, body); } reduceIdentifierExpression(node) { return this.identity; } reduceIfStatement(node, { test, consequent, alternate }) { return this.append(test, consequent, alternate == null ? () => this.identity : alternate); } reduceImport(node, { defaultBinding, namedImports }) { return this.append(defaultBinding == null ? () => this.identity : defaultBinding, ...namedImports); } reduceImportNamespace(node, { defaultBinding, namespaceBinding }) { return this.append(defaultBinding == null ? () => this.identity : defaultBinding, namespaceBinding); } reduceImportSpecifier(node, { binding }) { return binding(); } reduceLabeledStatement(node, { body }) { return body(); } reduceLiteralBooleanExpression(node) { return this.identity; } reduceLiteralInfinityExpression(node) { return this.identity; } reduceLiteralNullExpression(node) { return this.identity; } reduceLiteralNumericExpression(node) { return this.identity; } reduceLiteralRegExpExpression(node) { return this.identity; } reduceLiteralStringExpression(node) { return this.identity; } reduceMethod(node, { name, params, body }) { return this.append(name, params, body); } reduceModule(node, { directives, items }) { return this.append(...directives, ...items); } reduceNewExpression(node, { callee, arguments: _arguments }) { return this.append(callee, ..._arguments); } reduceNewTargetExpression(node) { return this.identity; } reduceObjectAssignmentTarget(node, { properties, rest }) { return this.append(...properties, rest == null ? () => this.identity : rest); } reduceObjectBinding(node, { properties, rest }) { return this.append(...properties, rest == null ? () => this.identity : rest); } reduceObjectExpression(node, { properties }) { return this.append(...properties); } reduceReturnStatement(node, { expression }) { return expression == null ? this.identity : expression(); } reduceScript(node, { directives, statements }) { return this.append(...directives, ...statements); } reduceSetter(node, { name, param, body }) { return this.append(name, param, body); } reduceShorthandProperty(node, { name }) { return name(); } reduceSpreadElement(node, { expression }) { return expression(); } reduceSpreadProperty(node, { expression }) { return expression(); } reduceStaticMemberAssignmentTarget(node, { object }) { return object(); } reduceStaticMemberExpression(node, { object }) { return object(); } reduceStaticPropertyName(node) { return this.identity; } reduceSuper(node) { return this.identity; } reduceSwitchCase(node, { test, consequent }) { return this.append(test, ...consequent); } reduceSwitchDefault(node, { consequent }) { return this.append(...consequent); } reduceSwitchStatement(node, { discriminant, cases }) { return this.append(discriminant, ...cases); } reduceSwitchStatementWithDefault(node, { discriminant, preDefaultCases, defaultCase, postDefaultCases }) { return this.append(discriminant, ...preDefaultCases, defaultCase, ...postDefaultCases); } reduceTemplateElement(node) { return this.identity; } reduceTemplateExpression(node, { tag, elements }) { return this.append(tag == null ? () => this.identity : tag, ...elements); } reduceThisExpression(node) { return this.identity; } reduceThrowStatement(node, { expression }) { return expression(); } reduceTryCatchStatement(node, { body, catchClause }) { return this.append(body, catchClause); } reduceTryFinallyStatement(node, { body, catchClause, finalizer }) { return this.append(body, catchClause == null ? () => this.identity : catchClause, finalizer); } reduceUnaryExpression(node, { operand }) { return operand(); } reduceUpdateExpression(node, { operand }) { return operand(); } reduceVariableDeclaration(node, { declarators }) { return this.append(...declarators); } reduceVariableDeclarationStatement(node, { declaration }) { return declaration(); } reduceVariableDeclarator(node, { binding, init }) { return this.append(binding, init == null ? () => this.identity : init); } reduceWhileStatement(node, { test, body }) { return this.append(test, body); } reduceWithStatement(node, { object, body }) { return this.append(object, body); } reduceYieldExpression(node, { expression }) { return expression == null ? this.identity : expression(); } reduceYieldGeneratorExpression(node, { expression }) { return expression(); } };