Remove tagged template literal global caching (#7722)

* Remove tagged template literal global caching

Fixes #7350.

* Review comments

* assert output
This commit is contained in:
Justin Ridgewell 2018-04-13 11:51:00 -04:00 committed by GitHub
parent 7a106025ea
commit 29eafbbf44
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 73 additions and 38 deletions

View File

@ -45,9 +45,6 @@ export default declare((api, options) => {
} }
return { return {
pre() {
this.templates = new Map();
},
visitor: { visitor: {
TaggedTemplateExpression(path) { TaggedTemplateExpression(path) {
const { node } = path; const { node } = path;
@ -75,40 +72,26 @@ export default declare((api, options) => {
} }
} }
// Generate a unique name based on the string literals so we dedupe const scope = path.scope.getProgramParent();
// identical strings used in the program. const templateObject = scope.generateUidIdentifier("templateObject");
const rawParts = raws.map(s => s.value).join(",");
const name = `${helperName}_${raws.length}_${rawParts}`;
let templateObject = this.templates.get(name);
if (templateObject) {
templateObject = t.cloneNode(templateObject);
} else {
const programPath = path.find(p => p.isProgram());
templateObject = programPath.scope.generateUidIdentifier(
"templateObject",
);
this.templates.set(name, templateObject);
const helperId = this.addHelper(helperName); const helperId = this.addHelper(helperName);
const callExpressionInput = []; const callExpressionInput = [t.arrayExpression(strings)];
callExpressionInput.push(t.arrayExpression(strings));
// only add raw arrayExpression if there is any difference between raws and strings
if (!isStringsRawEqual) { if (!isStringsRawEqual) {
callExpressionInput.push(t.arrayExpression(raws)); callExpressionInput.push(t.arrayExpression(raws));
} }
// only add raw arrayExpression if there is any difference between raws and strings
const init = t.callExpression(helperId, callExpressionInput); const init = t.callExpression(helperId, callExpressionInput);
annotateAsPure(init); annotateAsPure(init);
init._compact = true; init._compact = true;
programPath.scope.push({ scope.push({
id: templateObject, id: templateObject,
init, init,
// This ensures that we don't fail if not using function expression helpers // This ensures that we don't fail if not using function expression helpers
_blockHoist: 1.9, _blockHoist: 1.9,
}); });
}
path.replaceWith( path.replaceWith(
t.callExpression(node.tag, [ t.callExpression(node.tag, [

View File

@ -0,0 +1,15 @@
var tag = v => v;
function foo() {
return tag`some template`;
}
function bar() {
return tag`some template`;
}
expect(foo()).toBe(foo());
expect(foo()).toEqual(["some template"]);
expect(bar()).toBe(bar());
expect(bar()).toEqual(["some template"]);
expect(bar()).not.toBe(foo());

View File

@ -0,0 +1,15 @@
var tag = v => v;
function foo() {
return tag`some template`;
}
function bar() {
return tag`some template`;
}
expect(foo()).toBe(foo());
expect(foo()).toEqual(["some template"]);
expect(bar()).toBe(bar());
expect(bar()).toEqual(["some template"]);
expect(bar()).not.toBe(foo());

View File

@ -0,0 +1,20 @@
var _templateObject = /*#__PURE__*/ _taggedTemplateLiteral(["some template"]),
_templateObject2 = /*#__PURE__*/ _taggedTemplateLiteral(["some template"]);
function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
var tag = v => v;
function foo() {
return tag(_templateObject);
}
function bar() {
return tag(_templateObject2);
}
expect(foo()).toBe(foo());
expect(foo()).toEqual(["some template"]);
expect(bar()).toBe(bar());
expect(bar()).toEqual(["some template"]);
expect(bar()).not.toBe(foo());

View File

@ -4,7 +4,8 @@ var _templateObject = /*#__PURE__*/ _taggedTemplateLiteral([void 0], ["\\unicode
_templateObject4 = /*#__PURE__*/ _taggedTemplateLiteral(["left", void 0], ["left", "\\xg"]), _templateObject4 = /*#__PURE__*/ _taggedTemplateLiteral(["left", void 0], ["left", "\\xg"]),
_templateObject5 = /*#__PURE__*/ _taggedTemplateLiteral(["left", void 0, "right"], ["left", "\\xg", "right"]), _templateObject5 = /*#__PURE__*/ _taggedTemplateLiteral(["left", void 0, "right"], ["left", "\\xg", "right"]),
_templateObject6 = /*#__PURE__*/ _taggedTemplateLiteral(["left", void 0, "right"], ["left", "\\u000g", "right"]), _templateObject6 = /*#__PURE__*/ _taggedTemplateLiteral(["left", void 0, "right"], ["left", "\\u000g", "right"]),
_templateObject7 = /*#__PURE__*/ _taggedTemplateLiteral(["left", void 0, "right"], ["left", "\\u{-0}", "right"]); _templateObject7 = /*#__PURE__*/ _taggedTemplateLiteral(["left", void 0, "right"], ["left", "\\u{-0}", "right"]),
_templateObject8 = /*#__PURE__*/ _taggedTemplateLiteral([void 0], ["\\01"]);
function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); } function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
@ -18,5 +19,5 @@ tag(_templateObject7, 0, 1);
function a() { function a() {
var undefined = 4; var undefined = 4;
tag(_templateObject2); tag(_templateObject8);
} }

View File

@ -4,7 +4,8 @@ var _templateObject = /*#__PURE__*/ _taggedTemplateLiteralLoose([void 0], ["\\un
_templateObject4 = /*#__PURE__*/ _taggedTemplateLiteralLoose(["left", void 0], ["left", "\\xg"]), _templateObject4 = /*#__PURE__*/ _taggedTemplateLiteralLoose(["left", void 0], ["left", "\\xg"]),
_templateObject5 = /*#__PURE__*/ _taggedTemplateLiteralLoose(["left", void 0, "right"], ["left", "\\xg", "right"]), _templateObject5 = /*#__PURE__*/ _taggedTemplateLiteralLoose(["left", void 0, "right"], ["left", "\\xg", "right"]),
_templateObject6 = /*#__PURE__*/ _taggedTemplateLiteralLoose(["left", void 0, "right"], ["left", "\\u000g", "right"]), _templateObject6 = /*#__PURE__*/ _taggedTemplateLiteralLoose(["left", void 0, "right"], ["left", "\\u000g", "right"]),
_templateObject7 = /*#__PURE__*/ _taggedTemplateLiteralLoose(["left", void 0, "right"], ["left", "\\u{-0}", "right"]); _templateObject7 = /*#__PURE__*/ _taggedTemplateLiteralLoose(["left", void 0, "right"], ["left", "\\u{-0}", "right"]),
_templateObject8 = /*#__PURE__*/ _taggedTemplateLiteralLoose([void 0], ["\\01"]);
function _taggedTemplateLiteralLoose(strings, raw) { if (!raw) { raw = strings.slice(0); } strings.raw = raw; return strings; } function _taggedTemplateLiteralLoose(strings, raw) { if (!raw) { raw = strings.slice(0); } strings.raw = raw; return strings; }
@ -18,5 +19,5 @@ tag(_templateObject7, 0, 1);
function a() { function a() {
var undefined = 4; var undefined = 4;
tag(_templateObject2); tag(_templateObject8);
} }