From 14a17af81b5174c399ee285dd49f11488dbe47d8 Mon Sep 17 00:00:00 2001 From: Lukas Taegert-Atkinson Date: Sun, 17 Feb 2019 08:05:26 +0100 Subject: [PATCH] Correctly render function expression inside simplified expression statements. (#2696) Resolves #2684 --- src/ast/nodes/CallExpression.ts | 18 ++++++ .../_config.js | 3 + .../main.js | 58 +++++++++++++++++++ 3 files changed, 79 insertions(+) create mode 100644 test/function/samples/function-expressions-simplified-to-statement/_config.js create mode 100644 test/function/samples/function-expressions-simplified-to-statement/main.js diff --git a/src/ast/nodes/CallExpression.ts b/src/ast/nodes/CallExpression.ts index 5a8dab171c4..172bd2594ef 100644 --- a/src/ast/nodes/CallExpression.ts +++ b/src/ast/nodes/CallExpression.ts @@ -1,3 +1,6 @@ +import MagicString from 'magic-string'; +import { BLANK } from '../../utils/blank'; +import { NodeRenderOptions, RenderOptions } from '../../utils/renderHelpers'; import CallOptions from '../CallOptions'; import { DeoptimizableEntity } from '../DeoptimizableEntity'; import { ExecutionPathOptions } from '../ExecutionPathOptions'; @@ -210,4 +213,19 @@ export default class CallExpression extends NodeBase implements DeoptimizableEnt this.returnExpression.deoptimizePath(path); } } + + render( + code: MagicString, + options: RenderOptions, + { renderedParentType }: NodeRenderOptions = BLANK + ) { + super.render(code, options); + if ( + renderedParentType === NodeType.ExpressionStatement && + this.callee.type === NodeType.FunctionExpression + ) { + code.appendRight(this.start, '('); + code.prependLeft(this.end, ')'); + } + } } diff --git a/test/function/samples/function-expressions-simplified-to-statement/_config.js b/test/function/samples/function-expressions-simplified-to-statement/_config.js new file mode 100644 index 00000000000..2a43659a713 --- /dev/null +++ b/test/function/samples/function-expressions-simplified-to-statement/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'correctly handles function expressions which are simplified to statements' +}; diff --git a/test/function/samples/function-expressions-simplified-to-statement/main.js b/test/function/samples/function-expressions-simplified-to-statement/main.js new file mode 100644 index 00000000000..f5f4e72e1a7 --- /dev/null +++ b/test/function/samples/function-expressions-simplified-to-statement/main.js @@ -0,0 +1,58 @@ +var value; + +// conditional expression +function foo(){ + value = 'foo'; +} + +true ? function foo(x){ + value = x; +}("consequent") : 2; + +assert.equal(value, 'consequent'); + +foo("incorrect"); + +assert.equal(value, 'foo'); + +false ? null: function foo(x){ + value = x; +}("alternate"); + +assert.equal(value, 'alternate'); + +// logical expression +function bar(){ + value = 'bar'; +} + +true && function bar(x){ + value = x; +}("and"); + +assert.equal(value, 'and'); + +bar("incorrect"); + +assert.equal(value, 'bar'); + +false || function bar(x){ + value = x; +}("or"); + +assert.equal(value, 'or'); + +// sequence expression +function baz(){ + value = 'baz'; +} + +0, function baz(x){ + value = x; +}("comma"); + +assert.equal(value, 'comma'); + +baz("incorrect"); + +assert.equal(value, 'baz');