Skip to content

Commit

Permalink
automatically add __PURE__ to WeakMap and WeakSet
Browse files Browse the repository at this point in the history
  • Loading branch information
evanw committed Dec 14, 2021
1 parent 22d7bdb commit 7918716
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 0 deletions.
29 changes: 29 additions & 0 deletions internal/js_parser/js_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
28 changes: 28 additions & 0 deletions internal/js_parser/js_parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}

0 comments on commit 7918716

Please sign in to comment.