From 0c2251a60d21134549dc22a7ab66cb1318829e46 Mon Sep 17 00:00:00 2001 From: Tony Quetano Date: Fri, 15 Dec 2023 22:37:14 -0500 Subject: [PATCH] abstract out utils --- src/inline-loops.macro.js | 153 +++++--------------------------------- src/utils.js | 136 +++++++++++++++++++++++++++++++++ 2 files changed, 153 insertions(+), 136 deletions(-) diff --git a/src/inline-loops.macro.js b/src/inline-loops.macro.js index c4569c1..1574290 100644 --- a/src/inline-loops.macro.js +++ b/src/inline-loops.macro.js @@ -1,7 +1,15 @@ const { MacroError, createMacro } = require('babel-plugin-macros'); const { createTemplates } = require('./templates'); const { createTraverseConfigs } = require('./traverse'); -const { rename } = require('./utils'); +const { + getCachedFnArgs, + getLocalName, + handleArrowFunctionExpressionUse, + handleInvalidUsage, + processNestedInlineLoopMacros, + rename, + replaceOrRemove, +} = require('./utils'); function myMacro({ references, babel }) { const { template, types: t } = babel; @@ -66,68 +74,6 @@ function myMacro({ references, babel }) { someRight: createHandleEverySome('some-right'), }; - function getImportedHandlerName(callee) { - const binding = callee.scope.getBinding(callee.node.name); - - if (!binding) { - return; - } - - const owner = binding.path; - - if (owner.isImportSpecifier()) { - const imported = owner.get('imported'); - const name = imported.node.name; - - if (!Object.keys(handlers).some((handler) => handler === name)) { - return; - } - - const importSource = owner.parentPath.get('source.value'); - - if (!importSource.node.endsWith('inline-loops.macro')) { - return; - } - - return name; - } - - if (owner.isVariableDeclarator()) { - const init = owner.get('init'); - - if ( - !init.isCallExpression() || - !init.get('callee').isIdentifier({ name: 'require' }) - ) { - return; - } - - const requireSource = init.get('arguments.0.value'); - - if (!requireSource.node.endsWith('inline-loops.macro')) { - return; - } - - const imported = owner - .get('id.properties') - .find((property) => - property.get('value').isIdentifier({ name: callee.node.name }), - ); - - if (!imported) { - return; - } - - const name = imported.get('key').node.name; - - if (!Object.keys(handlers).some((handler) => handler === name)) { - return; - } - - return name; - } - } - function getInjectedBodyAndLogic({ callback, isForEach, @@ -216,16 +162,6 @@ function myMacro({ references, babel }) { return { injectedBody: [], logic }; } - function getCachedFnArgs(local, isReduce) { - return isReduce - ? [local.accumulated, local.value, local.key, local.collection] - : [local.value, local.key, local.collection]; - } - - function getLocalName(path, name = path.node.name) { - return path.scope.generateUidIdentifier(name); - } - function getLocalReferences(path, statement, isReduce) { const args = path.get('arguments'); @@ -317,61 +253,6 @@ function myMacro({ references, babel }) { }; } - function handleArrowFunctionExpressionUse(path) { - if (path.parentPath.isArrowFunctionExpression()) { - path.parentPath.arrowFunctionToExpression({ - allowInsertArrow: false, - noNewArrows: true, - }); - } - } - - function handleInvalidUsage(path) { - const [collection, callback] = path.get('arguments'); - - if (collection.isSpreadElement()) { - throw new MacroError( - 'You cannot use spread arguments with `inline-loops.macro`; please declare the arguments explicitly.', - ); - } - - const importedHandlerName = getImportedHandlerName(callback); - - if (importedHandlerName) { - throw new MacroError( - 'You cannot use a method from `inline-loops.macro` directly as a handler; please wrap it in a function call.', - ); - } - } - - function processNestedInlineLoopMacros(path) { - if (!path.isCallExpression()) { - return; - } - - const callee = path.get('callee'); - - if (!callee.isIdentifier()) { - return; - } - - const importedHandlerName = getImportedHandlerName(callee); - - if (importedHandlerName) { - handlers[importedHandlerName](path.get('callee')); - } - } - - function replaceOrRemove(path, replacement) { - const parentPath = path.parentPath; - - if (parentPath.isExpressionStatement()) { - path.remove(); - } else { - path.replaceWith(replacement); - } - } - function createHandleEverySome(type) { return function handleFilter(referencePath) { const path = referencePath.parentPath; @@ -380,12 +261,12 @@ function myMacro({ references, babel }) { return; } - handleInvalidUsage(path); + handleInvalidUsage({ handlers, path }); handleArrowFunctionExpressionUse(path); const [collection, callback] = path.get('arguments'); - processNestedInlineLoopMacros(collection); + processNestedInlineLoopMacros(collection, handlers); const statement = path.getStatementParent(); const local = getLocalReferences(path, statement); @@ -495,12 +376,12 @@ function myMacro({ references, babel }) { return; } - handleInvalidUsage(path); + handleInvalidUsage({ handlers, path }); handleArrowFunctionExpressionUse(path); const [collection, callback] = path.get('arguments'); - processNestedInlineLoopMacros(collection); + processNestedInlineLoopMacros(collection, handlers); const statement = path.getStatementParent(); const local = getLocalReferences(path, statement); @@ -610,12 +491,12 @@ function myMacro({ references, babel }) { return; } - handleInvalidUsage(path); + handleInvalidUsage({ handlers, path }); handleArrowFunctionExpressionUse(path); const [collection, callback] = path.get('arguments'); - processNestedInlineLoopMacros(collection); + processNestedInlineLoopMacros(collection, handlers); const statement = path.getStatementParent(); const local = getLocalReferences(path, statement); @@ -778,12 +659,12 @@ function myMacro({ references, babel }) { return; } - handleInvalidUsage(path); + handleInvalidUsage({ handlers, path }); handleArrowFunctionExpressionUse(path); const [collection, callback, initialValue] = path.get('arguments'); - processNestedInlineLoopMacros(collection); + processNestedInlineLoopMacros(collection, handlers); const statement = path.getStatementParent(); const local = getLocalReferences(path, statement, true); diff --git a/src/utils.js b/src/utils.js index fb74733..dd4d2bf 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,7 +1,143 @@ +const { MacroError } = require('babel-plugin-macros'); + +function getCachedFnArgs(local, isReduce) { + return isReduce + ? [local.accumulated, local.value, local.key, local.collection] + : [local.value, local.key, local.collection]; +} + +function getImportedHandlerName(callee, handlers) { + const binding = callee.scope.getBinding(callee.node.name); + + if (!binding) { + return; + } + + const owner = binding.path; + + if (owner.isImportSpecifier()) { + const imported = owner.get('imported'); + const name = imported.node.name; + + if (!Object.keys(handlers).some((handler) => handler === name)) { + return; + } + + const importSource = owner.parentPath.get('source.value'); + + if (!importSource.node.endsWith('inline-loops.macro')) { + return; + } + + return name; + } + + if (owner.isVariableDeclarator()) { + const init = owner.get('init'); + + if ( + !init.isCallExpression() || + !init.get('callee').isIdentifier({ name: 'require' }) + ) { + return; + } + + const requireSource = init.get('arguments.0.value'); + + if (!requireSource.node.endsWith('inline-loops.macro')) { + return; + } + + const imported = owner + .get('id.properties') + .find((property) => + property.get('value').isIdentifier({ name: callee.node.name }), + ); + + if (!imported) { + return; + } + + const name = imported.get('key').node.name; + + if (!Object.keys(handlers).some((handler) => handler === name)) { + return; + } + + return name; + } +} + +function getLocalName(path, name = path.node.name) { + return path.scope.generateUidIdentifier(name); +} + +function handleArrowFunctionExpressionUse(path) { + if (path.parentPath.isArrowFunctionExpression()) { + path.parentPath.arrowFunctionToExpression({ + allowInsertArrow: false, + noNewArrows: true, + }); + } +} + +function handleInvalidUsage({ handlers, path }) { + const [collection, callback] = path.get('arguments'); + + if (collection.isSpreadElement()) { + throw new MacroError( + 'You cannot use spread arguments with `inline-loops.macro`; please declare the arguments explicitly.', + ); + } + + const importedHandlerName = getImportedHandlerName(callback, handlers); + + if (importedHandlerName) { + throw new MacroError( + 'You cannot use a method from `inline-loops.macro` directly as a handler; please wrap it in a function call.', + ); + } +} + +function processNestedInlineLoopMacros(path, handlers) { + if (!path.isCallExpression()) { + return; + } + + const callee = path.get('callee'); + + if (!callee.isIdentifier()) { + return; + } + + const importedHandlerName = getImportedHandlerName(callee, handlers); + + if (importedHandlerName) { + handlers[importedHandlerName](path.get('callee')); + } +} + function rename(path, newName) { path.scope.rename(path.node.name, newName); } +function replaceOrRemove(path, replacement) { + const parentPath = path.parentPath; + + if (parentPath.isExpressionStatement()) { + path.remove(); + } else { + path.replaceWith(replacement); + } +} + module.exports = { + getCachedFnArgs, + getImportedHandlerName, + getLocalName, + handleArrowFunctionExpressionUse, + handleInvalidUsage, + processNestedInlineLoopMacros, rename, + replaceOrRemove, };