Handle mini notation without S
This commit is contained in:
parent
a5c4fd5bc1
commit
e92865cecb
2 changed files with 68 additions and 12 deletions
|
|
@ -26,6 +26,15 @@ describe('transpiler', () => {
|
||||||
it('adds await to bare samples call', () => {
|
it('adds await to bare samples call', () => {
|
||||||
expect(transpiler("samples('xxx');", simple).output).toEqual("await samples('xxx');");
|
expect(transpiler("samples('xxx');", simple).output).toEqual("await samples('xxx');");
|
||||||
});
|
});
|
||||||
|
it('treats mini strings in K(...) as strudel', () => {
|
||||||
|
expect(transpiler('K("bd")', simple).output).toEqual("worklet('pat[0]', m('bd', 2));");
|
||||||
|
});
|
||||||
|
it('treats K(...) as kabelsalat', () => {
|
||||||
|
expect(transpiler('K(1+2)', simple).output).toEqual("worklet('1 + 2');");
|
||||||
|
});
|
||||||
|
it('handles strudel S(...) inside kabelsalat K(...)', () => {
|
||||||
|
expect(transpiler('K(S("bd"))', simple).output).toEqual("worklet('pat[0]', m('bd', 4));");
|
||||||
|
});
|
||||||
/* it('parses dynamic imports', () => {
|
/* it('parses dynamic imports', () => {
|
||||||
expect(
|
expect(
|
||||||
transpiler("const { default: foo } = await import('https://bar.com/foo.js');", {
|
transpiler("const { default: foo } = await import('https://bar.com/foo.js');", {
|
||||||
|
|
|
||||||
|
|
@ -223,8 +223,10 @@ function extractPatternPlaceholders(expr) {
|
||||||
walk(templateExpr, {
|
walk(templateExpr, {
|
||||||
enter(node, parent, prop, index) {
|
enter(node, parent, prop, index) {
|
||||||
parents.set(node, { parent, prop, index });
|
parents.set(node, { parent, prop, index });
|
||||||
if (isStrudelPatternCall(node)) {
|
const patternExpr = getStrudelPatternExpr(node);
|
||||||
targets.push(node);
|
if (patternExpr) {
|
||||||
|
targets.push({ node, patternExpr });
|
||||||
|
this.skip();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
@ -233,18 +235,12 @@ function extractPatternPlaceholders(expr) {
|
||||||
return { template: genExprSource(templateExpr), patternExprs: [] };
|
return { template: genExprSource(templateExpr), patternExprs: [] };
|
||||||
}
|
}
|
||||||
|
|
||||||
targets.sort((a, b) => (a.start ?? 0) - (b.start ?? 0));
|
targets.sort((a, b) => getPatternNodeOrder(a.node) - getPatternNodeOrder(b.node));
|
||||||
|
|
||||||
const patternExprs = targets.map((node) => {
|
const patternExprs = targets.map(({ patternExpr }) => cloneNode(patternExpr));
|
||||||
const arg = node.arguments?.[0];
|
|
||||||
if (!arg) {
|
|
||||||
throw new Error('S(...) requires an argument');
|
|
||||||
}
|
|
||||||
return cloneNode(arg);
|
|
||||||
});
|
|
||||||
|
|
||||||
let currentExpr = templateExpr;
|
let currentExpr = templateExpr;
|
||||||
targets.forEach((node, index) => {
|
targets.forEach(({ node }, index) => {
|
||||||
currentExpr = replaceNode(node, placeholderAst(index), parents, currentExpr);
|
currentExpr = replaceNode(node, placeholderAst(index), parents, currentExpr);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -252,7 +248,21 @@ function extractPatternPlaceholders(expr) {
|
||||||
return { template, patternExprs };
|
return { template, patternExprs };
|
||||||
}
|
}
|
||||||
|
|
||||||
function isStrudelPatternCall(node) {
|
function getStrudelPatternExpr(node) {
|
||||||
|
if (isStrudelPatternWrap(node)) {
|
||||||
|
const arg = node.arguments?.[0];
|
||||||
|
if (!arg) {
|
||||||
|
throw new Error('S(...) requires an argument');
|
||||||
|
}
|
||||||
|
return arg;
|
||||||
|
}
|
||||||
|
if (isMiniCall(node)) {
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isStrudelPatternWrap(node) {
|
||||||
if (node.type !== 'CallExpression') {
|
if (node.type !== 'CallExpression') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -266,6 +276,43 @@ function isStrudelPatternCall(node) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getMinilangName() {
|
||||||
|
const minilang = languages.get('minilang');
|
||||||
|
return minilang?.name || 'm';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Used to identify transpiled `m(...)` calls for proper conversion
|
||||||
|
// to, say, kabelsalat placeholders
|
||||||
|
function isMiniCall(node) {
|
||||||
|
if (node.type !== 'CallExpression') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const callee = node.callee;
|
||||||
|
if (callee.type !== 'Identifier') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (callee.name !== getMinilangName()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const firstArg = node.arguments?.[0];
|
||||||
|
return firstArg?.type === 'Literal' && typeof firstArg.value === 'string';
|
||||||
|
}
|
||||||
|
|
||||||
|
// If `start` is available, we use it. If it's already been transpiled
|
||||||
|
// to `m(...)`, use the provided offset
|
||||||
|
function getPatternNodeOrder(node) {
|
||||||
|
if (typeof node.start === 'number') {
|
||||||
|
return node.start;
|
||||||
|
}
|
||||||
|
if (isMiniCall(node)) {
|
||||||
|
const offsetArg = node.arguments?.[1];
|
||||||
|
if (offsetArg?.type === 'Literal' && typeof offsetArg.value === 'number') {
|
||||||
|
return offsetArg.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
function placeholderAst(index) {
|
function placeholderAst(index) {
|
||||||
return {
|
return {
|
||||||
type: 'MemberExpression',
|
type: 'MemberExpression',
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue