source: trip-planner-front/node_modules/@babel/preset-modules/src/plugins/transform-tagged-template-caching/index.js@ 8d391a1

Last change on this file since 8d391a1 was e29cc2e, checked in by Ema <ema_spirova@…>, 3 years ago

primeNG components

  • Property mode set to 100644
File size: 3.2 KB
Line 
1/**
2 * Converts destructured parameters with default values to non-shorthand syntax.
3 * This fixes the only Tagged Templates-related bug in ES Modules-supporting browsers (Safari 10 & 11).
4 * Use this plugin instead of `@babel/plugin-transform-template-literals` when targeting ES Modules.
5 *
6 * @example
7 * // Bug 1: Safari 10/11 doesn't reliably return the same Strings value.
8 * // The value changes depending on invocation and function optimization state.
9 * function f() { return Object`` }
10 * f() === new f() // false, should be true.
11 *
12 * @example
13 * // Bug 2: Safari 10/11 use the same cached strings value when the string parts are the same.
14 * // This behavior comes from an earlier version of the spec, and can cause tricky bugs.
15 * Object``===Object`` // true, should be false.
16 *
17 * Benchmarks: https://jsperf.com/compiled-tagged-template-performance
18 */
19export default ({ types: t }) => ({
20 name: "transform-tagged-template-caching",
21 visitor: {
22 TaggedTemplateExpression(path, state) {
23 // tagged templates we've already dealt with
24 let processed = state.get("processed");
25 if (!processed) {
26 processed = new WeakSet();
27 state.set("processed", processed);
28 }
29
30 if (processed.has(path.node)) return path.skip();
31
32 // Grab the expressions from the original tag.
33 // tag`a${'hello'}` // ['hello']
34 const expressions = path.node.quasi.expressions;
35
36 // Create an identity function helper:
37 // identity = t => t
38 let identity = state.get("identity");
39 if (!identity) {
40 identity = path.scope
41 .getProgramParent()
42 .generateDeclaredUidIdentifier("_");
43 state.set("identity", identity);
44 const binding = path.scope.getBinding(identity.name);
45 binding.path.get("init").replaceWith(
46 t.arrowFunctionExpression(
47 // re-use the helper identifier for compressability
48 [t.identifier("t")],
49 t.identifier("t")
50 )
51 );
52 }
53
54 // Use the identity function helper to get a reference to the template's Strings.
55 // We replace all expressions with `0` ensure Strings has the same shape.
56 // identity`a${0}`
57 const template = t.taggedTemplateExpression(
58 t.cloneNode(identity),
59 t.templateLiteral(
60 path.node.quasi.quasis,
61 expressions.map(() => t.numericLiteral(0))
62 )
63 );
64 processed.add(template);
65
66 // Install an inline cache at the callsite using the global variable:
67 // _t || (_t = identity`a${0}`)
68 const ident = path.scope
69 .getProgramParent()
70 .generateDeclaredUidIdentifier("t");
71 path.scope.getBinding(ident.name).path.parent.kind = "let";
72 const inlineCache = t.logicalExpression(
73 "||",
74 ident,
75 t.assignmentExpression("=", t.cloneNode(ident), template)
76 );
77
78 // The original tag function becomes a plain function call.
79 // The expressions omitted from the cached Strings tag are directly applied as arguments.
80 // tag(_t || (_t = Object`a${0}`), 'hello')
81 const node = t.callExpression(path.node.tag, [
82 inlineCache,
83 ...expressions,
84 ]);
85 path.replaceWith(node);
86 },
87 },
88});
Note: See TracBrowser for help on using the repository browser.