Skip to content

Commit

Permalink
fix #1560: bug with "!" after "new" in TypeScript
Browse files Browse the repository at this point in the history
  • Loading branch information
evanw committed Aug 31, 2021
1 parent 66f1d16 commit 9f507f4
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 15 deletions.
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
# Changelog

## Unreleased

* Fix a TypeScript parsing edge case with the postfix `!` operator ([#1560](https://github.com/evanw/esbuild/issues/1560))

This release fixes a bug with esbuild's TypeScript parser where the postfix `!` operator incorrectly terminated a member expression after the `new` operator:

```js
// Original input
new Foo!.Bar();

// Old output
new Foo().Bar();

// New output
new Foo.Bar();
```

The problem was that `!` was considered a postfix operator instead of part of a member expression. It is now considered to be part of a member expression instead, which fixes this edge case.

## 0.12.24

* Fix an edge case with direct `eval` and variable renaming
Expand Down
15 changes: 0 additions & 15 deletions internal/js_parser/js_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -3109,18 +3109,6 @@ func (p *parser) parsePrefix(level js_ast.L, errors *deferredErrors, flags exprF
target := p.parseExprWithFlags(js_ast.LMember, flags)
args := []js_ast.Expr{}

if p.options.ts.Parse {
// Skip over TypeScript non-null assertions
if p.lexer.Token == js_lexer.TExclamation && !p.lexer.HasNewlineBefore {
p.lexer.Next()
}

// Skip over TypeScript type arguments here if there are any
if p.lexer.Token == js_lexer.TLessThan {
p.trySkipTypeScriptTypeArgumentsWithBacktracking()
}
}

if p.lexer.Token == js_lexer.TOpenParen {
args = p.parseCallArgs()
}
Expand Down Expand Up @@ -3779,9 +3767,6 @@ func (p *parser) parseSuffix(left js_ast.Expr, level js_ast.L, errors *deferredE
if !p.options.ts.Parse {
p.lexer.Unexpected()
}
if level >= js_ast.LPostfix {
return left
}
p.lexer.Next()
optionalChain = oldOptionalChain

Expand Down
4 changes: 4 additions & 0 deletions internal/js_parser/ts_parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1354,9 +1354,13 @@ func TestTSNew(t *testing.T) {

expectPrintedTS(t, "new Foo!()", "new Foo();\n")
expectPrintedTS(t, "new Foo!<number>()", "new Foo();\n")
expectPrintedTS(t, "new Foo!.Bar()", "new Foo.Bar();\n")
expectPrintedTS(t, "new Foo!.Bar<number>()", "new Foo.Bar();\n")
expectPrintedTS(t, "new Foo!['Bar']()", "new Foo[\"Bar\"]();\n")
expectPrintedTS(t, "new Foo\n!(x)", "new Foo();\n!x;\n")
expectPrintedTS(t, "new Foo<number>!(x)", "new Foo() < number > !x;\n")
expectParseErrorTS(t, "new Foo<number>!()", "<stdin>: error: Unexpected \")\"\n")
expectParseErrorTS(t, "new Foo\n!.Bar()", "<stdin>: error: Unexpected \".\"\n")
expectParseError(t, "new Foo!()", "<stdin>: error: Unexpected \"!\"\n")
}

Expand Down

0 comments on commit 9f507f4

Please sign in to comment.