Skip to content

Commit

Permalink
Support module.exports = { name }
Browse files Browse the repository at this point in the history
  • Loading branch information
kasperisager committed Nov 5, 2024
1 parent de0c344 commit 21e49bd
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 8 deletions.
62 changes: 54 additions & 8 deletions lex.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,26 @@ enum {
bare_module_lexer_reexport = 0x20,
};

static inline bool
bare_module_lexer__is_line_terminator (uint8_t c) {
return c == 0xa || c == 0xd;
}

static inline bool
bare_module_lexer__is_whitespace (uint8_t c) {
return c == ' ' || c == '\t' || c == 0xb || c == 0xc || c == 0xa0 || bare_module_lexer__is_line_terminator(c);
}

static inline bool
bare_module_lexer__is_id_start (uint8_t c) {
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || c == '$';
}

static inline bool
bare_module_lexer__is_id (uint8_t c) {
return bare_module_lexer__is_id_start(c) || (c >= '0' && c <= '9');
}

static inline int
bare_module_lexer__add_position (js_env_t *env, js_value_t *entry, size_t statement_start, size_t input_start, size_t input_end) {
int err;
Expand Down Expand Up @@ -169,18 +189,17 @@ bare_module_lexer__lex (js_env_t *env, js_value_t *imports, js_value_t *exports,
// Current character, checked
#define c(offset) (i + offset < n ? u(offset) : -1)

// Whitespace character
#define ws(c) (c == ' ' || c == '\t' || c == 0xb || c == 0xc || c == 0xa0)

// Line terminator
#define lt(c) (c == 0xa || c == 0xd)

// Begins with string, unchecked
#define bu(t, l) (strncmp((const char *) &s[i], t, l) == 0)

// Begins with string, checked
#define bc(t, l) (i + l < n && bu(t, l))

#define lt bare_module_lexer__is_line_terminator
#define ws bare_module_lexer__is_whitespace
#define ids bare_module_lexer__is_id_start
#define id bare_module_lexer__is_id

while (i < n) {
while (i < n && ws(u(0))) i++;

Expand Down Expand Up @@ -506,6 +525,31 @@ bare_module_lexer__lex (js_env_t *env, js_value_t *imports, js_value_t *exports,

// exports = \{
if (c(0) == '{') {
i++;

while (c(0) != '}') {
while (i < n && ws(u(0))) i++;

if (ids(c(0))) {
ss = i++;

while (id(c(0))) i++;

se = i;

err = bare_module_lexer__add_export(env, exports, &el, s, es, ss, se);
if (err < 0) goto err;
}

while (i < n && ws(u(0))) i++;

if (c(0) != ',') break;

i++;
}

// exports = \{[^}]*\}
if (c(0) == '}') i++;
}

// exports = require
Expand Down Expand Up @@ -614,10 +658,12 @@ bare_module_lexer__lex (js_env_t *env, js_value_t *imports, js_value_t *exports,

#undef u
#undef c
#undef ws
#undef lt
#undef bu
#undef bc
#undef lt
#undef ws
#undef ids
#undef id

return 0;

Expand Down
26 changes: 26 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,32 @@ test('module.exports["name"]', (t) => {
})
})

test('module.exports = {}', (t) => {
t.alike(lex('module.exports = {}'), {
imports: [],
exports: []
})
})

test('module.exports = { name }', (t) => {
t.alike(lex('module.exports = { foo }'), {
imports: [],
exports: [{ name: 'foo', position: [0, 19, 22] }]
})
})

test('module.exports = { name, name }', (t) => {
t.alike(lex('module.exports = { foo, bar }'), {
imports: [],
exports: [{ name: 'foo', position: [0, 19, 22] }, { name: 'bar', position: [0, 24, 27] }]
})

t.alike(lex('module.exports = { foo,\n bar }'), {
imports: [],
exports: [{ name: 'foo', position: [0, 19, 22] }, { name: 'bar', position: [0, 25, 28] }]
})
})

test('import \'id\'', (t) => {
t.alike(lex('import \'./foo.js\''), {
imports: [{ specifier: './foo.js', type: IMPORT, names: [], position: [0, 8, 16] }],
Expand Down

0 comments on commit 21e49bd

Please sign in to comment.