Skip to content

Commit

Permalink
fixes after landing #2038
Browse files Browse the repository at this point in the history
  • Loading branch information
evanw committed Mar 10, 2022
1 parent 5b782b6 commit 9fe4a61
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 12 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@

## Unreleased

* Add support for parsing "instantiation expressions" from TypeScript 4.7 ([#2038](https://github.com/evanw/esbuild/pull/2038))

The upcoming version of TypeScript now lets you specify `<...>` type parameters on a JavaScript identifier without using a call expression:

```ts
const ErrorMap = Map<string, Error>; // new () => Map<string, Error>
const errorMap = new ErrorMap(); // Map<string, Error>
```

With this release, esbuild can now parse these new type annotations. This feature was contributed by [@g-plane](https://github.com/g-plane).

* Avoid `new Function` in esbuild's library code ([#2081](https://github.com/evanw/esbuild/issues/2081))

Some JavaScript environments such as Cloudflare Workers or Deno Deploy don't allow `new Function` because they disallow dynamic JavaScript evaluation. Previously esbuild's WebAssembly-based library used this to construct the WebAssembly worker function. With this release, the code is now inlined without using `new Function` so it will be able to run even when this restriction is in place.
Expand Down
10 changes: 4 additions & 6 deletions internal/js_lexer/js_lexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -2191,12 +2191,10 @@ func (lexer *Lexer) ScanRegExp() {
}

switch lexer.codePoint {
case '\r', '\n', 0x2028, 0x2029:
// Newlines aren't allowed in regular expressions
lexer.SyntaxError()

case -1: // This indicates the end of the file
lexer.SyntaxError()
case -1, // This indicates the end of the file
'\r', '\n', 0x2028, 0x2029: // Newlines aren't allowed in regular expressions
lexer.addRangeError(logger.Range{Loc: logger.Loc{Start: int32(lexer.end)}}, "Unterminated regular expression")
panic(LexerPanic{})

default:
lexer.step()
Expand Down
9 changes: 4 additions & 5 deletions internal/js_parser/ts_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -790,17 +790,16 @@ func (p *parser) isTSArrowFnJSX() (isTSArrowFn bool) {
func (p *parser) canFollowTypeArgumentsInExpression() bool {
switch p.lexer.Token {
case
// These are the only tokens can legally follow a type argument list. So we
// definitely want to treat them as type arg lists.
// These tokens can follow a type argument list in a call expression.
js_lexer.TOpenParen, // foo<x>(
js_lexer.TNoSubstitutionTemplateLiteral, // foo<T> `...`
js_lexer.TTemplateHead: // foo<T> `...${100}...`
return true

case
// These tokens can't follow in a call expression,
// nor can they start an expression.
// So, consider the type argument list part of an instantiation expression.
// These tokens can't follow in a call expression, nor can they start an
// expression. So, consider the type argument list part of an instantiation
// expression.
js_lexer.TComma, // foo<x>,
js_lexer.TDot, // foo<x>.
js_lexer.TQuestionDot, // foo<x>?.
Expand Down
10 changes: 9 additions & 1 deletion internal/js_parser/ts_parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1620,6 +1620,14 @@ func TestTSInstantiationExpression(t *testing.T) {

expectParseErrorTS(t, "const a8 = f<number><number>;", "<stdin>: ERROR: Unexpected \";\"\n")
expectParseErrorTS(t, "const b1 = f?.<number>;", "<stdin>: ERROR: Expected \"(\" but found \";\"\n")

// The TypeScript compiler doesn't do semicolon insertion before "<" when
// inside "typeof" but does in other situations. Was this an oversight? Not sure,
// but we replicate this behavior because it matters when JSX syntax is enabled.
expectPrintedTSX(t, "type x = typeof y\n<number>\n1", "1;\n")
expectParseErrorTS(t, "type x = typeof y\n<number>\n1\n</number>", "<stdin>: ERROR: Unterminated regular expression\n")
expectParseErrorTSX(t, "type x = y\n<number>\n1", "<stdin>: ERROR: Unexpected end of file\n")
expectPrintedTSX(t, "type x = y\n<number>\n1\n</number>", "/* @__PURE__ */ React.createElement(\"number\", null, \"1\");\n")
}

func TestTSExponentiation(t *testing.T) {
Expand Down Expand Up @@ -1952,7 +1960,7 @@ func TestTSNoAmbiguousLessThan(t *testing.T) {
"<stdin>: ERROR: This syntax is not allowed in files with the \".mts\" or \".cts\" extension\n")
expectParseErrorTSNoAmbiguousLessThan(t, "<x>y</x>",
"<stdin>: ERROR: This syntax is not allowed in files with the \".mts\" or \".cts\" extension\n"+
"<stdin>: ERROR: Unexpected end of file\n")
"<stdin>: ERROR: Unterminated regular expression\n")
expectParseErrorTSNoAmbiguousLessThan(t, "<x extends></x>",
"<stdin>: ERROR: This syntax is not allowed in files with the \".mts\" or \".cts\" extension\n"+
"<stdin>: ERROR: Unexpected \">\"\n")
Expand Down

0 comments on commit 9fe4a61

Please sign in to comment.