From 79187160bcf3ca0e24d0371cdaf0defcd2fc6824 Mon Sep 17 00:00:00 2001 From: Evan Wallace Date: Tue, 14 Dec 2021 00:36:15 +0000 Subject: [PATCH] automatically add __PURE__ to WeakMap and WeakSet --- internal/js_parser/js_parser.go | 29 ++++++++++++++++++++++++++++ internal/js_parser/js_parser_test.go | 28 +++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/internal/js_parser/js_parser.go b/internal/js_parser/js_parser.go index 03141a7352d..6203a2f6758 100644 --- a/internal/js_parser/js_parser.go +++ b/internal/js_parser/js_parser.go @@ -13103,6 +13103,35 @@ func (p *parser) maybeMarkKnownGlobalConstructorAsPure(e *js_ast.ENew) { if id, ok := e.Target.Data.(*js_ast.EIdentifier); ok { if symbol := p.symbols[id.Ref.InnerIndex]; symbol.Kind == js_ast.SymbolUnbound { switch symbol.OriginalName { + case "WeakSet", "WeakMap": + n := len(e.Args) + + if n == 0 { + // "new WeakSet()" is pure + e.CanBeUnwrappedIfUnused = true + break + } + + if n == 1 { + switch arg := e.Args[0].Data.(type) { + case *js_ast.ENull, *js_ast.EUndefined: + // "new WeakSet(null)" is pure + // "new WeakSet(void 0)" is pure + e.CanBeUnwrappedIfUnused = true + + case *js_ast.EArray: + if len(arg.Items) == 0 { + // "new WeakSet([])" is pure + e.CanBeUnwrappedIfUnused = true + } else { + // "new WeakSet([x])" is impure because an exception is thrown if "x" is not an object + } + + default: + // "new WeakSet(x)" is impure because the iterator for "x" could have side effects + } + } + case "Set": n := len(e.Args) diff --git a/internal/js_parser/js_parser_test.go b/internal/js_parser/js_parser_test.go index 961ede1403f..f48036fc5c6 100644 --- a/internal/js_parser/js_parser_test.go +++ b/internal/js_parser/js_parser_test.go @@ -4911,3 +4911,31 @@ func TestAutoPureForMap(t *testing.T) { expectPrinted(t, "new Map([x, []])", "new Map([x, []]);\n") expectPrinted(t, "new Map([[], x])", "new Map([[], x]);\n") } + +func TestAutoPureForWeakSet(t *testing.T) { + expectPrinted(t, "new WeakSet", "/* @__PURE__ */ new WeakSet();\n") + expectPrinted(t, "new WeakSet(null)", "/* @__PURE__ */ new WeakSet(null);\n") + expectPrinted(t, "new WeakSet(undefined)", "/* @__PURE__ */ new WeakSet(void 0);\n") + expectPrinted(t, "new WeakSet([])", "/* @__PURE__ */ new WeakSet([]);\n") + + expectPrinted(t, "new WeakSet([x])", "new WeakSet([x]);\n") + expectPrinted(t, "new WeakSet(x)", "new WeakSet(x);\n") + expectPrinted(t, "new WeakSet(false)", "new WeakSet(false);\n") + expectPrinted(t, "new WeakSet({})", "new WeakSet({});\n") + expectPrinted(t, "new WeakSet({ x })", "new WeakSet({ x });\n") +} + +func TestAutoPureForWeakMap(t *testing.T) { + expectPrinted(t, "new WeakMap", "/* @__PURE__ */ new WeakMap();\n") + expectPrinted(t, "new WeakMap(null)", "/* @__PURE__ */ new WeakMap(null);\n") + expectPrinted(t, "new WeakMap(undefined)", "/* @__PURE__ */ new WeakMap(void 0);\n") + expectPrinted(t, "new WeakMap([])", "/* @__PURE__ */ new WeakMap([]);\n") + + expectPrinted(t, "new WeakMap([[]])", "new WeakMap([[]]);\n") + expectPrinted(t, "new WeakMap([[], []])", "new WeakMap([[], []]);\n") + expectPrinted(t, "new WeakMap(x)", "new WeakMap(x);\n") + expectPrinted(t, "new WeakMap(false)", "new WeakMap(false);\n") + expectPrinted(t, "new WeakMap([x])", "new WeakMap([x]);\n") + expectPrinted(t, "new WeakMap([x, []])", "new WeakMap([x, []]);\n") + expectPrinted(t, "new WeakMap([[], x])", "new WeakMap([[], x]);\n") +}