Add ability to turn mini parsing off with midi-off decorator
This commit is contained in:
parent
cfeff26d42
commit
8529516c66
2 changed files with 52 additions and 0 deletions
|
|
@ -42,4 +42,18 @@ describe('transpiler', () => {
|
||||||
[12, 14],
|
[12, 14],
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
it('allows disabling mini', () => {
|
||||||
|
const code = `/* mini-off */
|
||||||
|
const randPrefix = Math.random() > 0.5 ? "b" : "s";
|
||||||
|
const drumPat = \`\${randPrefix}d\`;
|
||||||
|
// mini-on
|
||||||
|
s(drumPat).lpf("5000 10000") // make sure mini still runs;
|
||||||
|
`;
|
||||||
|
const { output, miniLocations } = transpiler(code, { ...simple, emitMiniLocations: true });
|
||||||
|
expect(output).not.toContain("m('b'");
|
||||||
|
expect(output).not.toContain("m('s'");
|
||||||
|
const cutoffIdx = code.indexOf('5000 10000');
|
||||||
|
expect(miniLocations).toHaveLength(2);
|
||||||
|
expect(miniLocations[0][0]).toEqual(cutoffIdx);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -21,12 +21,15 @@ export function registerLanguage(type, config) {
|
||||||
export function transpiler(input, options = {}) {
|
export function transpiler(input, options = {}) {
|
||||||
const { wrapAsync = false, addReturn = true, emitMiniLocations = true, emitWidgets = true } = options;
|
const { wrapAsync = false, addReturn = true, emitMiniLocations = true, emitWidgets = true } = options;
|
||||||
|
|
||||||
|
const comments = [];
|
||||||
let ast = parse(input, {
|
let ast = parse(input, {
|
||||||
ecmaVersion: 2022,
|
ecmaVersion: 2022,
|
||||||
allowAwaitOutsideFunction: true,
|
allowAwaitOutsideFunction: true,
|
||||||
locations: true,
|
locations: true,
|
||||||
|
onComment: comments,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const miniDisableRanges = findMiniDisableRanges(comments, input.length);
|
||||||
let miniLocations = [];
|
let miniLocations = [];
|
||||||
const collectMiniLocations = (value, node) => {
|
const collectMiniLocations = (value, node) => {
|
||||||
const minilang = languages.get('minilang');
|
const minilang = languages.get('minilang');
|
||||||
|
|
@ -66,6 +69,9 @@ export function transpiler(input, options = {}) {
|
||||||
return this.replace(tidalWithLocation(raw, offset));
|
return this.replace(tidalWithLocation(raw, offset));
|
||||||
}
|
}
|
||||||
if (isBackTickString(node, parent)) {
|
if (isBackTickString(node, parent)) {
|
||||||
|
if (isMiniDisabled(node.start, miniDisableRanges)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const { quasis } = node;
|
const { quasis } = node;
|
||||||
const { raw } = quasis[0].value;
|
const { raw } = quasis[0].value;
|
||||||
this.skip();
|
this.skip();
|
||||||
|
|
@ -73,6 +79,9 @@ export function transpiler(input, options = {}) {
|
||||||
return this.replace(miniWithLocation(raw, node));
|
return this.replace(miniWithLocation(raw, node));
|
||||||
}
|
}
|
||||||
if (isStringWithDoubleQuotes(node)) {
|
if (isStringWithDoubleQuotes(node)) {
|
||||||
|
if (isMiniDisabled(node.start, miniDisableRanges)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const { value } = node;
|
const { value } = node;
|
||||||
this.skip();
|
this.skip();
|
||||||
emitMiniLocations && collectMiniLocations(value, node);
|
emitMiniLocations && collectMiniLocations(value, node);
|
||||||
|
|
@ -327,3 +336,32 @@ function languageWithLocation(name, value, offset) {
|
||||||
optional: false,
|
optional: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function findMiniDisableRanges(comments, codeEnd) {
|
||||||
|
const ranges = [];
|
||||||
|
const stack = []; // used to track on/off pairs
|
||||||
|
for (const comment of comments) {
|
||||||
|
const value = comment.value.trim();
|
||||||
|
if (value.startsWith('mini-off')) {
|
||||||
|
stack.push(comment.start);
|
||||||
|
} else if (value.startsWith('mini-on')) {
|
||||||
|
const start = stack.pop();
|
||||||
|
ranges.push([start, comment.end]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (stack.length) {
|
||||||
|
// If no closing mini-on is found, just turn it off until `codeEnd`
|
||||||
|
const start = stack.pop();
|
||||||
|
ranges.push([start, codeEnd]);
|
||||||
|
}
|
||||||
|
return ranges;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isMiniDisabled(offset, miniDisableRanges) {
|
||||||
|
for (const [start, end] of miniDisableRanges) {
|
||||||
|
if (offset >= start && offset < end) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue