Tokens arrays of tagged template literals not linked to the tagged template
Opened this issue · 1 comments
From MDN:
For any particular tagged template literal expression, the tag function will always be called with the exact same literal array, no matter how many times the literal is evaluated.
Input:
function tag(tokens) {
return tokens;
}
function runTag() {
return tag`a${123}b${456}c`;
}
const tokens = runTag();
export default function compare() {
return runTag() === tokens;
}
In the source code, compare()
returns true
. But in output it returns false
because Livepack does not understand the link between tokens
and the template literal in runTag()
.
Output:
const Object$0 = Object,
ObjectFreeze = Object$0.freeze;
export default (
(tokens, tag, runTag$0) => (
runTag$0 = function runTag() {
return tag`a${123}b${456}c`;
},
function compare() {
return runTag$0() === tokens;
}
)
)(
ObjectFreeze(
Object$0.defineProperties(
["a", "b", "c"],
{ raw: { value: ObjectFreeze(["a", "b", "c"]) } }
)
),
function tag(tokens) {
return tokens;
}
);
This would be annoying to solve.
Instrumentation would need to replace the tag
function with a wrapper which records:
- the tokens array
- the
raw
property of the tokens array - the function which the tagged template is in
If the tokens array/raw tokens array and the function are both included in output, it'd need to rewrite the runTag
function as:
const tokens = (t => t)`a${0}b${0}c`;
function runTag() {
// Was: tag`a${123}b${456}c`
return tag(tokens, 123, 456);
}
NB: The tokens array is lexically bound to the tagged template.
const tag = tokens => tokens;
const makeRunTag = () => () => tag`a${1}b${2}c`;
const tokens1 = makeRunTag()();
const tokens2 = makeRunTag()();
console.log(tokens1 === tokens2); // true
i.e. A single tagged template in source code corresponds to a single tokens array, regardless of how many function instances it's in.