Skip to content

Commit dfe5675

Browse files
authored
Allow 'undefined' in let or const declaration (#639)
Except at the global scope of a classic script because... who knows, that's just how it is. Fixes: #633
1 parent 42262a7 commit dfe5675

File tree

6 files changed

+35
-4
lines changed

6 files changed

+35
-4
lines changed

quickjs.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22709,9 +22709,17 @@ static __exception int js_define_var(JSParseState *s, JSAtom name, int tok)
2270922709
&& fd->is_strict_mode) {
2271022710
return js_parse_error(s, "invalid variable name in strict mode");
2271122711
}
22712-
if ((name == JS_ATOM_let || name == JS_ATOM_undefined)
22713-
&& (tok == TOK_LET || tok == TOK_CONST)) {
22714-
return js_parse_error(s, "invalid lexical variable name");
22712+
if (tok == TOK_LET || tok == TOK_CONST) {
22713+
if (name == JS_ATOM_let)
22714+
return js_parse_error(s, "invalid lexical variable name 'let'");
22715+
// |undefined| is allowed as an identifier except at the global
22716+
// scope of a classic script; sloppy or strict doesn't matter
22717+
if (name == JS_ATOM_undefined
22718+
&& fd->scope_level == 1
22719+
&& fd->is_global_var
22720+
&& !fd->module) {
22721+
return js_parse_error(s, "'undefined' already declared");
22722+
}
2271522723
}
2271622724
switch(tok) {
2271722725
case TOK_LET:

run-test262.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1783,6 +1783,7 @@ int run_test(const char *filename, int *msec)
17831783
char *error_type;
17841784
int ret, eval_flags, use_strict, use_nostrict;
17851785
BOOL is_negative, is_nostrict, is_onlystrict, is_async, is_module, skip;
1786+
BOOL detect_module = TRUE;
17861787
BOOL can_block;
17871788
namelist_t include_list = { 0 }, *ip = &include_list;
17881789

@@ -1838,6 +1839,9 @@ int run_test(const char *filename, int *msec)
18381839
is_async = TRUE;
18391840
skip |= skip_async;
18401841
}
1842+
else if (str_equal(option, "qjs:no-detect-module")) {
1843+
detect_module = FALSE;
1844+
}
18411845
else if (str_equal(option, "module")) {
18421846
is_module = TRUE;
18431847
skip |= skip_module;
@@ -1920,7 +1924,7 @@ int run_test(const char *filename, int *msec)
19201924
atomic_inc(&test_skipped);
19211925
ret = -2;
19221926
} else {
1923-
if (local) {
1927+
if (local && detect_module) {
19241928
is_module = JS_DetectModule(buf, buf_len);
19251929
}
19261930
if (is_module) {

tests/bug633/0.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/*---
2+
flags: [qjs:no-detect-module]
3+
negative:
4+
phase: parse
5+
type: SyntaxError
6+
---*/
7+
const undefined = 42 // SyntaxError at global scope

tests/bug633/1.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/*---
2+
flags: [qjs:no-detect-module, module]
3+
---*/
4+
const undefined = 42 // not a SyntaxError at toplevel module scope

tests/bug633/2.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/*---
2+
flags: [qjs:no-detect-module]
3+
---*/
4+
{ const undefined = 42 } // not a SyntaxError, not at global scope

tests/bug633/3.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/*---
2+
flags: [qjs:no-detect-module]
3+
---*/
4+
;(function() { const undefined = 42 })() // not a SyntaxError, not at global scope

0 commit comments

Comments
 (0)