Leftover AST nodes in compiled output
Adapted from #605 (closed)
import { isPunctuator, fromPunctuator } from './helpers' for syntax;
syntax m = ctx => {
let delim = ctx.next().value;
var arr = [];
for (let item of ctx.contextify(delim)) {
if (!isPunctuator(item, ',')) {
arr.push(item);
arr.push(fromPunctuator(item, ','));
arr.push(item);
} else {
arr.push(item);
}
}
return #`[${arr}]`;
}
m {
1, 2, 3, "sdf"
}
// expected
[1, 1, 2, 2, 3, 3, "sdf", "sdf"];
// actual
;
;
[1, 1, 2, 2, 3, 3, "sdf", "sdf"];
This puzzled me for a long time as I assumed it was an issue w/ ASI. Then I tried looking at the generated AST before codegen:
{
exportedNames: [],
items: [
{ type: 'EmptyStatement', loc: null },
{
declaration: {
kind: 'syntax',
declarators: [{
binding: {
name: {
token: {..., value: 'm', ...},
bindings: Map {...},
scopesets: {...}
},
type: 'BindingIdentifier',
loc: null
},
init: {
params: {
items: [...],
rest: null,
type: 'FormalParameters',
loc: null
},
body: {
directives: [],
statements: [...],
type: 'FunctionBody',
loc: null
},
type: 'ArrowExpression',
loc: null
},
type: 'VariableDeclarator',
loc: null
}],
type: 'VariableDeclaration',
loc: null
},
type: 'VariableDeclarationStatement',
loc: null
}, {
expression: {
elements: [...],
type: 'ArrayExpression',
loc: null
},
type: 'ExpressionStatement',
loc: null
},
exports: []
}
It looks like an import ... for syntax
is being replaced w/ an EmptyStatement
. This is reasonable, but it would probably be better to just remove it from the list of items.
The more concerning issue is that the macro definition isn't being erased. It's not displaying, I'm guessing, because shift-codegen
doesn't know what to do w/ VariableDeclaration#kind
equal to syntax
.
I know it doesn't affect the how the code executes, but it looks messy and I'd rather have it cleared up before v3.0.0 is released.
@disnet do you have any pointers to where the erasure should be happening?