0

I would like to write a Babel plugin that translates a block-statement as first argument to function foo into an arrow function body.

I would like to transform foo({var a = 1;}) into foo(() => {var a = 1;})

I tried the following:

visitor: {
    CallExpression(path) {
        if (path.node.callee.name == 'foo') {
            if (path.node.hasOwnProperty('_alreadyVisited')) return;
                path.replaceWith( t.callExpression( path.node.callee, 
                [t.arrowFunctionExpression([], path.node.arguments[0])] ) );
            path.node['_alreadyVisited'] = true;
        }       
    }
}

But it seems my plugin rule is not even considered, as Babel.transform already fails before with: Uncaught SyntaxError: unknown: Unexpected keyword 'var'

Any ideas would be greatly appreciated.

Edmund Moshammer
  • 688
  • 7
  • 19
  • 1
    Yeah, that syntax is invalid, so babel doesn't even start transforming your code. You'll have to find a way to pre-process raw text to do that. (Why though? I don't understand why you would look for a way to deliberately write bad syntax; `foo({ ... })` is interpreted as passing an object literal, not a function body, so the parser expects a key) –  Oct 28 '20 at 08:40
  • Thank you very much Chris. I see. I was hoping for a shorthand, given I know that the argument will always be a function body. Would there be any other valid syntax than “() => {xxx}” to indicate xxx is a block statement? – Edmund Moshammer Oct 28 '20 at 09:18
  • Can you give an example of an actual situation in which you want to use a function call like that? Maybe there is a better way, given how -sorry- nonsensical the statement in your question is (the function sets a local variable and doesn't return anything), so it amounts to `foo()`) –  Oct 28 '20 at 09:30
  • I have a function in mind that sets an environment variable to be considered in any nested function calls. The full statement in the end will be a user string input that I want to be flexible but also user friendly. [link](https://jsfiddle.net/jqb8oewa/) I would have liked to shorten the example in the jsfiddle to: `setenv( { env+setenv( { env }, 2 ) }, 1 )` – Edmund Moshammer Oct 28 '20 at 10:21
  • I'd love to help but I'm still at a loss here, sorry. You could pass the variable name as string maybe, and use it as key for a global object? Still not sure what you're trying to achieve exactly. –  Oct 28 '20 at 10:28
  • Thanks again. This exchange helped me a lot to better understand the workings of babel. It gives me some food for thought. – Edmund Moshammer Oct 28 '20 at 11:45

0 Answers0