diff --git a/packages/babel/src/transformation/file/index.js b/packages/babel/src/transformation/file/index.js index 6505704cb3..1253224892 100644 --- a/packages/babel/src/transformation/file/index.js +++ b/packages/babel/src/transformation/file/index.js @@ -407,6 +407,30 @@ export default class File { return uid; } + addTemplateObject(helperName: string, strings: Array, raw: Array): Object { + // Generate a unique name based on the string literals so we dedupe + // identical strings used in the program. + var stringIds = raw.elements.map(function(string) { + return string.value; + }); + var name = `${helperName}_${raw.elements.length}_${stringIds.join(",")}`; + + var declar = this.declarations[name]; + if (declar) return declar; + + var uid = this.declarations[name] = this.scope.generateUidIdentifier("templateObject"); + + var helperId = this.addHelper(helperName); + var init = t.callExpression(helperId, [strings, raw]); + init._compact = true; + this.scope.push({ + id: uid, + init: init, + _blockHoist: 1.9 // This ensures that we don't fail if not using function expression helpers + }); + return uid; + } + /** * [Please add a description.] */ diff --git a/packages/babel/src/transformation/transformers/es6/template-literals.js b/packages/babel/src/transformation/transformers/es6/template-literals.js index 83f35c5e89..b561f64757 100644 --- a/packages/babel/src/transformation/transformers/es6/template-literals.js +++ b/packages/babel/src/transformation/transformers/es6/template-literals.js @@ -64,7 +64,9 @@ export var visitor = { var templateName = "tagged-template-literal"; if (file.isLoose("es6.templateLiterals")) templateName += "-loose"; - args.push(t.callExpression(file.addHelper(templateName), [strings, raw])); + + var templateObject = file.addTemplateObject(templateName, strings, raw); + args.push(templateObject); args = args.concat(quasi.expressions); diff --git a/packages/babel/src/traversal/scope/index.js b/packages/babel/src/traversal/scope/index.js index 7ef81af584..0d577152b4 100644 --- a/packages/babel/src/traversal/scope/index.js +++ b/packages/babel/src/traversal/scope/index.js @@ -829,14 +829,15 @@ export default class Scope { var unique = opts.unique; var kind = opts.kind || "var"; + var blockHoist = opts._blockHoist == null ? 2 : opts._blockHoist; - var dataKey = `declaration:${kind}`; + var dataKey = `declaration:${kind}:${blockHoist}`; var declar = !unique && path.getData(dataKey); if (!declar) { declar = t.variableDeclaration(kind, []); declar._generated = true; - declar._blockHoist = 2; + declar._blockHoist = blockHoist; this.hub.file.attachAuxiliaryComment(declar); diff --git a/packages/babel/test/fixtures/transformation/es6.template-literals/tag-loose/actual.js b/packages/babel/test/fixtures/transformation/es6.template-literals/tag-loose/actual.js index 7fe1864736..52419bb505 100644 --- a/packages/babel/test/fixtures/transformation/es6.template-literals/tag-loose/actual.js +++ b/packages/babel/test/fixtures/transformation/es6.template-literals/tag-loose/actual.js @@ -1 +1,3 @@ var foo = bar`wow\na${ 42 }b ${_.foobar()}`; +var bar = bar`wow\nab${ 42 } ${_.foobar()}`; +var bar = bar`wow\naB${ 42 } ${_.baz()}`; diff --git a/packages/babel/test/fixtures/transformation/es6.template-literals/tag-loose/expected.js b/packages/babel/test/fixtures/transformation/es6.template-literals/tag-loose/expected.js index a2264017ba..9378680632 100644 --- a/packages/babel/test/fixtures/transformation/es6.template-literals/tag-loose/expected.js +++ b/packages/babel/test/fixtures/transformation/es6.template-literals/tag-loose/expected.js @@ -1,5 +1,11 @@ "use strict"; +var _templateObject = _taggedTemplateLiteralLoose(["wow\na", "b ", ""], ["wow\\na", "b ", ""]), + _templateObject2 = _taggedTemplateLiteralLoose(["wow\nab", " ", ""], ["wow\\nab", " ", ""]), + _templateObject3 = _taggedTemplateLiteralLoose(["wow\naB", " ", ""], ["wow\\naB", " ", ""]); + function _taggedTemplateLiteralLoose(strings, raw) { strings.raw = raw; return strings; } -var foo = bar(_taggedTemplateLiteralLoose(["wow\na", "b ", ""], ["wow\\na", "b ", ""]), 42, _.foobar()); \ No newline at end of file +var foo = bar(_templateObject, 42, _.foobar()); +var bar = bar(_templateObject2, 42, _.foobar()); +var bar = bar(_templateObject3, 42, _.baz()); \ No newline at end of file diff --git a/packages/babel/test/fixtures/transformation/es6.template-literals/tag/expected.js b/packages/babel/test/fixtures/transformation/es6.template-literals/tag/expected.js index db7bc65355..7749db566b 100644 --- a/packages/babel/test/fixtures/transformation/es6.template-literals/tag/expected.js +++ b/packages/babel/test/fixtures/transformation/es6.template-literals/tag/expected.js @@ -1,5 +1,7 @@ "use strict"; +var _templateObject = _taggedTemplateLiteral(["wow\na", "b ", ""], ["wow\\na", "b ", ""]); + function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); } -var foo = bar(_taggedTemplateLiteral(["wow\na", "b ", ""], ["wow\\na", "b ", ""]), 42, _.foobar()); \ No newline at end of file +var foo = bar(_templateObject, 42, _.foobar());