Skip to content

Commit

Permalink
feat: simple destructuring support (#154)
Browse files Browse the repository at this point in the history
* feat: simple destructuring support

* handle more variations

* fixup
  • Loading branch information
guybedford committed Jun 10, 2023
1 parent 36ce8f0 commit 224531c
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 18 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -6,3 +6,4 @@ yarn.lock
lib/lexer.emcc.js
src/lexer.js
types/lexer.d.ts
src/*.mem
2 changes: 1 addition & 1 deletion lib/lexer.asm.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion lib/lexer.emcc.asm.js

Large diffs are not rendered by default.

Binary file modified lib/lexer.wasm
Binary file not shown.
51 changes: 37 additions & 14 deletions src/lexer.c
Expand Up @@ -510,28 +510,51 @@ void tryParseExportStatement () {
// export var/let/const name = ...(, name = ...)+
case 'v':
case 'l':
// destructured initializations not currently supported (skipped for { or [)
// also, lexing names after variable equals is skipped (export var p = function () { ... }, q = 5 skips "q")
pos += 2;
// simple declaration lexing only handles names. Any syntax after variable equals is skipped
// (export var p = function () { ... }, q = 5 skips "q")
pos += 3;
facade = false;
do {
pos++;
ch = commentWhitespace(true);
startPos = pos;
ch = readToWsOrPunctuator(ch);
// very basic destructuring support only of the singular form:
// export const { a, b, ...c }
// without aliasing, nesting or defaults
bool destructuring = ch == '{' || ch == '[';
const char16_t* destructuringPos = pos;
if (destructuring) {
pos += 1;
ch = commentWhitespace(true);
const char16_t* startPos = pos;
startPos = pos;
ch = readToWsOrPunctuator(ch);
// dont yet handle [ { destructurings
if (ch == '{' || ch == '[') {
break;
}
}
do {
if (pos == startPos)
return;
break;
addExport(startPos, pos, startPos, pos);
ch = commentWhitespace(true);
if (ch == '=') {
if (destructuring && (ch == '}' || ch == ']')) {
destructuring = false;
break;
}
} while (ch == ',');
pos--;
if (ch != ',') {
pos -= 1;
break;
}
pos++;
ch = commentWhitespace(true);
startPos = pos;
// internal destructurings unsupported
if (ch == '{' || ch == '[') {
pos -= 1;
break;
}
ch = readToWsOrPunctuator(ch);
} while (true);
// if stuck inside destructuring syntax, backtrack
if (destructuring) {
pos = (char16_t*)destructuringPos - 1;
}
return;

default:
Expand Down
15 changes: 13 additions & 2 deletions test/_unit.cjs
Expand Up @@ -39,6 +39,17 @@ function assertExportIs(source, actual, expected) {
suite('Lexer', () => {
beforeEach(async () => await init);

test(`Simple export destructuring`, () => {
const source = `
export const{URI,Utils,...Another}=LIB
export var p, { z } = {};
export var { aa, qq: { z } } = { qq: {} }, pp = {};
`;
const [, exports] = parse(source);
assert.deepStrictEqual(exports.map(e => e.n), ['URI', 'Utils', 'p', 'aa', 'qq']);
});

test(`Export default cases`, () => {
const source = `
export default "export default a"
Expand Down Expand Up @@ -343,8 +354,8 @@ suite('Lexer', () => {
export { ok };
`;
const [, exports] = parse(source);
assert.strictEqual(exports.length, 1);
assertExportIs(source, exports[0], { n: 'ok', ln: 'ok' });
assert.strictEqual(exports.length, 3);
assertExportIs(source, exports[0], { n: 'a', ln: 'a' });
});

test('Minified import syntax', () => {
Expand Down

0 comments on commit 224531c

Please sign in to comment.