From c6e829703ec61e2f1dc908651d98d2af92a9b347 Mon Sep 17 00:00:00 2001 From: Nathan Cahill Date: Tue, 9 Jan 2018 21:46:27 -0700 Subject: [PATCH] move declaration to in-place for expressions - fixes #87 --- src/program/types/CallExpression.js | 15 +++++++++++++-- test/samples/spread-operator.js | 21 +++++++++++++++++---- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/program/types/CallExpression.js b/src/program/types/CallExpression.js index 3671f526..86a438c6 100644 --- a/src/program/types/CallExpression.js +++ b/src/program/types/CallExpression.js @@ -57,9 +57,20 @@ export default class CallExpression extends Node { if (this.callee.object.type === 'Identifier') { context = this.callee.object.name; } else { - context = this.findScope(true).createDeclaration('ref'); const callExpression = this.callee.object; - code.prependRight(callExpression.start, `(${context} = `); + + // Prepend the declaraction in place to prevent an expression + // begining with a parenthesis. Other types are guarded by + // an expression before the parenthesis so the declaration + // is created at the top of the scope. + if (this.parent.type === 'ExpressionStatement') { + context = this.findScope(true).createIdentifier('ref'); + code.prependRight(callExpression.start, `var ${context}; (${context} = `); + } else { + context = this.findScope(true).createDeclaration('ref'); + code.prependRight(callExpression.start, `(${context} = `); + } + code.appendLeft(callExpression.end, `)`); } } else { diff --git a/test/samples/spread-operator.js b/test/samples/spread-operator.js index b5fc4349..1db58599 100644 --- a/test/samples/spread-operator.js +++ b/test/samples/spread-operator.js @@ -38,9 +38,7 @@ module.exports = [ ( foo || bar ).baz( ...values );`, output: ` - var ref; - - (ref = ( foo || bar )).baz.apply( ref, values );` + var ref; (ref = ( foo || bar )).baz.apply( ref, values );` }, { @@ -585,5 +583,20 @@ module.exports = [ }; } } ` - } + }, + + { + description: + 'transpiles a spread operator with semicolon before parens', + + input: ` + const foo = { bar: [] } + const baz = true ? [1,2,3] : [] + foo.bar.push(...baz)`, + + output: ` + var foo = { bar: [] } + var baz = true ? [1,2,3] : [] + var ref; (ref = foo.bar).push.apply(ref, baz)` + }, ];