From d06bfdb04ef33bf87ff553d408de2efe1fe5ea72 Mon Sep 17 00:00:00 2001 From: Evan Wallace Date: Sat, 27 Mar 2021 15:46:20 -0700 Subject: [PATCH] release notes for #1067 --- CHANGELOG.md | 17 +++++++++++++++++ internal/js_parser/js_parser.go | 2 +- internal/js_parser/js_parser_test.go | 4 ++-- scripts/end-to-end-tests.js | 4 ++-- 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c87a676b40..d39dc953279 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,22 @@ # Changelog +## Unreleased + +* Warn about mutation of private methods ([#1067](https://github.com/evanw/esbuild/pull/1067)) + + Mutating a private method in JavaScript is not allowed, and will throw at run-time: + + ```js + class Foo { + #method() {} + mutate() { + this.#method = () => {} + } + } + ``` + + This is the case both when esbuild passes the syntax through untransformed and when esbuild transforms the syntax into the equivalent code that uses a `WeakSet` to emulate private methods in older browsers. However, it's clear from this code that doing this will always throw, so this code is almost surely a mistake. With this release, esbuild will now warn when you do this. This change was contributed by [@jridgewell](https://github.com/jridgewell). + ## 0.10.2 * Fix a crash that was introduced in the previous release ([#1064](https://github.com/evanw/esbuild/issues/1064)) diff --git a/internal/js_parser/js_parser.go b/internal/js_parser/js_parser.go index 00416588abf..726dec8dadc 100644 --- a/internal/js_parser/js_parser.go +++ b/internal/js_parser/js_parser.go @@ -10554,7 +10554,7 @@ func (p *parser) visitExprInOut(expr js_ast.Expr, in exprIn) (js_ast.Expr, exprO } else if !p.options.suppressWarningsAboutWeirdCode { if in.assignTarget != js_ast.AssignTargetNone && (kind == js_ast.SymbolPrivateMethod || kind == js_ast.SymbolPrivateStaticMethod) { r := logger.Range{Loc: e.Index.Loc, Len: int32(len(name))} - p.log.AddRangeWarning(&p.source, r, fmt.Sprintf("Writing to readonly method %q will throw", name)) + p.log.AddRangeWarning(&p.source, r, fmt.Sprintf("Writing to read-only method %q will throw", name)) } else if in.assignTarget != js_ast.AssignTargetNone && (kind == js_ast.SymbolPrivateGet || kind == js_ast.SymbolPrivateStaticGet) { r := logger.Range{Loc: e.Index.Loc, Len: int32(len(name))} p.log.AddRangeWarning(&p.source, r, fmt.Sprintf("Writing to getter-only property %q will throw", name)) diff --git a/internal/js_parser/js_parser_test.go b/internal/js_parser/js_parser_test.go index afe752f4ad2..824a8e3f90c 100644 --- a/internal/js_parser/js_parser_test.go +++ b/internal/js_parser/js_parser_test.go @@ -3902,9 +3902,9 @@ func TestPrivateIdentifiers(t *testing.T) { // Writing to method warnings expectParseError(t, "class Foo { #x() { this.#x = 1 } }", - ": warning: Writing to readonly method \"#x\" will throw\n") + ": warning: Writing to read-only method \"#x\" will throw\n") expectParseError(t, "class Foo { #x() { this.#x += 1 } }", - ": warning: Writing to readonly method \"#x\" will throw\n") + ": warning: Writing to read-only method \"#x\" will throw\n") expectPrinted(t, `class Foo { #if diff --git a/scripts/end-to-end-tests.js b/scripts/end-to-end-tests.js index 55c57303426..c103193d6ee 100644 --- a/scripts/end-to-end-tests.js +++ b/scripts/end-to-end-tests.js @@ -2053,7 +2053,7 @@ new Foo().bar() `, }, { - expectedStderr: ` > in.js:22:29: warning: Writing to readonly method "#method" will throw + expectedStderr: ` > in.js:22:29: warning: Writing to read-only method "#method" will throw 22 │ expect(() => obj.#method = 1, 'Cannot write to private f... ╵ ~~~~~~~ @@ -2065,7 +2065,7 @@ 24 │ expect(() => this.#getter = 1, 'member.set is not a func... ╵ ~~~~~~~ - > in.js:25:30: warning: Writing to readonly method "#method" will throw + > in.js:25:30: warning: Writing to read-only method "#method" will throw 25 │ expect(() => this.#method = 1, 'member.set is not a func... ╵ ~~~~~~~