-
Fix some parsing edge cases (#835)
This release fixes the following edge cases:
-
Code using
in
inside a template literal inside a for loop initializer such asfor (let x = `${a in b ? '0' : '1'}`; false; );
is now allowed. Previously thein
operator was incorrectly considered to be part of a for-in loop. -
In TypeScript, it's not valid to have a newline in between the
async
and the<
tokens inside the codeasync <T>() => {}
. Previously this was incorrectly treated as an asynchronous arrow function expression. -
Code of the form
new async()
must construct the function calledasync
. Previously this was incorrectly treated asnew (async())()
instead due to the speculative parsing of asynchronous arrow functions. -
Code of the form
new async () => {}
must not be allowed. Previously this was incorrectly allowed since the speculative parsing of asynchronous arrow functions did not check the precedence level. -
It's not valid to start an initializer expression in a for-of loop with the token
let
such asfor (let.foo of bar) {}
. This is now forbidden. In addition, the code generator now respects this rule sofor ((let.foo) of bar) {}
is now printed asfor ((let).foo of bar) {}
. -
Array and object binding patterns do not allow a comma after rest elements, so code such as
[...a, b] = [c]
is invalid. This case is correctly handled by esbuild. However, it's possible to have both an array or object binding pattern and an array or object literal on the left-hand side of a destructuring assignment such as[[...a, b].c] = [d]
. In that case it should be allowed for a comma to come after the spread element in the array or object literal expression. Previously this was incorrectly treated as an error by esbuild. -
It's technically allowed (although perhaps not ever actually useful) to call
super()
from within a default argument initializer like this:class Derived extends Base { constructor(arg = super()) { } }
Previously esbuild did not permit this, which is incorrect. Doing this is now permitted.
-
It is an error to use
arguments
in a class field initializer such asclass { x = arguments[0] }
, but it is not an error to usearguments
in a computed class property name such asclass { [arguments[0]] = x }
or inside TypeScript decorators such asclass { @decorator(arguments[0]) x() {} }
. Previously all of these cases were an error in esbuild, which is incorrect. Usingarguments
inside computed class property names and TypeScript decorators is now allowed. -
It is not permitted to use a function declaration inside an if statement such as
if (0) function f() {}
in strict mode. Previously this was allowed, but this is now forbidden. -
It is not permitted to re-declare a generator and/or asynchronous function declaration inside a block scope:
// This is allowed function *a() {} function *a() {} // This is allowed function f() { function *b() {} function *b() {} } // This is not allowed { function *c() {} function *c() {} }
The parser now enforces this rule.
-
Legacy octal escape sequences are octal escape sequences other than
\0
with a single zero. These are forbidden in untagged template literals and in all strings in strict mode code. Previously esbuild didn't enforce this rule, but it is now enforced. -
Technically the directive prologue is allowed to contain multiple directives, so strict mode should still be applied even if a
"use strict";
directive is preceded by another directive. For example,"use \000"; "use strict";
should be a syntax error because strict mode is active. This technicality has now been implemented. -
It is supposed to be a syntax error if a use strict directive is inside a function with a non-simple parameter list, such as
(x = 1) => { 'use strict' }
. Previously esbuild allowed this code, but now this code is a syntax error. -
It is forbidden for a template literal tag to be an optional chain such as
a?.b`c`
. This rule is now enforced by esbuild, so code like this is now a syntax error. In addition, the code generator now avoids generating this syntax by wrapping any optional chain template literal tags in parentheses. -
According to the standard, all code inside a class statement or expression should be in strict mode. Previously esbuild treated code inside a class as the same strict mode status as the surrounding code, but now code in a class is always interpreted as strict mode code.
-
Duplicate bindings in the same parameter list are not allowed if the parameter list isn't simple, such as in the code
function f(a, [a]) {}
, or if the parameter list belongs to an arrow function or a method. This rule is now enforced by esbuild's parser, so doing this is now a syntax error. -
Array and object destructuring patterns are only valid if they are not surrounded by parentheses. Previously esbuild incorrectly allowed code such as
([]) = []
and({}) = {}
. This invalid code is now a syntax error. -
It is now an error to use the shorthand property syntax
({yield})
inside a generator and({await})
inside an asynchronous function. Previously those cases were incorrectly allowed. -
A newline in between
async
and a method name is no longer allowed. Instead, this is a syntax error inside an object literal and a class field inside a class body.
-
-
Remove the local web server feature from the WebAssembly package (#836)
This feature didn't work anyway (maybe sockets don't work with Go's WebAssembly target?) and including it added around 3mb of unnecessary extra code to the WebAssembly module file. Removing this brings the size of the WebAssembly module from around 11mb down to 8.3mb.