diff --git a/src/print/handlers.js b/src/print/handlers.js index 9603f88..64ce576 100644 --- a/src/print/handlers.js +++ b/src/print/handlers.js @@ -1,3 +1,4 @@ +import { push_array } from '../utils/push_array'; // heavily based on https://github.com/davidbonnet/astring // released under MIT license https://github.com/davidbonnet/astring/blob/master/LICENSE @@ -248,7 +249,7 @@ const join = (nodes, separator) => { const joined = [...nodes[0]]; for (let i = 1; i < nodes.length; i += 1) { - joined.push(separator, ...nodes[i]); + push_array(joined, [separator], nodes[i]); } return joined; }; @@ -326,8 +327,8 @@ const handle_body = (nodes, state) => { ); } - chunks.push( - ...body[i] + push_array(chunks, + body[i] ); needed_padding = needs_padding; @@ -356,10 +357,10 @@ const handle_var_declaration = (node, state) => { const separator = c(multiple_lines ? `,\n${state.indent}\t` : ', '); if (multiple_lines) { - chunks.push(...join(declarators, separator)); + push_array(chunks, join(declarators, separator)); } else { - chunks.push( - ...join(declarators, separator) + push_array(chunks, + join(declarators, separator) ); } @@ -416,9 +417,9 @@ const handlers = { ]; if (node.alternate) { - chunks.push( - c(' else '), - ...handle(node.alternate, state) + push_array(chunks, + [c(' else ')], + handle(node.alternate, state) ); } @@ -463,19 +464,19 @@ const handlers = { node.cases.forEach(block => { if (block.test) { - chunks.push( - c(`\n${state.indent}\tcase `), - ...handle(block.test, { ...state, indent: `${state.indent}\t` }), - c(':') + push_array(chunks, + [c(`\n${state.indent}\tcase `)], + handle(block.test, { ...state, indent: `${state.indent}\t` }), + [c(':')] ); } else { chunks.push(c(`\n${state.indent}\tdefault:`)) } block.consequent.forEach(statement => { - chunks.push( - c(`\n${state.indent}\t\t`), - ...handle(statement, { ...state, indent: `${state.indent}\t\t` }) + push_array(chunks, + [c(`\n${state.indent}\t\t`)], + handle(statement, { ...state, indent: `${state.indent}\t\t` }) ); }); }); @@ -513,20 +514,20 @@ const handlers = { if (node.handler) { if (node.handler.param) { - chunks.push( - c(' catch('), - ...handle(node.handler.param, state), - c(') ') + push_array(chunks, + [c(' catch(')], + handle(node.handler.param, state), + [c(') ')] ); } else { chunks.push(c(' catch ')); } - chunks.push(...handle(node.handler.body, state)); + push_array(chunks, handle(node.handler.body, state)); } if (node.finalizer) { - chunks.push(c(' finally '), ...handle(node.finalizer, state)); + push_array(chunks, [c(' finally ')], handle(node.finalizer, state)); } return chunks; @@ -556,20 +557,20 @@ const handlers = { if (node.init) { if (node.init.type === 'VariableDeclaration') { - chunks.push(...handle_var_declaration(node.init, state)); + push_array(chunks, handle_var_declaration(node.init, state)); } else { - chunks.push(...handle(node.init, state)); + push_array(chunks, handle(node.init, state)); } } chunks.push(c('; ')); - if (node.test) chunks.push(...handle(node.test, state)); + if (node.test) push_array(chunks, handle(node.test, state)); chunks.push(c('; ')); - if (node.update) chunks.push(...handle(node.update, state)); + if (node.update) push_array(chunks, handle(node.update, state)); - chunks.push( - c(') '), - ...handle(node.body, state) + push_array(chunks, + [c(') ')], + handle(node.body, state) ); return chunks; @@ -581,16 +582,16 @@ const handlers = { ]; if (node.left.type === 'VariableDeclaration') { - chunks.push(...handle_var_declaration(node.left, state)); + push_array(chunks, handle_var_declaration(node.left, state)); } else { - chunks.push(...handle(node.left, state)); + push_array(chunks, handle(node.left, state)); } - chunks.push( - c(node.type === 'ForInStatement' ? ` in ` : ` of `), - ...handle(node.right, state), - c(') '), - ...handle(node.body, state) + push_array(chunks, + [c(node.type === 'ForInStatement' ? ` in ` : ` of `)], + handle(node.right, state), + [c(') ')], + handle(node.body, state) ); return chunks; @@ -605,7 +606,7 @@ const handlers = { if (node.async) chunks.push(c('async ')); chunks.push(c(node.generator ? 'function* ' : 'function ')); - if (node.id) chunks.push(...handle(node.id, state)); + if (node.id) push_array(chunks, handle(node.id, state)); chunks.push(c('(')); const params = node.params.map(p => handle(p, { @@ -621,20 +622,20 @@ const handlers = { const separator = c(multiple_lines ? `,\n${state.indent}` : ', '); if (multiple_lines) { - chunks.push( - c(`\n${state.indent}\t`), - ...join(params, separator), - c(`\n${state.indent}`) + push_array(chunks, + [c(`\n${state.indent}\t`)], + join(params, separator), + [c(`\n${state.indent}`)] ); } else { - chunks.push( - ...join(params, separator) + push_array(chunks, + join(params, separator) ); } - chunks.push( - c(') '), - ...handle(node.body, state) + push_array(chunks, + [c(') ')], + handle(node.body, state) ); return chunks; @@ -659,17 +660,17 @@ const handlers = { ClassDeclaration(node, state) { const chunks = [c('class ')]; - if (node.id) chunks.push(...handle(node.id, state), c(' ')); + if (node.id) push_array(chunks, handle(node.id, state), [c(' ')]); if (node.superClass) { - chunks.push( - c('extends '), - ...handle(node.superClass, state), - c(' ') + push_array(chunks, + [c('extends ')], + handle(node.superClass, state), + [c(' ')] ); } - chunks.push(...handle(node.body, state)); + push_array(chunks, handle(node.body, state)); return chunks; }, @@ -717,16 +718,16 @@ const handlers = { const width = get_length(chunks) + specifiers.map(get_length).reduce(sum, 0) + (2 * specifiers.length) + 6 + get_length(source); if (width > 80) { - chunks.push( - c(`{\n\t`), - ...join(specifiers, c(',\n\t')), - c('\n}') + push_array(chunks, + [c(`{\n\t`)], + join(specifiers, c(',\n\t')), + [c('\n}')] ); } else { - chunks.push( - c(`{ `), - ...join(specifiers, c(', ')), - c(' }') + push_array(chunks, + [c(`{ `)], + join(specifiers, c(', ')), + [c(' }')] ); } } @@ -734,9 +735,9 @@ const handlers = { chunks.push(c(' from ')); } - chunks.push( - ...source, - c(';') + push_array(chunks, + source, + [c(';')] ); return chunks; @@ -763,7 +764,7 @@ const handlers = { const chunks = [c('export ')]; if (node.declaration) { - chunks.push(...handle(node.declaration, state)); + push_array(chunks, handle(node.declaration, state)); } else { const specifiers = node.specifiers.map((/** @type {ExportSpecifier} */ specifier) => { const name = handle(specifier.local, state)[0]; @@ -779,23 +780,23 @@ const handlers = { const width = 7 + specifiers.map(get_length).reduce(sum, 0) + 2 * specifiers.length; if (width > 80) { - chunks.push( - c('{\n\t'), - ...join(specifiers, c(',\n\t')), - c('\n}') + push_array(chunks, + [c('{\n\t')], + join(specifiers, c(',\n\t')), + [c('\n}')] ); } else { - chunks.push( - c('{ '), - ...join(specifiers, c(', ')), - c(' }') + push_array(chunks, + [c('{ ')], + join(specifiers, c(', ')), + [c(' }')] ); } if (node.source) { - chunks.push( - c(' from '), - ...handle(node.source, state) + push_array(chunks, + [c(' from ')], + handle(node.source, state) ); } } @@ -834,26 +835,26 @@ const handlers = { } if (node.computed) { - chunks.push( - c('['), - ...handle(node.key, state), - c(']') + push_array(chunks, + [c('[')], + handle(node.key, state), + [c(']')] ); } else { - chunks.push(...handle(node.key, state)); + push_array(chunks, handle(node.key, state)); } chunks.push(c('(')); const { params } = node.value; for (let i = 0; i < params.length; i += 1) { - chunks.push(...handle(params[i], state)); + push_array(chunks, handle(params[i], state)); if (i < params.length - 1) chunks.push(c(', ')); } - chunks.push( - c(') '), - ...handle(node.value.body, state) + push_array(chunks, + [c(') ')], + handle(node.value.body, state) ); return chunks; @@ -865,30 +866,30 @@ const handlers = { if (node.async) chunks.push(c('async ')); if (node.params.length === 1 && node.params[0].type === 'Identifier') { - chunks.push(...handle(node.params[0], state)); + push_array(chunks, handle(node.params[0], state)); } else { const params = node.params.map(param => handle(param, { ...state, indent: state.indent + '\t' })); - chunks.push( - c('('), - ...join(params, c(', ')), - c(')') + push_array(chunks, + [c('(')], + join(params, c(', ')), + [c(')')] ); } chunks.push(c(' => ')); if (node.body.type === 'ObjectExpression') { - chunks.push( - c('('), - ...handle(node.body, state), - c(')') + push_array(chunks, + [c('(')], + handle(node.body, state), + [c(')')] ); } else { - chunks.push(...handle(node.body, state)); + push_array(chunks, handle(node.body, state)); } return chunks; @@ -934,11 +935,11 @@ const handlers = { const { quasis, expressions } = node; for (let i = 0; i < expressions.length; i++) { - chunks.push( - c(quasis[i].value.raw), - c('${'), - ...handle(expressions[i], state), - c('}') + push_array(chunks, + [c(quasis[i].value.raw)], + [c('${')], + handle(expressions[i], state), + [c('}')] ); } @@ -983,14 +984,14 @@ const handlers = { ); if (multiple_lines) { - chunks.push( - c(`\n${state.indent}\t`), - ...join(elements, c(`,\n${state.indent}\t`)), - c(`\n${state.indent}`), - ...sparse_commas + push_array(chunks, + [c(`\n${state.indent}\t`)], + join(elements, c(`,\n${state.indent}\t`)), + [c(`\n${state.indent}`)], + sparse_commas ); } else { - chunks.push(...join(elements, c(', ')), ...sparse_commas); + push_array(chunks, join(elements, c(', ')), sparse_commas); } chunks.push(c(']')); @@ -1010,7 +1011,7 @@ const handlers = { const separator = c(', '); node.properties.forEach((p, i) => { - chunks.push(...handle(p, { + push_array(chunks, handle(p, { ...state, indent: state.indent + '\t' })); @@ -1098,12 +1099,12 @@ const handlers = { chunks.push(c('*')); } - chunks.push( - ...(node.computed ? [c('['), ...key, c(']')] : key), - c('('), - ...join(node.value.params.map((/** @type {Pattern} */ param) => handle(param, state)), c(', ')), - c(') '), - ...handle(node.value.body, state) + push_array(chunks, + node.computed ? [c('['), ...key, c(']')] : key, + [c('(')], + join(node.value.params.map((/** @type {Pattern} */ param) => handle(param, state)), c(', ')), + [c(') ')], + handle(node.value.body, state) ); return chunks; @@ -1129,7 +1130,7 @@ const handlers = { const chunks = [c('{ ')]; for (let i = 0; i < node.properties.length; i += 1) { - chunks.push(...handle(node.properties[i], state)); + push_array(chunks, handle(node.properties[i], state)); if (i < node.properties.length - 1) chunks.push(c(', ')); } @@ -1159,13 +1160,13 @@ const handlers = { EXPRESSIONS_PRECEDENCE[node.argument.type] < EXPRESSIONS_PRECEDENCE.UnaryExpression ) { - chunks.push( - c('('), - ...handle(node.argument, state), - c(')') + push_array(chunks, + [c('(')], + handle(node.argument, state), + [c(')')] ); } else { - chunks.push(...handle(node.argument, state)); + push_array(chunks, handle(node.argument, state)); } return chunks; @@ -1196,25 +1197,25 @@ const handlers = { // } if (needs_parens(node.left, node, false)) { - chunks.push( - c('('), - ...handle(node.left, state), - c(')') + push_array(chunks, + [c('(')], + handle(node.left, state), + [c(')')] ); } else { - chunks.push(...handle(node.left, state)); + push_array(chunks, handle(node.left, state)); } chunks.push(c(` ${node.operator} `)); if (needs_parens(node.right, node, true)) { - chunks.push( - c('('), - ...handle(node.right, state), - c(')') + push_array(chunks, + [c('(')], + handle(node.right, state), + [c(')')] ); } else { - chunks.push(...handle(node.right, state)); + push_array(chunks, handle(node.right, state)); } return chunks; @@ -1227,12 +1228,12 @@ const handlers = { EXPRESSIONS_PRECEDENCE[node.test.type] > EXPRESSIONS_PRECEDENCE.ConditionalExpression ) { - chunks.push(...handle(node.test, state)); + push_array(chunks, handle(node.test, state)); } else { - chunks.push( - c('('), - ...handle(node.test, state), - c(')') + push_array(chunks, + [c('(')], + handle(node.test, state), + [c(')')] ); } @@ -1247,18 +1248,18 @@ const handlers = { ); if (multiple_lines) { - chunks.push( - c(`\n${state.indent}? `), - ...consequent, - c(`\n${state.indent}: `), - ...alternate + push_array(chunks, + [c(`\n${state.indent}? `)], + consequent, + [c(`\n${state.indent}: `)], + alternate ); } else { - chunks.push( - c(` ? `), - ...consequent, - c(` : `), - ...alternate + push_array(chunks, + [c(` ? `)], + consequent, + [c(` : `)], + alternate ); } @@ -1272,13 +1273,13 @@ const handlers = { EXPRESSIONS_PRECEDENCE[node.callee.type] < EXPRESSIONS_PRECEDENCE.CallExpression || has_call_expression(node.callee) ) { - chunks.push( - c('('), - ...handle(node.callee, state), - c(')') + push_array(chunks, + [c('(')], + handle(node.callee, state), + [c(')')] ) } else { - chunks.push(...handle(node.callee, state)); + push_array(chunks, handle(node.callee, state)); } // TODO this is copied from CallExpression — DRY it out @@ -1291,10 +1292,10 @@ const handlers = { ? c(',\n' + state.indent) : c(', '); - chunks.push( - c('('), - ...join(args, separator), - c(')') + push_array(chunks, + [c('(')], + join(args, separator), + [c(')')] ); return chunks; @@ -1311,13 +1312,13 @@ const handlers = { EXPRESSIONS_PRECEDENCE[node.callee.type] < EXPRESSIONS_PRECEDENCE.CallExpression ) { - chunks.push( - c('('), - ...handle(node.callee, state), - c(')') + push_array(chunks, + [c('(')], + handle(node.callee, state), + [c(')')] ); } else { - chunks.push(...handle(node.callee, state)); + push_array(chunks, handle(node.callee, state)); } if (/** @type {SimpleCallExpression} */ (node).optional) { @@ -1335,16 +1336,16 @@ const handlers = { indent: `${state.indent}\t` })); - chunks.push( - c(`(\n${state.indent}\t`), - ...join(args, c(`,\n${state.indent}\t`)), - c(`\n${state.indent})`) + push_array(chunks, + [c(`(\n${state.indent}\t`)], + join(args, c(`,\n${state.indent}\t`)), + [c(`\n${state.indent})`)] ); } else { - chunks.push( - c('('), - ...join(args, c(', ')), - c(')') + push_array(chunks, + [c('(')], + join(args, c(', ')), + [c(')')] ); } @@ -1355,28 +1356,28 @@ const handlers = { const chunks = []; if (EXPRESSIONS_PRECEDENCE[node.object.type] < EXPRESSIONS_PRECEDENCE.MemberExpression) { - chunks.push( - c('('), - ...handle(node.object, state), - c(')') + push_array(chunks, + [c('(')], + handle(node.object, state), + [c(')')] ); } else { - chunks.push(...handle(node.object, state)); + push_array(chunks, handle(node.object, state)); } if (node.computed) { if (node.optional) { chunks.push(c('?.')); } - chunks.push( - c('['), - ...handle(node.property, state), - c(']') + push_array(chunks, + [c('[')], + handle(node.property, state), + [c(']')] ); } else { - chunks.push( - c(node.optional ? '?.' : '.'), - ...handle(node.property, state) + push_array(chunks, + [c(node.optional ? '?.' : '.')], + handle(node.property, state) ); } diff --git a/src/utils/push_array.js b/src/utils/push_array.js new file mode 100644 index 0000000..5756cb9 --- /dev/null +++ b/src/utils/push_array.js @@ -0,0 +1,11 @@ +export function push_array(this_array, ...other_array_list) { + let count = 0; + for (let a = 0; a < other_array_list.length; a++) { + const other_array = other_array_list[a]; + for (let i = 0; i < other_array.length; i++) { + this_array.push(other_array[i]); + } + count += other_array.length; + } + return count; +};