diff --git a/src/ast/E.zig b/src/ast/E.zig index 4b30eaa3ed..5f81aabd17 100644 --- a/src/ast/E.zig +++ b/src/ast/E.zig @@ -122,7 +122,7 @@ pub const New = struct { // True if there is a comment containing "@__PURE__" or "#__PURE__" preceding // this call expression. See the comment inside ECall for more details. - can_be_unwrapped_if_unused: bool = false, + can_be_unwrapped_if_unused: CallUnwrap = .never, close_parens_loc: logger.Loc, }; @@ -171,7 +171,7 @@ pub const Call = struct { // Note that the arguments are not considered to be part of the call. If the // call itself is removed due to this annotation, the arguments must remain // if they have side effects. - can_be_unwrapped_if_unused: bool = false, + can_be_unwrapped_if_unused: CallUnwrap = .never, // Used when printing to generate the source prop on the fly was_jsx_element: bool = false, @@ -183,6 +183,12 @@ pub const Call = struct { } }; +pub const CallUnwrap = enum(u2) { + never, + if_unused, + if_unused_and_toString_safe, +}; + pub const Dot = struct { // target is Node target: ExprNodeIndex, @@ -197,7 +203,7 @@ pub const Dot = struct { // If true, this property access is a function that, when called, can be // unwrapped if the resulting value is unused. Unwrapping means discarding // the call target but keeping any arguments with side effects. - call_can_be_unwrapped_if_unused: bool = false, + call_can_be_unwrapped_if_unused: CallUnwrap = .never, pub fn hasSameFlagsAs(a: *Dot, b: *Dot) bool { return (a.optional_chain == b.optional_chain and diff --git a/src/ast/Expr.zig b/src/ast/Expr.zig index d3939cd938..d86486f94c 100644 --- a/src/ast/Expr.zig +++ b/src/ast/Expr.zig @@ -2670,6 +2670,19 @@ pub const Data = union(Tag) { }; } + pub fn isSafeToString(data: Expr.Data) bool { + return switch (data) { + // rope strings can throw when toString is called. + .e_string => |str| str.next == null, + + .e_number, .e_boolean, .e_undefined, .e_null => true, + // BigInt is deliberately excluded as a large enough BigInt could throw an out of memory error. + // + + else => false, + }; + } + pub fn knownPrimitive(data: Expr.Data) PrimitiveType { return switch (data) { .e_big_int => .bigint, diff --git a/src/bun.js/RuntimeTranspilerCache.zig b/src/bun.js/RuntimeTranspilerCache.zig index dbab5c9958..ff195b989a 100644 --- a/src/bun.js/RuntimeTranspilerCache.zig +++ b/src/bun.js/RuntimeTranspilerCache.zig @@ -11,7 +11,8 @@ /// Version 12: "use strict"; makes it CommonJS if we otherwise don't know which one to pick. /// Version 13: Hoist `import.meta.require` definition, see #15738 /// Version 14: Updated global defines table list. -const expected_version = 14; +/// Version 15: Updated global defines table list. +const expected_version = 15; const bun = @import("bun"); const std = @import("std"); diff --git a/src/cli/build_command.zig b/src/cli/build_command.zig index 4258efc82d..ec05e81a48 100644 --- a/src/cli/build_command.zig +++ b/src/cli/build_command.zig @@ -263,6 +263,7 @@ pub const BuildCommand = struct { null, null, this_transpiler.options.define.drop_debugger, + this_transpiler.options.dead_code_elimination and this_transpiler.options.minify_syntax, ); try bun.bake.addImportMetaDefines(allocator, this_transpiler.options.define, .development, .server); diff --git a/src/defines-table.zig b/src/defines-table.zig index feab03ffcc..41f4438fd7 100644 --- a/src/defines-table.zig +++ b/src/defines-table.zig @@ -18,54 +18,16 @@ const defines = @import("./defines.zig"); // Note that membership in this list says nothing about whether calling any of // these functions has any side effects. It only says something about // referencing these function without calling them. -pub const GlobalDefinesKey = [_][]const string{ - +pub const global_no_side_effect_property_accesses = &[_][]const string{ // Array: Static methods // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array#Static_methods &[_]string{ "Array", "from" }, - &[_]string{ "Array", "of" }, &[_]string{ "Array", "isArray" }, + &[_]string{ "Array", "of" }, - // Object: Static methods - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object#Static_methods - &[_]string{ "Object", "assign" }, - &[_]string{ "Object", "create" }, - &[_]string{ "Object", "defineProperties" }, - &[_]string{ "Object", "defineProperty" }, - &[_]string{ "Object", "entries" }, - &[_]string{ "Object", "freeze" }, - &[_]string{ "Object", "fromEntries" }, - &[_]string{ "Object", "getOwnPropertyDescriptor" }, - &[_]string{ "Object", "getOwnPropertyDescriptors" }, - &[_]string{ "Object", "getOwnPropertyNames" }, - &[_]string{ "Object", "getOwnPropertySymbols" }, - &[_]string{ "Object", "getPrototypeOf" }, - &[_]string{ "Object", "groupBy" }, - &[_]string{ "Object", "hasOwn" }, - &[_]string{ "Object", "is" }, - &[_]string{ "Object", "isExtensible" }, - &[_]string{ "Object", "isFrozen" }, - &[_]string{ "Object", "isSealed" }, - &[_]string{ "Object", "keys" }, - &[_]string{ "Object", "preventExtensions" }, - &[_]string{ "Object", "seal" }, - &[_]string{ "Object", "setPrototypeOf" }, - &[_]string{ "Object", "values" }, - - // Object: Instance methods - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object#Instance_methods - &[_]string{ "Object", "prototype", "__defineGetter__" }, - &[_]string{ "Object", "prototype", "__defineSetter__" }, - &[_]string{ "Object", "prototype", "__lookupGetter__" }, - &[_]string{ "Object", "prototype", "__lookupSetter__" }, - &[_]string{ "Object", "prototype", "hasOwnProperty" }, - &[_]string{ "Object", "prototype", "isPrototypeOf" }, - &[_]string{ "Object", "prototype", "propertyIsEnumerable" }, - &[_]string{ "Object", "prototype", "toLocaleString" }, - &[_]string{ "Object", "prototype", "toString" }, - &[_]string{ "Object", "prototype", "unwatch" }, - &[_]string{ "Object", "prototype", "valueOf" }, - &[_]string{ "Object", "prototype", "watch" }, + // JSON: Static methods + &[_]string{ "JSON", "parse" }, + &[_]string{ "JSON", "stringify" }, // Math: Static properties // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math#Static_properties @@ -116,10 +78,70 @@ pub const GlobalDefinesKey = [_][]const string{ &[_]string{ "Math", "tanh" }, &[_]string{ "Math", "trunc" }, - // Symbol: Static methods - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol#static_methods - &[_]string{ "Symbol", "for" }, - &[_]string{ "Symbol", "keyFor" }, + // Number: Static methods + &[_]string{ "Number", "isFinite" }, + &[_]string{ "Number", "isInteger" }, + &[_]string{ "Number", "isNaN" }, + &[_]string{ "Number", "isSafeInteger" }, + &[_]string{ "Number", "parseFloat" }, + &[_]string{ "Number", "parseInt" }, + + // Object: Static methods + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object#Static_methods + &[_]string{ "Object", "assign" }, + &[_]string{ "Object", "create" }, + &[_]string{ "Object", "defineProperties" }, + &[_]string{ "Object", "defineProperty" }, + &[_]string{ "Object", "entries" }, + &[_]string{ "Object", "freeze" }, + &[_]string{ "Object", "fromEntries" }, + &[_]string{ "Object", "getOwnPropertyDescriptor" }, + &[_]string{ "Object", "getOwnPropertyDescriptors" }, + &[_]string{ "Object", "getOwnPropertyNames" }, + &[_]string{ "Object", "getOwnPropertySymbols" }, + &[_]string{ "Object", "getPrototypeOf" }, + &[_]string{ "Object", "groupBy" }, + &[_]string{ "Object", "hasOwn" }, + &[_]string{ "Object", "is" }, + &[_]string{ "Object", "isExtensible" }, + &[_]string{ "Object", "isFrozen" }, + &[_]string{ "Object", "isSealed" }, + &[_]string{ "Object", "keys" }, + &[_]string{ "Object", "preventExtensions" }, + &[_]string{ "Object", "seal" }, + &[_]string{ "Object", "setPrototypeOf" }, + &[_]string{ "Object", "values" }, + + // Object: Instance methods + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object#Instance_methods + &[_]string{ "Object", "prototype", "__defineGetter__" }, + &[_]string{ "Object", "prototype", "__defineSetter__" }, + &[_]string{ "Object", "prototype", "__lookupGetter__" }, + &[_]string{ "Object", "prototype", "__lookupSetter__" }, + &[_]string{ "Object", "prototype", "hasOwnProperty" }, + &[_]string{ "Object", "prototype", "isPrototypeOf" }, + &[_]string{ "Object", "prototype", "propertyIsEnumerable" }, + &[_]string{ "Object", "prototype", "toLocaleString" }, + &[_]string{ "Object", "prototype", "toString" }, + &[_]string{ "Object", "prototype", "unwatch" }, + &[_]string{ "Object", "prototype", "valueOf" }, + &[_]string{ "Object", "prototype", "watch" }, + + // Reflect: Static methods + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect#static_methods + &[_]string{ "Reflect", "apply" }, + &[_]string{ "Reflect", "construct" }, + &[_]string{ "Reflect", "defineProperty" }, + &[_]string{ "Reflect", "deleteProperty" }, + &[_]string{ "Reflect", "get" }, + &[_]string{ "Reflect", "getOwnPropertyDescriptor" }, + &[_]string{ "Reflect", "getPrototypeOf" }, + &[_]string{ "Reflect", "has" }, + &[_]string{ "Reflect", "isExtensible" }, + &[_]string{ "Reflect", "ownKeys" }, + &[_]string{ "Reflect", "preventExtensions" }, + &[_]string{ "Reflect", "set" }, + &[_]string{ "Reflect", "setPrototypeOf" }, // Symbol: Static properties // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol#static_properties @@ -139,24 +161,9 @@ pub const GlobalDefinesKey = [_][]const string{ &[_]string{ "Symbol", "toStringTag" }, &[_]string{ "Symbol", "unscopables" }, - // Reflect: Static methods - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect#static_methods - &[_]string{ "Reflect", "apply" }, - &[_]string{ "Reflect", "construct" }, - &[_]string{ "Reflect", "defineProperty" }, - &[_]string{ "Reflect", "deleteProperty" }, - &[_]string{ "Reflect", "get" }, - &[_]string{ "Reflect", "getOwnPropertyDescriptor" }, - &[_]string{ "Reflect", "getPrototypeOf" }, - &[_]string{ "Reflect", "has" }, - &[_]string{ "Reflect", "isExtensible" }, - &[_]string{ "Reflect", "ownKeys" }, - &[_]string{ "Reflect", "preventExtensions" }, - &[_]string{ "Reflect", "set" }, - &[_]string{ "Reflect", "setPrototypeOf" }, - - &[_]string{ "JSON", "parse" }, - &[_]string{ "JSON", "stringify" }, + // Symbol: Static methods + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol#static_methods + &[_]string{ "Symbol", "keyFor" }, // Console method references are assumed to have no side effects // https://developer.mozilla.org/en-US/docs/Web/API/console @@ -180,12 +187,24 @@ pub const GlobalDefinesKey = [_][]const string{ &[_]string{ "console", "trace" }, &[_]string{ "console", "warn" }, + // Crypto: Static methods &[_]string{ "crypto", "randomUUID" }, }; -const pure_global_identifier_define = defines.IdentifierDefine{ - .valueless = true, - .can_be_removed_if_unused = true, +pub const global_no_side_effect_function_calls_safe_for_to_string = &[_][]const string{ + + // Calling Symbol.for("foo") never throws (unless it's a rope string) + // This improves React bundle sizes slightly. + &[_]string{ "Symbol", "for" }, + + // Haven't seen a bundle size improvement from adding more to this list yet. +}; + +const pure_global_identifier_define = &defines.IdentifierDefine{ + .flags = .{ + .valueless = true, + .can_be_removed_if_unused = true, + }, .value = .{ .e_undefined = .{} }, }; const js_ast = bun.JSAst; @@ -196,215 +215,233 @@ const identifiers = struct { const inf_val = js_ast.E.Number{ .value = std.math.inf(f64) }; // Step 2. Swap in certain literal values because those can be constant folded - pub const @"undefined" = defines.IdentifierDefine{ + pub const @"undefined" = &defines.IdentifierDefine{ .value = js_ast.Expr.Data{ .e_undefined = .{} }, - .valueless = false, - .can_be_removed_if_unused = true, + .flags = .{ + .valueless = false, + .can_be_removed_if_unused = true, + }, }; - pub const NaN = defines.IdentifierDefine{ + pub const NaN = &defines.IdentifierDefine{ .value = js_ast.Expr.Data{ .e_number = nan_val }, }; - pub const Infinity = defines.IdentifierDefine{ + pub const Infinity = &defines.IdentifierDefine{ .value = js_ast.Expr.Data{ .e_number = inf_val }, }; }; -pub const pure_global_identifiers = .{ - .{ "NaN", identifiers.NaN }, - .{ "Infinity", identifiers.Infinity }, - .{ "undefined", identifiers.undefined }, +const PureGlobalIdentifierValue = enum { + NaN, + Infinity, + @"strict undefined", + other, + + pub fn value(this: PureGlobalIdentifierValue) *const defines.IdentifierDefine { + return switch (this) { + .NaN => identifiers.NaN, + .Infinity => identifiers.Infinity, + .@"strict undefined" => identifiers.undefined, + .other => pure_global_identifier_define, + }; + } +}; + +pub const pure_global_identifier_map = bun.ComptimeStringMap(PureGlobalIdentifierValue, .{ + .{ "NaN", PureGlobalIdentifierValue.NaN }, + .{ "Infinity", PureGlobalIdentifierValue.Infinity }, + .{ "undefined", PureGlobalIdentifierValue.@"strict undefined" }, // These global identifiers should exist in all JavaScript environments. This // deliberately omits "NaN", "Infinity", and "undefined" because these are // treated as automatically-inlined constants instead of identifiers. - .{ "Array", pure_global_identifier_define }, - .{ "Boolean", pure_global_identifier_define }, - .{ "Function", pure_global_identifier_define }, - .{ "Math", pure_global_identifier_define }, - .{ "Number", pure_global_identifier_define }, - .{ "Object", pure_global_identifier_define }, - .{ "RegExp", pure_global_identifier_define }, - .{ "String", pure_global_identifier_define }, + .{ "Array", PureGlobalIdentifierValue.other }, + .{ "Boolean", PureGlobalIdentifierValue.other }, + .{ "Function", PureGlobalIdentifierValue.other }, + .{ "Math", PureGlobalIdentifierValue.other }, + .{ "Number", PureGlobalIdentifierValue.other }, + .{ "Object", PureGlobalIdentifierValue.other }, + .{ "RegExp", PureGlobalIdentifierValue.other }, + .{ "String", PureGlobalIdentifierValue.other }, // Other globals present in both the browser and node (except "eval" because // it has special behavior) - .{ "AbortController", pure_global_identifier_define }, - .{ "AbortSignal", pure_global_identifier_define }, - .{ "AggregateError", pure_global_identifier_define }, - .{ "ArrayBuffer", pure_global_identifier_define }, - .{ "BigInt", pure_global_identifier_define }, - .{ "DataView", pure_global_identifier_define }, - .{ "Date", pure_global_identifier_define }, - .{ "Error", pure_global_identifier_define }, - .{ "EvalError", pure_global_identifier_define }, - .{ "Event", pure_global_identifier_define }, - .{ "EventTarget", pure_global_identifier_define }, - .{ "Float16Array", pure_global_identifier_define }, - .{ "Float32Array", pure_global_identifier_define }, - .{ "Float64Array", pure_global_identifier_define }, - .{ "Int16Array", pure_global_identifier_define }, - .{ "Int32Array", pure_global_identifier_define }, - .{ "Int8Array", pure_global_identifier_define }, - .{ "Intl", pure_global_identifier_define }, - .{ "JSON", pure_global_identifier_define }, - .{ "Map", pure_global_identifier_define }, - .{ "MessageChannel", pure_global_identifier_define }, - .{ "MessageEvent", pure_global_identifier_define }, - .{ "MessagePort", pure_global_identifier_define }, - .{ "Promise", pure_global_identifier_define }, - .{ "Proxy", pure_global_identifier_define }, - .{ "RangeError", pure_global_identifier_define }, - .{ "ReferenceError", pure_global_identifier_define }, - .{ "Reflect", pure_global_identifier_define }, - .{ "Set", pure_global_identifier_define }, - .{ "Symbol", pure_global_identifier_define }, - .{ "SyntaxError", pure_global_identifier_define }, - .{ "TextDecoder", pure_global_identifier_define }, - .{ "TextEncoder", pure_global_identifier_define }, - .{ "TypeError", pure_global_identifier_define }, - .{ "URIError", pure_global_identifier_define }, - .{ "URL", pure_global_identifier_define }, - .{ "URLSearchParams", pure_global_identifier_define }, - .{ "Uint16Array", pure_global_identifier_define }, - .{ "Uint32Array", pure_global_identifier_define }, - .{ "Uint8Array", pure_global_identifier_define }, - .{ "Uint8ClampedArray", pure_global_identifier_define }, - .{ "WeakMap", pure_global_identifier_define }, - .{ "WeakSet", pure_global_identifier_define }, - .{ "WebAssembly", pure_global_identifier_define }, - .{ "clearInterval", pure_global_identifier_define }, - .{ "clearTimeout", pure_global_identifier_define }, - .{ "console", pure_global_identifier_define }, - .{ "decodeURI", pure_global_identifier_define }, - .{ "decodeURIComponent", pure_global_identifier_define }, - .{ "encodeURI", pure_global_identifier_define }, - .{ "encodeURIComponent", pure_global_identifier_define }, - .{ "escape", pure_global_identifier_define }, - .{ "globalThis", pure_global_identifier_define }, - .{ "isFinite", pure_global_identifier_define }, - .{ "isNaN", pure_global_identifier_define }, - .{ "parseFloat", pure_global_identifier_define }, - .{ "parseInt", pure_global_identifier_define }, - .{ "queueMicrotask", pure_global_identifier_define }, - .{ "setInterval", pure_global_identifier_define }, - .{ "setTimeout", pure_global_identifier_define }, - .{ "unescape", pure_global_identifier_define }, + .{ "AbortController", PureGlobalIdentifierValue.other }, + .{ "AbortSignal", PureGlobalIdentifierValue.other }, + .{ "AggregateError", PureGlobalIdentifierValue.other }, + .{ "ArrayBuffer", PureGlobalIdentifierValue.other }, + .{ "BigInt", PureGlobalIdentifierValue.other }, + .{ "DataView", PureGlobalIdentifierValue.other }, + .{ "Date", PureGlobalIdentifierValue.other }, + .{ "Error", PureGlobalIdentifierValue.other }, + .{ "EvalError", PureGlobalIdentifierValue.other }, + .{ "Event", PureGlobalIdentifierValue.other }, + .{ "EventTarget", PureGlobalIdentifierValue.other }, + .{ "Float16Array", PureGlobalIdentifierValue.other }, + .{ "Float32Array", PureGlobalIdentifierValue.other }, + .{ "Float64Array", PureGlobalIdentifierValue.other }, + .{ "Int16Array", PureGlobalIdentifierValue.other }, + .{ "Int32Array", PureGlobalIdentifierValue.other }, + .{ "Int8Array", PureGlobalIdentifierValue.other }, + .{ "Intl", PureGlobalIdentifierValue.other }, + .{ "JSON", PureGlobalIdentifierValue.other }, + .{ "Map", PureGlobalIdentifierValue.other }, + .{ "MessageChannel", PureGlobalIdentifierValue.other }, + .{ "MessageEvent", PureGlobalIdentifierValue.other }, + .{ "MessagePort", PureGlobalIdentifierValue.other }, + .{ "Promise", PureGlobalIdentifierValue.other }, + .{ "Proxy", PureGlobalIdentifierValue.other }, + .{ "RangeError", PureGlobalIdentifierValue.other }, + .{ "ReferenceError", PureGlobalIdentifierValue.other }, + .{ "Reflect", PureGlobalIdentifierValue.other }, + .{ "Set", PureGlobalIdentifierValue.other }, + .{ "Symbol", PureGlobalIdentifierValue.other }, + .{ "SyntaxError", PureGlobalIdentifierValue.other }, + .{ "TextDecoder", PureGlobalIdentifierValue.other }, + .{ "TextEncoder", PureGlobalIdentifierValue.other }, + .{ "TypeError", PureGlobalIdentifierValue.other }, + .{ "URIError", PureGlobalIdentifierValue.other }, + .{ "URL", PureGlobalIdentifierValue.other }, + .{ "URLSearchParams", PureGlobalIdentifierValue.other }, + .{ "Uint16Array", PureGlobalIdentifierValue.other }, + .{ "Uint32Array", PureGlobalIdentifierValue.other }, + .{ "Uint8Array", PureGlobalIdentifierValue.other }, + .{ "Uint8ClampedArray", PureGlobalIdentifierValue.other }, + .{ "WeakMap", PureGlobalIdentifierValue.other }, + .{ "WeakSet", PureGlobalIdentifierValue.other }, + .{ "WebAssembly", PureGlobalIdentifierValue.other }, + .{ "clearInterval", PureGlobalIdentifierValue.other }, + .{ "clearTimeout", PureGlobalIdentifierValue.other }, + .{ "console", PureGlobalIdentifierValue.other }, + .{ "decodeURI", PureGlobalIdentifierValue.other }, + .{ "decodeURIComponent", PureGlobalIdentifierValue.other }, + .{ "encodeURI", PureGlobalIdentifierValue.other }, + .{ "encodeURIComponent", PureGlobalIdentifierValue.other }, + .{ "escape", PureGlobalIdentifierValue.other }, + .{ "globalThis", PureGlobalIdentifierValue.other }, + .{ "isFinite", PureGlobalIdentifierValue.other }, + .{ "isNaN", PureGlobalIdentifierValue.other }, + .{ "parseFloat", PureGlobalIdentifierValue.other }, + .{ "parseInt", PureGlobalIdentifierValue.other }, + .{ "queueMicrotask", PureGlobalIdentifierValue.other }, + .{ "setInterval", PureGlobalIdentifierValue.other }, + .{ "setTimeout", PureGlobalIdentifierValue.other }, + .{ "unescape", PureGlobalIdentifierValue.other }, // CSSOM APIs - .{ "CSSAnimation", pure_global_identifier_define }, - .{ "CSSFontFaceRule", pure_global_identifier_define }, - .{ "CSSImportRule", pure_global_identifier_define }, - .{ "CSSKeyframeRule", pure_global_identifier_define }, - .{ "CSSKeyframesRule", pure_global_identifier_define }, - .{ "CSSMediaRule", pure_global_identifier_define }, - .{ "CSSNamespaceRule", pure_global_identifier_define }, - .{ "CSSPageRule", pure_global_identifier_define }, - .{ "CSSRule", pure_global_identifier_define }, - .{ "CSSRuleList", pure_global_identifier_define }, - .{ "CSSStyleDeclaration", pure_global_identifier_define }, - .{ "CSSStyleRule", pure_global_identifier_define }, - .{ "CSSStyleSheet", pure_global_identifier_define }, - .{ "CSSSupportsRule", pure_global_identifier_define }, - .{ "CSSTransition", pure_global_identifier_define }, + .{ "CSSAnimation", PureGlobalIdentifierValue.other }, + .{ "CSSFontFaceRule", PureGlobalIdentifierValue.other }, + .{ "CSSImportRule", PureGlobalIdentifierValue.other }, + .{ "CSSKeyframeRule", PureGlobalIdentifierValue.other }, + .{ "CSSKeyframesRule", PureGlobalIdentifierValue.other }, + .{ "CSSMediaRule", PureGlobalIdentifierValue.other }, + .{ "CSSNamespaceRule", PureGlobalIdentifierValue.other }, + .{ "CSSPageRule", PureGlobalIdentifierValue.other }, + .{ "CSSRule", PureGlobalIdentifierValue.other }, + .{ "CSSRuleList", PureGlobalIdentifierValue.other }, + .{ "CSSStyleDeclaration", PureGlobalIdentifierValue.other }, + .{ "CSSStyleRule", PureGlobalIdentifierValue.other }, + .{ "CSSStyleSheet", PureGlobalIdentifierValue.other }, + .{ "CSSSupportsRule", PureGlobalIdentifierValue.other }, + .{ "CSSTransition", PureGlobalIdentifierValue.other }, // SVG DOM - .{ "SVGAElement", pure_global_identifier_define }, - .{ "SVGAngle", pure_global_identifier_define }, - .{ "SVGAnimateElement", pure_global_identifier_define }, - .{ "SVGAnimateMotionElement", pure_global_identifier_define }, - .{ "SVGAnimateTransformElement", pure_global_identifier_define }, - .{ "SVGAnimatedAngle", pure_global_identifier_define }, - .{ "SVGAnimatedBoolean", pure_global_identifier_define }, - .{ "SVGAnimatedEnumeration", pure_global_identifier_define }, - .{ "SVGAnimatedInteger", pure_global_identifier_define }, - .{ "SVGAnimatedLength", pure_global_identifier_define }, - .{ "SVGAnimatedLengthList", pure_global_identifier_define }, - .{ "SVGAnimatedNumber", pure_global_identifier_define }, - .{ "SVGAnimatedNumberList", pure_global_identifier_define }, - .{ "SVGAnimatedPreserveAspectRatio", pure_global_identifier_define }, - .{ "SVGAnimatedRect", pure_global_identifier_define }, - .{ "SVGAnimatedString", pure_global_identifier_define }, - .{ "SVGAnimatedTransformList", pure_global_identifier_define }, - .{ "SVGAnimationElement", pure_global_identifier_define }, - .{ "SVGCircleElement", pure_global_identifier_define }, - .{ "SVGClipPathElement", pure_global_identifier_define }, - .{ "SVGComponentTransferFunctionElement", pure_global_identifier_define }, - .{ "SVGDefsElement", pure_global_identifier_define }, - .{ "SVGDescElement", pure_global_identifier_define }, - .{ "SVGElement", pure_global_identifier_define }, - .{ "SVGEllipseElement", pure_global_identifier_define }, - .{ "SVGFEBlendElement", pure_global_identifier_define }, - .{ "SVGFEColorMatrixElement", pure_global_identifier_define }, - .{ "SVGFEComponentTransferElement", pure_global_identifier_define }, - .{ "SVGFECompositeElement", pure_global_identifier_define }, - .{ "SVGFEConvolveMatrixElement", pure_global_identifier_define }, - .{ "SVGFEDiffuseLightingElement", pure_global_identifier_define }, - .{ "SVGFEDisplacementMapElement", pure_global_identifier_define }, - .{ "SVGFEDistantLightElement", pure_global_identifier_define }, - .{ "SVGFEDropShadowElement", pure_global_identifier_define }, - .{ "SVGFEFloodElement", pure_global_identifier_define }, - .{ "SVGFEFuncAElement", pure_global_identifier_define }, - .{ "SVGFEFuncBElement", pure_global_identifier_define }, - .{ "SVGFEFuncGElement", pure_global_identifier_define }, - .{ "SVGFEFuncRElement", pure_global_identifier_define }, - .{ "SVGFEGaussianBlurElement", pure_global_identifier_define }, - .{ "SVGFEImageElement", pure_global_identifier_define }, - .{ "SVGFEMergeElement", pure_global_identifier_define }, - .{ "SVGFEMergeNodeElement", pure_global_identifier_define }, - .{ "SVGFEMorphologyElement", pure_global_identifier_define }, - .{ "SVGFEOffsetElement", pure_global_identifier_define }, - .{ "SVGFEPointLightElement", pure_global_identifier_define }, - .{ "SVGFESpecularLightingElement", pure_global_identifier_define }, - .{ "SVGFESpotLightElement", pure_global_identifier_define }, - .{ "SVGFETileElement", pure_global_identifier_define }, - .{ "SVGFETurbulenceElement", pure_global_identifier_define }, - .{ "SVGFilterElement", pure_global_identifier_define }, - .{ "SVGForeignObjectElement", pure_global_identifier_define }, - .{ "SVGGElement", pure_global_identifier_define }, - .{ "SVGGeometryElement", pure_global_identifier_define }, - .{ "SVGGradientElement", pure_global_identifier_define }, - .{ "SVGGraphicsElement", pure_global_identifier_define }, - .{ "SVGImageElement", pure_global_identifier_define }, - .{ "SVGLength", pure_global_identifier_define }, - .{ "SVGLengthList", pure_global_identifier_define }, - .{ "SVGLineElement", pure_global_identifier_define }, - .{ "SVGLinearGradientElement", pure_global_identifier_define }, - .{ "SVGMPathElement", pure_global_identifier_define }, - .{ "SVGMarkerElement", pure_global_identifier_define }, - .{ "SVGMaskElement", pure_global_identifier_define }, - .{ "SVGMatrix", pure_global_identifier_define }, - .{ "SVGMetadataElement", pure_global_identifier_define }, - .{ "SVGNumber", pure_global_identifier_define }, - .{ "SVGNumberList", pure_global_identifier_define }, - .{ "SVGPathElement", pure_global_identifier_define }, - .{ "SVGPatternElement", pure_global_identifier_define }, - .{ "SVGPoint", pure_global_identifier_define }, - .{ "SVGPointList", pure_global_identifier_define }, - .{ "SVGPolygonElement", pure_global_identifier_define }, - .{ "SVGPolylineElement", pure_global_identifier_define }, - .{ "SVGPreserveAspectRatio", pure_global_identifier_define }, - .{ "SVGRadialGradientElement", pure_global_identifier_define }, - .{ "SVGRect", pure_global_identifier_define }, - .{ "SVGRectElement", pure_global_identifier_define }, - .{ "SVGSVGElement", pure_global_identifier_define }, - .{ "SVGScriptElement", pure_global_identifier_define }, - .{ "SVGSetElement", pure_global_identifier_define }, - .{ "SVGStopElement", pure_global_identifier_define }, - .{ "SVGStringList", pure_global_identifier_define }, - .{ "SVGStyleElement", pure_global_identifier_define }, - .{ "SVGSwitchElement", pure_global_identifier_define }, - .{ "SVGSymbolElement", pure_global_identifier_define }, - .{ "SVGTSpanElement", pure_global_identifier_define }, - .{ "SVGTextContentElement", pure_global_identifier_define }, - .{ "SVGTextElement", pure_global_identifier_define }, - .{ "SVGTextPathElement", pure_global_identifier_define }, - .{ "SVGTextPositioningElement", pure_global_identifier_define }, - .{ "SVGTitleElement", pure_global_identifier_define }, - .{ "SVGTransform", pure_global_identifier_define }, - .{ "SVGTransformList", pure_global_identifier_define }, - .{ "SVGUnitTypes", pure_global_identifier_define }, - .{ "SVGUseElement", pure_global_identifier_define }, - .{ "SVGViewElement", pure_global_identifier_define }, + .{ "SVGAElement", PureGlobalIdentifierValue.other }, + .{ "SVGAngle", PureGlobalIdentifierValue.other }, + .{ "SVGAnimateElement", PureGlobalIdentifierValue.other }, + .{ "SVGAnimateMotionElement", PureGlobalIdentifierValue.other }, + .{ "SVGAnimateTransformElement", PureGlobalIdentifierValue.other }, + .{ "SVGAnimatedAngle", PureGlobalIdentifierValue.other }, + .{ "SVGAnimatedBoolean", PureGlobalIdentifierValue.other }, + .{ "SVGAnimatedEnumeration", PureGlobalIdentifierValue.other }, + .{ "SVGAnimatedInteger", PureGlobalIdentifierValue.other }, + .{ "SVGAnimatedLength", PureGlobalIdentifierValue.other }, + .{ "SVGAnimatedLengthList", PureGlobalIdentifierValue.other }, + .{ "SVGAnimatedNumber", PureGlobalIdentifierValue.other }, + .{ "SVGAnimatedNumberList", PureGlobalIdentifierValue.other }, + .{ "SVGAnimatedPreserveAspectRatio", PureGlobalIdentifierValue.other }, + .{ "SVGAnimatedRect", PureGlobalIdentifierValue.other }, + .{ "SVGAnimatedString", PureGlobalIdentifierValue.other }, + .{ "SVGAnimatedTransformList", PureGlobalIdentifierValue.other }, + .{ "SVGAnimationElement", PureGlobalIdentifierValue.other }, + .{ "SVGCircleElement", PureGlobalIdentifierValue.other }, + .{ "SVGClipPathElement", PureGlobalIdentifierValue.other }, + .{ "SVGComponentTransferFunctionElement", PureGlobalIdentifierValue.other }, + .{ "SVGDefsElement", PureGlobalIdentifierValue.other }, + .{ "SVGDescElement", PureGlobalIdentifierValue.other }, + .{ "SVGElement", PureGlobalIdentifierValue.other }, + .{ "SVGEllipseElement", PureGlobalIdentifierValue.other }, + .{ "SVGFEBlendElement", PureGlobalIdentifierValue.other }, + .{ "SVGFEColorMatrixElement", PureGlobalIdentifierValue.other }, + .{ "SVGFEComponentTransferElement", PureGlobalIdentifierValue.other }, + .{ "SVGFECompositeElement", PureGlobalIdentifierValue.other }, + .{ "SVGFEConvolveMatrixElement", PureGlobalIdentifierValue.other }, + .{ "SVGFEDiffuseLightingElement", PureGlobalIdentifierValue.other }, + .{ "SVGFEDisplacementMapElement", PureGlobalIdentifierValue.other }, + .{ "SVGFEDistantLightElement", PureGlobalIdentifierValue.other }, + .{ "SVGFEDropShadowElement", PureGlobalIdentifierValue.other }, + .{ "SVGFEFloodElement", PureGlobalIdentifierValue.other }, + .{ "SVGFEFuncAElement", PureGlobalIdentifierValue.other }, + .{ "SVGFEFuncBElement", PureGlobalIdentifierValue.other }, + .{ "SVGFEFuncGElement", PureGlobalIdentifierValue.other }, + .{ "SVGFEFuncRElement", PureGlobalIdentifierValue.other }, + .{ "SVGFEGaussianBlurElement", PureGlobalIdentifierValue.other }, + .{ "SVGFEImageElement", PureGlobalIdentifierValue.other }, + .{ "SVGFEMergeElement", PureGlobalIdentifierValue.other }, + .{ "SVGFEMergeNodeElement", PureGlobalIdentifierValue.other }, + .{ "SVGFEMorphologyElement", PureGlobalIdentifierValue.other }, + .{ "SVGFEOffsetElement", PureGlobalIdentifierValue.other }, + .{ "SVGFEPointLightElement", PureGlobalIdentifierValue.other }, + .{ "SVGFESpecularLightingElement", PureGlobalIdentifierValue.other }, + .{ "SVGFESpotLightElement", PureGlobalIdentifierValue.other }, + .{ "SVGFETileElement", PureGlobalIdentifierValue.other }, + .{ "SVGFETurbulenceElement", PureGlobalIdentifierValue.other }, + .{ "SVGFilterElement", PureGlobalIdentifierValue.other }, + .{ "SVGForeignObjectElement", PureGlobalIdentifierValue.other }, + .{ "SVGGElement", PureGlobalIdentifierValue.other }, + .{ "SVGGeometryElement", PureGlobalIdentifierValue.other }, + .{ "SVGGradientElement", PureGlobalIdentifierValue.other }, + .{ "SVGGraphicsElement", PureGlobalIdentifierValue.other }, + .{ "SVGImageElement", PureGlobalIdentifierValue.other }, + .{ "SVGLength", PureGlobalIdentifierValue.other }, + .{ "SVGLengthList", PureGlobalIdentifierValue.other }, + .{ "SVGLineElement", PureGlobalIdentifierValue.other }, + .{ "SVGLinearGradientElement", PureGlobalIdentifierValue.other }, + .{ "SVGMPathElement", PureGlobalIdentifierValue.other }, + .{ "SVGMarkerElement", PureGlobalIdentifierValue.other }, + .{ "SVGMaskElement", PureGlobalIdentifierValue.other }, + .{ "SVGMatrix", PureGlobalIdentifierValue.other }, + .{ "SVGMetadataElement", PureGlobalIdentifierValue.other }, + .{ "SVGNumber", PureGlobalIdentifierValue.other }, + .{ "SVGNumberList", PureGlobalIdentifierValue.other }, + .{ "SVGPathElement", PureGlobalIdentifierValue.other }, + .{ "SVGPatternElement", PureGlobalIdentifierValue.other }, + .{ "SVGPoint", PureGlobalIdentifierValue.other }, + .{ "SVGPointList", PureGlobalIdentifierValue.other }, + .{ "SVGPolygonElement", PureGlobalIdentifierValue.other }, + .{ "SVGPolylineElement", PureGlobalIdentifierValue.other }, + .{ "SVGPreserveAspectRatio", PureGlobalIdentifierValue.other }, + .{ "SVGRadialGradientElement", PureGlobalIdentifierValue.other }, + .{ "SVGRect", PureGlobalIdentifierValue.other }, + .{ "SVGRectElement", PureGlobalIdentifierValue.other }, + .{ "SVGSVGElement", PureGlobalIdentifierValue.other }, + .{ "SVGScriptElement", PureGlobalIdentifierValue.other }, + .{ "SVGSetElement", PureGlobalIdentifierValue.other }, + .{ "SVGStopElement", PureGlobalIdentifierValue.other }, + .{ "SVGStringList", PureGlobalIdentifierValue.other }, + .{ "SVGStyleElement", PureGlobalIdentifierValue.other }, + .{ "SVGSwitchElement", PureGlobalIdentifierValue.other }, + .{ "SVGSymbolElement", PureGlobalIdentifierValue.other }, + .{ "SVGTSpanElement", PureGlobalIdentifierValue.other }, + .{ "SVGTextContentElement", PureGlobalIdentifierValue.other }, + .{ "SVGTextElement", PureGlobalIdentifierValue.other }, + .{ "SVGTextPathElement", PureGlobalIdentifierValue.other }, + .{ "SVGTextPositioningElement", PureGlobalIdentifierValue.other }, + .{ "SVGTitleElement", PureGlobalIdentifierValue.other }, + .{ "SVGTransform", PureGlobalIdentifierValue.other }, + .{ "SVGTransformList", PureGlobalIdentifierValue.other }, + .{ "SVGUnitTypes", PureGlobalIdentifierValue.other }, + .{ "SVGUseElement", PureGlobalIdentifierValue.other }, + .{ "SVGViewElement", PureGlobalIdentifierValue.other }, // Other browser APIs // @@ -426,466 +463,464 @@ pub const pure_global_identifiers = .{ // - localStorage // - sessionStorage // - .{ "AnalyserNode", pure_global_identifier_define }, - .{ "Animation", pure_global_identifier_define }, - .{ "AnimationEffect", pure_global_identifier_define }, - .{ "AnimationEvent", pure_global_identifier_define }, - .{ "AnimationPlaybackEvent", pure_global_identifier_define }, - .{ "AnimationTimeline", pure_global_identifier_define }, - .{ "Attr", pure_global_identifier_define }, - .{ "Audio", pure_global_identifier_define }, - .{ "AudioBuffer", pure_global_identifier_define }, - .{ "AudioBufferSourceNode", pure_global_identifier_define }, - .{ "AudioDestinationNode", pure_global_identifier_define }, - .{ "AudioListener", pure_global_identifier_define }, - .{ "AudioNode", pure_global_identifier_define }, - .{ "AudioParam", pure_global_identifier_define }, - .{ "AudioProcessingEvent", pure_global_identifier_define }, - .{ "AudioScheduledSourceNode", pure_global_identifier_define }, - .{ "BarProp", pure_global_identifier_define }, - .{ "BeforeUnloadEvent", pure_global_identifier_define }, - .{ "BiquadFilterNode", pure_global_identifier_define }, - .{ "Blob", pure_global_identifier_define }, - .{ "BlobEvent", pure_global_identifier_define }, - .{ "ByteLengthQueuingStrategy", pure_global_identifier_define }, - .{ "CDATASection", pure_global_identifier_define }, - .{ "CSS", pure_global_identifier_define }, - .{ "CanvasGradient", pure_global_identifier_define }, - .{ "CanvasPattern", pure_global_identifier_define }, - .{ "CanvasRenderingContext2D", pure_global_identifier_define }, - .{ "ChannelMergerNode", pure_global_identifier_define }, - .{ "ChannelSplitterNode", pure_global_identifier_define }, - .{ "CharacterData", pure_global_identifier_define }, - .{ "ClipboardEvent", pure_global_identifier_define }, - .{ "CloseEvent", pure_global_identifier_define }, - .{ "Comment", pure_global_identifier_define }, - .{ "CompositionEvent", pure_global_identifier_define }, - .{ "ConvolverNode", pure_global_identifier_define }, - .{ "CountQueuingStrategy", pure_global_identifier_define }, - .{ "Crypto", pure_global_identifier_define }, - .{ "CustomElementRegistry", pure_global_identifier_define }, - .{ "CustomEvent", pure_global_identifier_define }, - .{ "DOMException", pure_global_identifier_define }, - .{ "DOMImplementation", pure_global_identifier_define }, - .{ "DOMMatrix", pure_global_identifier_define }, - .{ "DOMMatrixReadOnly", pure_global_identifier_define }, - .{ "DOMParser", pure_global_identifier_define }, - .{ "DOMPoint", pure_global_identifier_define }, - .{ "DOMPointReadOnly", pure_global_identifier_define }, - .{ "DOMQuad", pure_global_identifier_define }, - .{ "DOMRect", pure_global_identifier_define }, - .{ "DOMRectList", pure_global_identifier_define }, - .{ "DOMRectReadOnly", pure_global_identifier_define }, - .{ "DOMStringList", pure_global_identifier_define }, - .{ "DOMStringMap", pure_global_identifier_define }, - .{ "DOMTokenList", pure_global_identifier_define }, - .{ "DataTransfer", pure_global_identifier_define }, - .{ "DataTransferItem", pure_global_identifier_define }, - .{ "DataTransferItemList", pure_global_identifier_define }, - .{ "DelayNode", pure_global_identifier_define }, - .{ "Document", pure_global_identifier_define }, - .{ "DocumentFragment", pure_global_identifier_define }, - .{ "DocumentTimeline", pure_global_identifier_define }, - .{ "DocumentType", pure_global_identifier_define }, - .{ "DragEvent", pure_global_identifier_define }, - .{ "DynamicsCompressorNode", pure_global_identifier_define }, - .{ "Element", pure_global_identifier_define }, - .{ "ErrorEvent", pure_global_identifier_define }, - .{ "EventSource", pure_global_identifier_define }, - .{ "File", pure_global_identifier_define }, - .{ "FileList", pure_global_identifier_define }, - .{ "FileReader", pure_global_identifier_define }, - .{ "FocusEvent", pure_global_identifier_define }, - .{ "FontFace", pure_global_identifier_define }, - .{ "FormData", pure_global_identifier_define }, - .{ "GainNode", pure_global_identifier_define }, - .{ "Gamepad", pure_global_identifier_define }, - .{ "GamepadButton", pure_global_identifier_define }, - .{ "GamepadEvent", pure_global_identifier_define }, - .{ "Geolocation", pure_global_identifier_define }, - .{ "GeolocationPositionError", pure_global_identifier_define }, - .{ "HTMLAllCollection", pure_global_identifier_define }, - .{ "HTMLAnchorElement", pure_global_identifier_define }, - .{ "HTMLAreaElement", pure_global_identifier_define }, - .{ "HTMLAudioElement", pure_global_identifier_define }, - .{ "HTMLBRElement", pure_global_identifier_define }, - .{ "HTMLBaseElement", pure_global_identifier_define }, - .{ "HTMLBodyElement", pure_global_identifier_define }, - .{ "HTMLButtonElement", pure_global_identifier_define }, - .{ "HTMLCanvasElement", pure_global_identifier_define }, - .{ "HTMLCollection", pure_global_identifier_define }, - .{ "HTMLDListElement", pure_global_identifier_define }, - .{ "HTMLDataElement", pure_global_identifier_define }, - .{ "HTMLDataListElement", pure_global_identifier_define }, - .{ "HTMLDetailsElement", pure_global_identifier_define }, - .{ "HTMLDirectoryElement", pure_global_identifier_define }, - .{ "HTMLDivElement", pure_global_identifier_define }, - .{ "HTMLDocument", pure_global_identifier_define }, - .{ "HTMLElement", pure_global_identifier_define }, - .{ "HTMLEmbedElement", pure_global_identifier_define }, - .{ "HTMLFieldSetElement", pure_global_identifier_define }, - .{ "HTMLFontElement", pure_global_identifier_define }, - .{ "HTMLFormControlsCollection", pure_global_identifier_define }, - .{ "HTMLFormElement", pure_global_identifier_define }, - .{ "HTMLFrameElement", pure_global_identifier_define }, - .{ "HTMLFrameSetElement", pure_global_identifier_define }, - .{ "HTMLHRElement", pure_global_identifier_define }, - .{ "HTMLHeadElement", pure_global_identifier_define }, - .{ "HTMLHeadingElement", pure_global_identifier_define }, - .{ "HTMLHtmlElement", pure_global_identifier_define }, - .{ "HTMLIFrameElement", pure_global_identifier_define }, - .{ "HTMLImageElement", pure_global_identifier_define }, - .{ "HTMLInputElement", pure_global_identifier_define }, - .{ "HTMLLIElement", pure_global_identifier_define }, - .{ "HTMLLabelElement", pure_global_identifier_define }, - .{ "HTMLLegendElement", pure_global_identifier_define }, - .{ "HTMLLinkElement", pure_global_identifier_define }, - .{ "HTMLMapElement", pure_global_identifier_define }, - .{ "HTMLMarqueeElement", pure_global_identifier_define }, - .{ "HTMLMediaElement", pure_global_identifier_define }, - .{ "HTMLMenuElement", pure_global_identifier_define }, - .{ "HTMLMetaElement", pure_global_identifier_define }, - .{ "HTMLMeterElement", pure_global_identifier_define }, - .{ "HTMLModElement", pure_global_identifier_define }, - .{ "HTMLOListElement", pure_global_identifier_define }, - .{ "HTMLObjectElement", pure_global_identifier_define }, - .{ "HTMLOptGroupElement", pure_global_identifier_define }, - .{ "HTMLOptionElement", pure_global_identifier_define }, - .{ "HTMLOptionsCollection", pure_global_identifier_define }, - .{ "HTMLOutputElement", pure_global_identifier_define }, - .{ "HTMLParagraphElement", pure_global_identifier_define }, - .{ "HTMLParamElement", pure_global_identifier_define }, - .{ "HTMLPictureElement", pure_global_identifier_define }, - .{ "HTMLPreElement", pure_global_identifier_define }, - .{ "HTMLProgressElement", pure_global_identifier_define }, - .{ "HTMLQuoteElement", pure_global_identifier_define }, - .{ "HTMLScriptElement", pure_global_identifier_define }, - .{ "HTMLSelectElement", pure_global_identifier_define }, - .{ "HTMLSlotElement", pure_global_identifier_define }, - .{ "HTMLSourceElement", pure_global_identifier_define }, - .{ "HTMLSpanElement", pure_global_identifier_define }, - .{ "HTMLStyleElement", pure_global_identifier_define }, - .{ "HTMLTableCaptionElement", pure_global_identifier_define }, - .{ "HTMLTableCellElement", pure_global_identifier_define }, - .{ "HTMLTableColElement", pure_global_identifier_define }, - .{ "HTMLTableElement", pure_global_identifier_define }, - .{ "HTMLTableRowElement", pure_global_identifier_define }, - .{ "HTMLTableSectionElement", pure_global_identifier_define }, - .{ "HTMLTemplateElement", pure_global_identifier_define }, - .{ "HTMLTextAreaElement", pure_global_identifier_define }, - .{ "HTMLTimeElement", pure_global_identifier_define }, - .{ "HTMLTitleElement", pure_global_identifier_define }, - .{ "HTMLTrackElement", pure_global_identifier_define }, - .{ "HTMLUListElement", pure_global_identifier_define }, - .{ "HTMLUnknownElement", pure_global_identifier_define }, - .{ "HTMLVideoElement", pure_global_identifier_define }, - .{ "HashChangeEvent", pure_global_identifier_define }, - .{ "Headers", pure_global_identifier_define }, - .{ "History", pure_global_identifier_define }, - .{ "IDBCursor", pure_global_identifier_define }, - .{ "IDBCursorWithValue", pure_global_identifier_define }, - .{ "IDBDatabase", pure_global_identifier_define }, - .{ "IDBFactory", pure_global_identifier_define }, - .{ "IDBIndex", pure_global_identifier_define }, - .{ "IDBKeyRange", pure_global_identifier_define }, - .{ "IDBObjectStore", pure_global_identifier_define }, - .{ "IDBOpenDBRequest", pure_global_identifier_define }, - .{ "IDBRequest", pure_global_identifier_define }, - .{ "IDBTransaction", pure_global_identifier_define }, - .{ "IDBVersionChangeEvent", pure_global_identifier_define }, - .{ "Image", pure_global_identifier_define }, - .{ "ImageData", pure_global_identifier_define }, - .{ "InputEvent", pure_global_identifier_define }, - .{ "IntersectionObserver", pure_global_identifier_define }, - .{ "IntersectionObserverEntry", pure_global_identifier_define }, - .{ "KeyboardEvent", pure_global_identifier_define }, - .{ "KeyframeEffect", pure_global_identifier_define }, - .{ "Location", pure_global_identifier_define }, - .{ "MediaCapabilities", pure_global_identifier_define }, - .{ "MediaElementAudioSourceNode", pure_global_identifier_define }, - .{ "MediaEncryptedEvent", pure_global_identifier_define }, - .{ "MediaError", pure_global_identifier_define }, - .{ "MediaList", pure_global_identifier_define }, - .{ "MediaQueryList", pure_global_identifier_define }, - .{ "MediaQueryListEvent", pure_global_identifier_define }, - .{ "MediaRecorder", pure_global_identifier_define }, - .{ "MediaSource", pure_global_identifier_define }, - .{ "MediaStream", pure_global_identifier_define }, - .{ "MediaStreamAudioDestinationNode", pure_global_identifier_define }, - .{ "MediaStreamAudioSourceNode", pure_global_identifier_define }, - .{ "MediaStreamTrack", pure_global_identifier_define }, - .{ "MediaStreamTrackEvent", pure_global_identifier_define }, - .{ "MimeType", pure_global_identifier_define }, - .{ "MimeTypeArray", pure_global_identifier_define }, - .{ "MouseEvent", pure_global_identifier_define }, - .{ "MutationEvent", pure_global_identifier_define }, - .{ "MutationObserver", pure_global_identifier_define }, - .{ "MutationRecord", pure_global_identifier_define }, - .{ "NamedNodeMap", pure_global_identifier_define }, - .{ "Navigator", pure_global_identifier_define }, - .{ "Node", pure_global_identifier_define }, - .{ "NodeFilter", pure_global_identifier_define }, - .{ "NodeIterator", pure_global_identifier_define }, - .{ "NodeList", pure_global_identifier_define }, - .{ "Notification", pure_global_identifier_define }, - .{ "OfflineAudioCompletionEvent", pure_global_identifier_define }, - .{ "Option", pure_global_identifier_define }, - .{ "OscillatorNode", pure_global_identifier_define }, - .{ "PageTransitionEvent", pure_global_identifier_define }, - .{ "Path2D", pure_global_identifier_define }, - .{ "Performance", pure_global_identifier_define }, - .{ "PerformanceEntry", pure_global_identifier_define }, - .{ "PerformanceMark", pure_global_identifier_define }, - .{ "PerformanceMeasure", pure_global_identifier_define }, - .{ "PerformanceNavigation", pure_global_identifier_define }, - .{ "PerformanceObserver", pure_global_identifier_define }, - .{ "PerformanceObserverEntryList", pure_global_identifier_define }, - .{ "PerformanceResourceTiming", pure_global_identifier_define }, - .{ "PerformanceTiming", pure_global_identifier_define }, - .{ "PeriodicWave", pure_global_identifier_define }, - .{ "Plugin", pure_global_identifier_define }, - .{ "PluginArray", pure_global_identifier_define }, - .{ "PointerEvent", pure_global_identifier_define }, - .{ "PopStateEvent", pure_global_identifier_define }, - .{ "ProcessingInstruction", pure_global_identifier_define }, - .{ "ProgressEvent", pure_global_identifier_define }, - .{ "PromiseRejectionEvent", pure_global_identifier_define }, - .{ "RTCCertificate", pure_global_identifier_define }, - .{ "RTCDTMFSender", pure_global_identifier_define }, - .{ "RTCDTMFToneChangeEvent", pure_global_identifier_define }, - .{ "RTCDataChannel", pure_global_identifier_define }, - .{ "RTCDataChannelEvent", pure_global_identifier_define }, - .{ "RTCIceCandidate", pure_global_identifier_define }, - .{ "RTCPeerConnection", pure_global_identifier_define }, - .{ "RTCPeerConnectionIceEvent", pure_global_identifier_define }, - .{ "RTCRtpReceiver", pure_global_identifier_define }, - .{ "RTCRtpSender", pure_global_identifier_define }, - .{ "RTCRtpTransceiver", pure_global_identifier_define }, - .{ "RTCSessionDescription", pure_global_identifier_define }, - .{ "RTCStatsReport", pure_global_identifier_define }, - .{ "RTCTrackEvent", pure_global_identifier_define }, - .{ "RadioNodeList", pure_global_identifier_define }, - .{ "Range", pure_global_identifier_define }, - .{ "ReadableStream", pure_global_identifier_define }, - .{ "Request", pure_global_identifier_define }, - .{ "ResizeObserver", pure_global_identifier_define }, - .{ "ResizeObserverEntry", pure_global_identifier_define }, - .{ "Response", pure_global_identifier_define }, - .{ "Screen", pure_global_identifier_define }, - .{ "ScriptProcessorNode", pure_global_identifier_define }, - .{ "SecurityPolicyViolationEvent", pure_global_identifier_define }, - .{ "Selection", pure_global_identifier_define }, - .{ "ShadowRoot", pure_global_identifier_define }, - .{ "SourceBuffer", pure_global_identifier_define }, - .{ "SourceBufferList", pure_global_identifier_define }, - .{ "SpeechSynthesisEvent", pure_global_identifier_define }, - .{ "SpeechSynthesisUtterance", pure_global_identifier_define }, - .{ "StaticRange", pure_global_identifier_define }, - .{ "Storage", pure_global_identifier_define }, - .{ "StorageEvent", pure_global_identifier_define }, - .{ "StyleSheet", pure_global_identifier_define }, - .{ "StyleSheetList", pure_global_identifier_define }, - .{ "Text", pure_global_identifier_define }, - .{ "TextMetrics", pure_global_identifier_define }, - .{ "TextTrack", pure_global_identifier_define }, - .{ "TextTrackCue", pure_global_identifier_define }, - .{ "TextTrackCueList", pure_global_identifier_define }, - .{ "TextTrackList", pure_global_identifier_define }, - .{ "TimeRanges", pure_global_identifier_define }, - .{ "TrackEvent", pure_global_identifier_define }, - .{ "TransitionEvent", pure_global_identifier_define }, - .{ "TreeWalker", pure_global_identifier_define }, - .{ "UIEvent", pure_global_identifier_define }, - .{ "VTTCue", pure_global_identifier_define }, - .{ "ValidityState", pure_global_identifier_define }, - .{ "VisualViewport", pure_global_identifier_define }, - .{ "WaveShaperNode", pure_global_identifier_define }, - .{ "WebGLActiveInfo", pure_global_identifier_define }, - .{ "WebGLBuffer", pure_global_identifier_define }, - .{ "WebGLContextEvent", pure_global_identifier_define }, - .{ "WebGLFramebuffer", pure_global_identifier_define }, - .{ "WebGLProgram", pure_global_identifier_define }, - .{ "WebGLQuery", pure_global_identifier_define }, - .{ "WebGLRenderbuffer", pure_global_identifier_define }, - .{ "WebGLRenderingContext", pure_global_identifier_define }, - .{ "WebGLSampler", pure_global_identifier_define }, - .{ "WebGLShader", pure_global_identifier_define }, - .{ "WebGLShaderPrecisionFormat", pure_global_identifier_define }, - .{ "WebGLSync", pure_global_identifier_define }, - .{ "WebGLTexture", pure_global_identifier_define }, - .{ "WebGLUniformLocation", pure_global_identifier_define }, - .{ "WebKitCSSMatrix", pure_global_identifier_define }, - .{ "WebSocket", pure_global_identifier_define }, - .{ "WheelEvent", pure_global_identifier_define }, - .{ "Window", pure_global_identifier_define }, - .{ "Worker", pure_global_identifier_define }, - .{ "XMLDocument", pure_global_identifier_define }, - .{ "XMLHttpRequest", pure_global_identifier_define }, - .{ "XMLHttpRequestEventTarget", pure_global_identifier_define }, - .{ "XMLHttpRequestUpload", pure_global_identifier_define }, - .{ "XMLSerializer", pure_global_identifier_define }, - .{ "XPathEvaluator", pure_global_identifier_define }, - .{ "XPathExpression", pure_global_identifier_define }, - .{ "XPathResult", pure_global_identifier_define }, - .{ "XSLTProcessor", pure_global_identifier_define }, - .{ "alert", pure_global_identifier_define }, - .{ "atob", pure_global_identifier_define }, - .{ "blur", pure_global_identifier_define }, - .{ "btoa", pure_global_identifier_define }, - .{ "cancelAnimationFrame", pure_global_identifier_define }, - .{ "captureEvents", pure_global_identifier_define }, - .{ "close", pure_global_identifier_define }, - .{ "closed", pure_global_identifier_define }, - .{ "confirm", pure_global_identifier_define }, - .{ "customElements", pure_global_identifier_define }, - .{ "devicePixelRatio", pure_global_identifier_define }, - .{ "document", pure_global_identifier_define }, - .{ "event", pure_global_identifier_define }, - .{ "fetch", pure_global_identifier_define }, - .{ "find", pure_global_identifier_define }, - .{ "focus", pure_global_identifier_define }, - .{ "frameElement", pure_global_identifier_define }, - .{ "frames", pure_global_identifier_define }, - .{ "getComputedStyle", pure_global_identifier_define }, - .{ "getSelection", pure_global_identifier_define }, - .{ "history", pure_global_identifier_define }, - .{ "indexedDB", pure_global_identifier_define }, - .{ "isSecureContext", pure_global_identifier_define }, - .{ "length", pure_global_identifier_define }, - .{ "location", pure_global_identifier_define }, - .{ "locationbar", pure_global_identifier_define }, - .{ "matchMedia", pure_global_identifier_define }, - .{ "menubar", pure_global_identifier_define }, - .{ "moveBy", pure_global_identifier_define }, - .{ "moveTo", pure_global_identifier_define }, - .{ "name", pure_global_identifier_define }, - .{ "navigator", pure_global_identifier_define }, - .{ "onabort", pure_global_identifier_define }, - .{ "onafterprint", pure_global_identifier_define }, - .{ "onanimationend", pure_global_identifier_define }, - .{ "onanimationiteration", pure_global_identifier_define }, - .{ "onanimationstart", pure_global_identifier_define }, - .{ "onbeforeprint", pure_global_identifier_define }, - .{ "onbeforeunload", pure_global_identifier_define }, - .{ "onblur", pure_global_identifier_define }, - .{ "oncanplay", pure_global_identifier_define }, - .{ "oncanplaythrough", pure_global_identifier_define }, - .{ "onchange", pure_global_identifier_define }, - .{ "onclick", pure_global_identifier_define }, - .{ "oncontextmenu", pure_global_identifier_define }, - .{ "oncuechange", pure_global_identifier_define }, - .{ "ondblclick", pure_global_identifier_define }, - .{ "ondrag", pure_global_identifier_define }, - .{ "ondragend", pure_global_identifier_define }, - .{ "ondragenter", pure_global_identifier_define }, - .{ "ondragleave", pure_global_identifier_define }, - .{ "ondragover", pure_global_identifier_define }, - .{ "ondragstart", pure_global_identifier_define }, - .{ "ondrop", pure_global_identifier_define }, - .{ "ondurationchange", pure_global_identifier_define }, - .{ "onemptied", pure_global_identifier_define }, - .{ "onended", pure_global_identifier_define }, - .{ "onerror", pure_global_identifier_define }, - .{ "onfocus", pure_global_identifier_define }, - .{ "ongotpointercapture", pure_global_identifier_define }, - .{ "onhashchange", pure_global_identifier_define }, - .{ "oninput", pure_global_identifier_define }, - .{ "oninvalid", pure_global_identifier_define }, - .{ "onkeydown", pure_global_identifier_define }, - .{ "onkeypress", pure_global_identifier_define }, - .{ "onkeyup", pure_global_identifier_define }, - .{ "onlanguagechange", pure_global_identifier_define }, - .{ "onload", pure_global_identifier_define }, - .{ "onloadeddata", pure_global_identifier_define }, - .{ "onloadedmetadata", pure_global_identifier_define }, - .{ "onloadstart", pure_global_identifier_define }, - .{ "onlostpointercapture", pure_global_identifier_define }, - .{ "onmessage", pure_global_identifier_define }, - .{ "onmousedown", pure_global_identifier_define }, - .{ "onmouseenter", pure_global_identifier_define }, - .{ "onmouseleave", pure_global_identifier_define }, - .{ "onmousemove", pure_global_identifier_define }, - .{ "onmouseout", pure_global_identifier_define }, - .{ "onmouseover", pure_global_identifier_define }, - .{ "onmouseup", pure_global_identifier_define }, - .{ "onoffline", pure_global_identifier_define }, - .{ "ononline", pure_global_identifier_define }, - .{ "onpagehide", pure_global_identifier_define }, - .{ "onpageshow", pure_global_identifier_define }, - .{ "onpause", pure_global_identifier_define }, - .{ "onplay", pure_global_identifier_define }, - .{ "onplaying", pure_global_identifier_define }, - .{ "onpointercancel", pure_global_identifier_define }, - .{ "onpointerdown", pure_global_identifier_define }, - .{ "onpointerenter", pure_global_identifier_define }, - .{ "onpointerleave", pure_global_identifier_define }, - .{ "onpointermove", pure_global_identifier_define }, - .{ "onpointerout", pure_global_identifier_define }, - .{ "onpointerover", pure_global_identifier_define }, - .{ "onpointerup", pure_global_identifier_define }, - .{ "onpopstate", pure_global_identifier_define }, - .{ "onprogress", pure_global_identifier_define }, - .{ "onratechange", pure_global_identifier_define }, - .{ "onrejectionhandled", pure_global_identifier_define }, - .{ "onreset", pure_global_identifier_define }, - .{ "onresize", pure_global_identifier_define }, - .{ "onscroll", pure_global_identifier_define }, - .{ "onseeked", pure_global_identifier_define }, - .{ "onseeking", pure_global_identifier_define }, - .{ "onselect", pure_global_identifier_define }, - .{ "onstalled", pure_global_identifier_define }, - .{ "onstorage", pure_global_identifier_define }, - .{ "onsubmit", pure_global_identifier_define }, - .{ "onsuspend", pure_global_identifier_define }, - .{ "ontimeupdate", pure_global_identifier_define }, - .{ "ontoggle", pure_global_identifier_define }, - .{ "ontransitioncancel", pure_global_identifier_define }, - .{ "ontransitionend", pure_global_identifier_define }, - .{ "ontransitionrun", pure_global_identifier_define }, - .{ "ontransitionstart", pure_global_identifier_define }, - .{ "onunhandledrejection", pure_global_identifier_define }, - .{ "onunload", pure_global_identifier_define }, - .{ "onvolumechange", pure_global_identifier_define }, - .{ "onwaiting", pure_global_identifier_define }, - .{ "onwebkitanimationend", pure_global_identifier_define }, - .{ "onwebkitanimationiteration", pure_global_identifier_define }, - .{ "onwebkitanimationstart", pure_global_identifier_define }, - .{ "onwebkittransitionend", pure_global_identifier_define }, - .{ "onwheel", pure_global_identifier_define }, - .{ "open", pure_global_identifier_define }, - .{ "opener", pure_global_identifier_define }, - .{ "origin", pure_global_identifier_define }, - .{ "outerHeight", pure_global_identifier_define }, - .{ "outerWidth", pure_global_identifier_define }, - .{ "parent", pure_global_identifier_define }, - .{ "performance", pure_global_identifier_define }, - .{ "personalbar", pure_global_identifier_define }, - .{ "postMessage", pure_global_identifier_define }, - .{ "print", pure_global_identifier_define }, - .{ "prompt", pure_global_identifier_define }, - .{ "releaseEvents", pure_global_identifier_define }, - .{ "requestAnimationFrame", pure_global_identifier_define }, - .{ "resizeBy", pure_global_identifier_define }, - .{ "resizeTo", pure_global_identifier_define }, - .{ "screen", pure_global_identifier_define }, - .{ "screenLeft", pure_global_identifier_define }, - .{ "screenTop", pure_global_identifier_define }, - .{ "screenX", pure_global_identifier_define }, - .{ "screenY", pure_global_identifier_define }, - .{ "scroll", pure_global_identifier_define }, - .{ "scrollBy", pure_global_identifier_define }, - .{ "scrollTo", pure_global_identifier_define }, - .{ "scrollbars", pure_global_identifier_define }, - .{ "self", pure_global_identifier_define }, - .{ "speechSynthesis", pure_global_identifier_define }, - .{ "status", pure_global_identifier_define }, - .{ "statusbar", pure_global_identifier_define }, - .{ "stop", pure_global_identifier_define }, - .{ "toolbar", pure_global_identifier_define }, - .{ "top", pure_global_identifier_define }, - .{ "webkitURL", pure_global_identifier_define }, - .{ "window", pure_global_identifier_define }, - .{ "crypto", pure_global_identifier_define }, -}; - -pub const pure_global_identifier_map = bun.ComptimeStringMap(defines.IdentifierDefine, pure_global_identifiers); + .{ "AnalyserNode", PureGlobalIdentifierValue.other }, + .{ "Animation", PureGlobalIdentifierValue.other }, + .{ "AnimationEffect", PureGlobalIdentifierValue.other }, + .{ "AnimationEvent", PureGlobalIdentifierValue.other }, + .{ "AnimationPlaybackEvent", PureGlobalIdentifierValue.other }, + .{ "AnimationTimeline", PureGlobalIdentifierValue.other }, + .{ "Attr", PureGlobalIdentifierValue.other }, + .{ "Audio", PureGlobalIdentifierValue.other }, + .{ "AudioBuffer", PureGlobalIdentifierValue.other }, + .{ "AudioBufferSourceNode", PureGlobalIdentifierValue.other }, + .{ "AudioDestinationNode", PureGlobalIdentifierValue.other }, + .{ "AudioListener", PureGlobalIdentifierValue.other }, + .{ "AudioNode", PureGlobalIdentifierValue.other }, + .{ "AudioParam", PureGlobalIdentifierValue.other }, + .{ "AudioProcessingEvent", PureGlobalIdentifierValue.other }, + .{ "AudioScheduledSourceNode", PureGlobalIdentifierValue.other }, + .{ "BarProp", PureGlobalIdentifierValue.other }, + .{ "BeforeUnloadEvent", PureGlobalIdentifierValue.other }, + .{ "BiquadFilterNode", PureGlobalIdentifierValue.other }, + .{ "Blob", PureGlobalIdentifierValue.other }, + .{ "BlobEvent", PureGlobalIdentifierValue.other }, + .{ "ByteLengthQueuingStrategy", PureGlobalIdentifierValue.other }, + .{ "CDATASection", PureGlobalIdentifierValue.other }, + .{ "CSS", PureGlobalIdentifierValue.other }, + .{ "CanvasGradient", PureGlobalIdentifierValue.other }, + .{ "CanvasPattern", PureGlobalIdentifierValue.other }, + .{ "CanvasRenderingContext2D", PureGlobalIdentifierValue.other }, + .{ "ChannelMergerNode", PureGlobalIdentifierValue.other }, + .{ "ChannelSplitterNode", PureGlobalIdentifierValue.other }, + .{ "CharacterData", PureGlobalIdentifierValue.other }, + .{ "ClipboardEvent", PureGlobalIdentifierValue.other }, + .{ "CloseEvent", PureGlobalIdentifierValue.other }, + .{ "Comment", PureGlobalIdentifierValue.other }, + .{ "CompositionEvent", PureGlobalIdentifierValue.other }, + .{ "ConvolverNode", PureGlobalIdentifierValue.other }, + .{ "CountQueuingStrategy", PureGlobalIdentifierValue.other }, + .{ "Crypto", PureGlobalIdentifierValue.other }, + .{ "CustomElementRegistry", PureGlobalIdentifierValue.other }, + .{ "CustomEvent", PureGlobalIdentifierValue.other }, + .{ "DOMException", PureGlobalIdentifierValue.other }, + .{ "DOMImplementation", PureGlobalIdentifierValue.other }, + .{ "DOMMatrix", PureGlobalIdentifierValue.other }, + .{ "DOMMatrixReadOnly", PureGlobalIdentifierValue.other }, + .{ "DOMParser", PureGlobalIdentifierValue.other }, + .{ "DOMPoint", PureGlobalIdentifierValue.other }, + .{ "DOMPointReadOnly", PureGlobalIdentifierValue.other }, + .{ "DOMQuad", PureGlobalIdentifierValue.other }, + .{ "DOMRect", PureGlobalIdentifierValue.other }, + .{ "DOMRectList", PureGlobalIdentifierValue.other }, + .{ "DOMRectReadOnly", PureGlobalIdentifierValue.other }, + .{ "DOMStringList", PureGlobalIdentifierValue.other }, + .{ "DOMStringMap", PureGlobalIdentifierValue.other }, + .{ "DOMTokenList", PureGlobalIdentifierValue.other }, + .{ "DataTransfer", PureGlobalIdentifierValue.other }, + .{ "DataTransferItem", PureGlobalIdentifierValue.other }, + .{ "DataTransferItemList", PureGlobalIdentifierValue.other }, + .{ "DelayNode", PureGlobalIdentifierValue.other }, + .{ "Document", PureGlobalIdentifierValue.other }, + .{ "DocumentFragment", PureGlobalIdentifierValue.other }, + .{ "DocumentTimeline", PureGlobalIdentifierValue.other }, + .{ "DocumentType", PureGlobalIdentifierValue.other }, + .{ "DragEvent", PureGlobalIdentifierValue.other }, + .{ "DynamicsCompressorNode", PureGlobalIdentifierValue.other }, + .{ "Element", PureGlobalIdentifierValue.other }, + .{ "ErrorEvent", PureGlobalIdentifierValue.other }, + .{ "EventSource", PureGlobalIdentifierValue.other }, + .{ "File", PureGlobalIdentifierValue.other }, + .{ "FileList", PureGlobalIdentifierValue.other }, + .{ "FileReader", PureGlobalIdentifierValue.other }, + .{ "FocusEvent", PureGlobalIdentifierValue.other }, + .{ "FontFace", PureGlobalIdentifierValue.other }, + .{ "FormData", PureGlobalIdentifierValue.other }, + .{ "GainNode", PureGlobalIdentifierValue.other }, + .{ "Gamepad", PureGlobalIdentifierValue.other }, + .{ "GamepadButton", PureGlobalIdentifierValue.other }, + .{ "GamepadEvent", PureGlobalIdentifierValue.other }, + .{ "Geolocation", PureGlobalIdentifierValue.other }, + .{ "GeolocationPositionError", PureGlobalIdentifierValue.other }, + .{ "HTMLAllCollection", PureGlobalIdentifierValue.other }, + .{ "HTMLAnchorElement", PureGlobalIdentifierValue.other }, + .{ "HTMLAreaElement", PureGlobalIdentifierValue.other }, + .{ "HTMLAudioElement", PureGlobalIdentifierValue.other }, + .{ "HTMLBRElement", PureGlobalIdentifierValue.other }, + .{ "HTMLBaseElement", PureGlobalIdentifierValue.other }, + .{ "HTMLBodyElement", PureGlobalIdentifierValue.other }, + .{ "HTMLButtonElement", PureGlobalIdentifierValue.other }, + .{ "HTMLCanvasElement", PureGlobalIdentifierValue.other }, + .{ "HTMLCollection", PureGlobalIdentifierValue.other }, + .{ "HTMLDListElement", PureGlobalIdentifierValue.other }, + .{ "HTMLDataElement", PureGlobalIdentifierValue.other }, + .{ "HTMLDataListElement", PureGlobalIdentifierValue.other }, + .{ "HTMLDetailsElement", PureGlobalIdentifierValue.other }, + .{ "HTMLDirectoryElement", PureGlobalIdentifierValue.other }, + .{ "HTMLDivElement", PureGlobalIdentifierValue.other }, + .{ "HTMLDocument", PureGlobalIdentifierValue.other }, + .{ "HTMLElement", PureGlobalIdentifierValue.other }, + .{ "HTMLEmbedElement", PureGlobalIdentifierValue.other }, + .{ "HTMLFieldSetElement", PureGlobalIdentifierValue.other }, + .{ "HTMLFontElement", PureGlobalIdentifierValue.other }, + .{ "HTMLFormControlsCollection", PureGlobalIdentifierValue.other }, + .{ "HTMLFormElement", PureGlobalIdentifierValue.other }, + .{ "HTMLFrameElement", PureGlobalIdentifierValue.other }, + .{ "HTMLFrameSetElement", PureGlobalIdentifierValue.other }, + .{ "HTMLHRElement", PureGlobalIdentifierValue.other }, + .{ "HTMLHeadElement", PureGlobalIdentifierValue.other }, + .{ "HTMLHeadingElement", PureGlobalIdentifierValue.other }, + .{ "HTMLHtmlElement", PureGlobalIdentifierValue.other }, + .{ "HTMLIFrameElement", PureGlobalIdentifierValue.other }, + .{ "HTMLImageElement", PureGlobalIdentifierValue.other }, + .{ "HTMLInputElement", PureGlobalIdentifierValue.other }, + .{ "HTMLLIElement", PureGlobalIdentifierValue.other }, + .{ "HTMLLabelElement", PureGlobalIdentifierValue.other }, + .{ "HTMLLegendElement", PureGlobalIdentifierValue.other }, + .{ "HTMLLinkElement", PureGlobalIdentifierValue.other }, + .{ "HTMLMapElement", PureGlobalIdentifierValue.other }, + .{ "HTMLMarqueeElement", PureGlobalIdentifierValue.other }, + .{ "HTMLMediaElement", PureGlobalIdentifierValue.other }, + .{ "HTMLMenuElement", PureGlobalIdentifierValue.other }, + .{ "HTMLMetaElement", PureGlobalIdentifierValue.other }, + .{ "HTMLMeterElement", PureGlobalIdentifierValue.other }, + .{ "HTMLModElement", PureGlobalIdentifierValue.other }, + .{ "HTMLOListElement", PureGlobalIdentifierValue.other }, + .{ "HTMLObjectElement", PureGlobalIdentifierValue.other }, + .{ "HTMLOptGroupElement", PureGlobalIdentifierValue.other }, + .{ "HTMLOptionElement", PureGlobalIdentifierValue.other }, + .{ "HTMLOptionsCollection", PureGlobalIdentifierValue.other }, + .{ "HTMLOutputElement", PureGlobalIdentifierValue.other }, + .{ "HTMLParagraphElement", PureGlobalIdentifierValue.other }, + .{ "HTMLParamElement", PureGlobalIdentifierValue.other }, + .{ "HTMLPictureElement", PureGlobalIdentifierValue.other }, + .{ "HTMLPreElement", PureGlobalIdentifierValue.other }, + .{ "HTMLProgressElement", PureGlobalIdentifierValue.other }, + .{ "HTMLQuoteElement", PureGlobalIdentifierValue.other }, + .{ "HTMLScriptElement", PureGlobalIdentifierValue.other }, + .{ "HTMLSelectElement", PureGlobalIdentifierValue.other }, + .{ "HTMLSlotElement", PureGlobalIdentifierValue.other }, + .{ "HTMLSourceElement", PureGlobalIdentifierValue.other }, + .{ "HTMLSpanElement", PureGlobalIdentifierValue.other }, + .{ "HTMLStyleElement", PureGlobalIdentifierValue.other }, + .{ "HTMLTableCaptionElement", PureGlobalIdentifierValue.other }, + .{ "HTMLTableCellElement", PureGlobalIdentifierValue.other }, + .{ "HTMLTableColElement", PureGlobalIdentifierValue.other }, + .{ "HTMLTableElement", PureGlobalIdentifierValue.other }, + .{ "HTMLTableRowElement", PureGlobalIdentifierValue.other }, + .{ "HTMLTableSectionElement", PureGlobalIdentifierValue.other }, + .{ "HTMLTemplateElement", PureGlobalIdentifierValue.other }, + .{ "HTMLTextAreaElement", PureGlobalIdentifierValue.other }, + .{ "HTMLTimeElement", PureGlobalIdentifierValue.other }, + .{ "HTMLTitleElement", PureGlobalIdentifierValue.other }, + .{ "HTMLTrackElement", PureGlobalIdentifierValue.other }, + .{ "HTMLUListElement", PureGlobalIdentifierValue.other }, + .{ "HTMLUnknownElement", PureGlobalIdentifierValue.other }, + .{ "HTMLVideoElement", PureGlobalIdentifierValue.other }, + .{ "HashChangeEvent", PureGlobalIdentifierValue.other }, + .{ "Headers", PureGlobalIdentifierValue.other }, + .{ "History", PureGlobalIdentifierValue.other }, + .{ "IDBCursor", PureGlobalIdentifierValue.other }, + .{ "IDBCursorWithValue", PureGlobalIdentifierValue.other }, + .{ "IDBDatabase", PureGlobalIdentifierValue.other }, + .{ "IDBFactory", PureGlobalIdentifierValue.other }, + .{ "IDBIndex", PureGlobalIdentifierValue.other }, + .{ "IDBKeyRange", PureGlobalIdentifierValue.other }, + .{ "IDBObjectStore", PureGlobalIdentifierValue.other }, + .{ "IDBOpenDBRequest", PureGlobalIdentifierValue.other }, + .{ "IDBRequest", PureGlobalIdentifierValue.other }, + .{ "IDBTransaction", PureGlobalIdentifierValue.other }, + .{ "IDBVersionChangeEvent", PureGlobalIdentifierValue.other }, + .{ "Image", PureGlobalIdentifierValue.other }, + .{ "ImageData", PureGlobalIdentifierValue.other }, + .{ "InputEvent", PureGlobalIdentifierValue.other }, + .{ "IntersectionObserver", PureGlobalIdentifierValue.other }, + .{ "IntersectionObserverEntry", PureGlobalIdentifierValue.other }, + .{ "KeyboardEvent", PureGlobalIdentifierValue.other }, + .{ "KeyframeEffect", PureGlobalIdentifierValue.other }, + .{ "Location", PureGlobalIdentifierValue.other }, + .{ "MediaCapabilities", PureGlobalIdentifierValue.other }, + .{ "MediaElementAudioSourceNode", PureGlobalIdentifierValue.other }, + .{ "MediaEncryptedEvent", PureGlobalIdentifierValue.other }, + .{ "MediaError", PureGlobalIdentifierValue.other }, + .{ "MediaList", PureGlobalIdentifierValue.other }, + .{ "MediaQueryList", PureGlobalIdentifierValue.other }, + .{ "MediaQueryListEvent", PureGlobalIdentifierValue.other }, + .{ "MediaRecorder", PureGlobalIdentifierValue.other }, + .{ "MediaSource", PureGlobalIdentifierValue.other }, + .{ "MediaStream", PureGlobalIdentifierValue.other }, + .{ "MediaStreamAudioDestinationNode", PureGlobalIdentifierValue.other }, + .{ "MediaStreamAudioSourceNode", PureGlobalIdentifierValue.other }, + .{ "MediaStreamTrack", PureGlobalIdentifierValue.other }, + .{ "MediaStreamTrackEvent", PureGlobalIdentifierValue.other }, + .{ "MimeType", PureGlobalIdentifierValue.other }, + .{ "MimeTypeArray", PureGlobalIdentifierValue.other }, + .{ "MouseEvent", PureGlobalIdentifierValue.other }, + .{ "MutationEvent", PureGlobalIdentifierValue.other }, + .{ "MutationObserver", PureGlobalIdentifierValue.other }, + .{ "MutationRecord", PureGlobalIdentifierValue.other }, + .{ "NamedNodeMap", PureGlobalIdentifierValue.other }, + .{ "Navigator", PureGlobalIdentifierValue.other }, + .{ "Node", PureGlobalIdentifierValue.other }, + .{ "NodeFilter", PureGlobalIdentifierValue.other }, + .{ "NodeIterator", PureGlobalIdentifierValue.other }, + .{ "NodeList", PureGlobalIdentifierValue.other }, + .{ "Notification", PureGlobalIdentifierValue.other }, + .{ "OfflineAudioCompletionEvent", PureGlobalIdentifierValue.other }, + .{ "Option", PureGlobalIdentifierValue.other }, + .{ "OscillatorNode", PureGlobalIdentifierValue.other }, + .{ "PageTransitionEvent", PureGlobalIdentifierValue.other }, + .{ "Path2D", PureGlobalIdentifierValue.other }, + .{ "Performance", PureGlobalIdentifierValue.other }, + .{ "PerformanceEntry", PureGlobalIdentifierValue.other }, + .{ "PerformanceMark", PureGlobalIdentifierValue.other }, + .{ "PerformanceMeasure", PureGlobalIdentifierValue.other }, + .{ "PerformanceNavigation", PureGlobalIdentifierValue.other }, + .{ "PerformanceObserver", PureGlobalIdentifierValue.other }, + .{ "PerformanceObserverEntryList", PureGlobalIdentifierValue.other }, + .{ "PerformanceResourceTiming", PureGlobalIdentifierValue.other }, + .{ "PerformanceTiming", PureGlobalIdentifierValue.other }, + .{ "PeriodicWave", PureGlobalIdentifierValue.other }, + .{ "Plugin", PureGlobalIdentifierValue.other }, + .{ "PluginArray", PureGlobalIdentifierValue.other }, + .{ "PointerEvent", PureGlobalIdentifierValue.other }, + .{ "PopStateEvent", PureGlobalIdentifierValue.other }, + .{ "ProcessingInstruction", PureGlobalIdentifierValue.other }, + .{ "ProgressEvent", PureGlobalIdentifierValue.other }, + .{ "PromiseRejectionEvent", PureGlobalIdentifierValue.other }, + .{ "RTCCertificate", PureGlobalIdentifierValue.other }, + .{ "RTCDTMFSender", PureGlobalIdentifierValue.other }, + .{ "RTCDTMFToneChangeEvent", PureGlobalIdentifierValue.other }, + .{ "RTCDataChannel", PureGlobalIdentifierValue.other }, + .{ "RTCDataChannelEvent", PureGlobalIdentifierValue.other }, + .{ "RTCIceCandidate", PureGlobalIdentifierValue.other }, + .{ "RTCPeerConnection", PureGlobalIdentifierValue.other }, + .{ "RTCPeerConnectionIceEvent", PureGlobalIdentifierValue.other }, + .{ "RTCRtpReceiver", PureGlobalIdentifierValue.other }, + .{ "RTCRtpSender", PureGlobalIdentifierValue.other }, + .{ "RTCRtpTransceiver", PureGlobalIdentifierValue.other }, + .{ "RTCSessionDescription", PureGlobalIdentifierValue.other }, + .{ "RTCStatsReport", PureGlobalIdentifierValue.other }, + .{ "RTCTrackEvent", PureGlobalIdentifierValue.other }, + .{ "RadioNodeList", PureGlobalIdentifierValue.other }, + .{ "Range", PureGlobalIdentifierValue.other }, + .{ "ReadableStream", PureGlobalIdentifierValue.other }, + .{ "Request", PureGlobalIdentifierValue.other }, + .{ "ResizeObserver", PureGlobalIdentifierValue.other }, + .{ "ResizeObserverEntry", PureGlobalIdentifierValue.other }, + .{ "Response", PureGlobalIdentifierValue.other }, + .{ "Screen", PureGlobalIdentifierValue.other }, + .{ "ScriptProcessorNode", PureGlobalIdentifierValue.other }, + .{ "SecurityPolicyViolationEvent", PureGlobalIdentifierValue.other }, + .{ "Selection", PureGlobalIdentifierValue.other }, + .{ "ShadowRoot", PureGlobalIdentifierValue.other }, + .{ "SourceBuffer", PureGlobalIdentifierValue.other }, + .{ "SourceBufferList", PureGlobalIdentifierValue.other }, + .{ "SpeechSynthesisEvent", PureGlobalIdentifierValue.other }, + .{ "SpeechSynthesisUtterance", PureGlobalIdentifierValue.other }, + .{ "StaticRange", PureGlobalIdentifierValue.other }, + .{ "Storage", PureGlobalIdentifierValue.other }, + .{ "StorageEvent", PureGlobalIdentifierValue.other }, + .{ "StyleSheet", PureGlobalIdentifierValue.other }, + .{ "StyleSheetList", PureGlobalIdentifierValue.other }, + .{ "Text", PureGlobalIdentifierValue.other }, + .{ "TextMetrics", PureGlobalIdentifierValue.other }, + .{ "TextTrack", PureGlobalIdentifierValue.other }, + .{ "TextTrackCue", PureGlobalIdentifierValue.other }, + .{ "TextTrackCueList", PureGlobalIdentifierValue.other }, + .{ "TextTrackList", PureGlobalIdentifierValue.other }, + .{ "TimeRanges", PureGlobalIdentifierValue.other }, + .{ "TrackEvent", PureGlobalIdentifierValue.other }, + .{ "TransitionEvent", PureGlobalIdentifierValue.other }, + .{ "TreeWalker", PureGlobalIdentifierValue.other }, + .{ "UIEvent", PureGlobalIdentifierValue.other }, + .{ "VTTCue", PureGlobalIdentifierValue.other }, + .{ "ValidityState", PureGlobalIdentifierValue.other }, + .{ "VisualViewport", PureGlobalIdentifierValue.other }, + .{ "WaveShaperNode", PureGlobalIdentifierValue.other }, + .{ "WebGLActiveInfo", PureGlobalIdentifierValue.other }, + .{ "WebGLBuffer", PureGlobalIdentifierValue.other }, + .{ "WebGLContextEvent", PureGlobalIdentifierValue.other }, + .{ "WebGLFramebuffer", PureGlobalIdentifierValue.other }, + .{ "WebGLProgram", PureGlobalIdentifierValue.other }, + .{ "WebGLQuery", PureGlobalIdentifierValue.other }, + .{ "WebGLRenderbuffer", PureGlobalIdentifierValue.other }, + .{ "WebGLRenderingContext", PureGlobalIdentifierValue.other }, + .{ "WebGLSampler", PureGlobalIdentifierValue.other }, + .{ "WebGLShader", PureGlobalIdentifierValue.other }, + .{ "WebGLShaderPrecisionFormat", PureGlobalIdentifierValue.other }, + .{ "WebGLSync", PureGlobalIdentifierValue.other }, + .{ "WebGLTexture", PureGlobalIdentifierValue.other }, + .{ "WebGLUniformLocation", PureGlobalIdentifierValue.other }, + .{ "WebKitCSSMatrix", PureGlobalIdentifierValue.other }, + .{ "WebSocket", PureGlobalIdentifierValue.other }, + .{ "WheelEvent", PureGlobalIdentifierValue.other }, + .{ "Window", PureGlobalIdentifierValue.other }, + .{ "Worker", PureGlobalIdentifierValue.other }, + .{ "XMLDocument", PureGlobalIdentifierValue.other }, + .{ "XMLHttpRequest", PureGlobalIdentifierValue.other }, + .{ "XMLHttpRequestEventTarget", PureGlobalIdentifierValue.other }, + .{ "XMLHttpRequestUpload", PureGlobalIdentifierValue.other }, + .{ "XMLSerializer", PureGlobalIdentifierValue.other }, + .{ "XPathEvaluator", PureGlobalIdentifierValue.other }, + .{ "XPathExpression", PureGlobalIdentifierValue.other }, + .{ "XPathResult", PureGlobalIdentifierValue.other }, + .{ "XSLTProcessor", PureGlobalIdentifierValue.other }, + .{ "alert", PureGlobalIdentifierValue.other }, + .{ "atob", PureGlobalIdentifierValue.other }, + .{ "blur", PureGlobalIdentifierValue.other }, + .{ "btoa", PureGlobalIdentifierValue.other }, + .{ "cancelAnimationFrame", PureGlobalIdentifierValue.other }, + .{ "captureEvents", PureGlobalIdentifierValue.other }, + .{ "close", PureGlobalIdentifierValue.other }, + .{ "closed", PureGlobalIdentifierValue.other }, + .{ "confirm", PureGlobalIdentifierValue.other }, + .{ "customElements", PureGlobalIdentifierValue.other }, + .{ "devicePixelRatio", PureGlobalIdentifierValue.other }, + .{ "document", PureGlobalIdentifierValue.other }, + .{ "event", PureGlobalIdentifierValue.other }, + .{ "fetch", PureGlobalIdentifierValue.other }, + .{ "find", PureGlobalIdentifierValue.other }, + .{ "focus", PureGlobalIdentifierValue.other }, + .{ "frameElement", PureGlobalIdentifierValue.other }, + .{ "frames", PureGlobalIdentifierValue.other }, + .{ "getComputedStyle", PureGlobalIdentifierValue.other }, + .{ "getSelection", PureGlobalIdentifierValue.other }, + .{ "history", PureGlobalIdentifierValue.other }, + .{ "indexedDB", PureGlobalIdentifierValue.other }, + .{ "isSecureContext", PureGlobalIdentifierValue.other }, + .{ "length", PureGlobalIdentifierValue.other }, + .{ "location", PureGlobalIdentifierValue.other }, + .{ "locationbar", PureGlobalIdentifierValue.other }, + .{ "matchMedia", PureGlobalIdentifierValue.other }, + .{ "menubar", PureGlobalIdentifierValue.other }, + .{ "moveBy", PureGlobalIdentifierValue.other }, + .{ "moveTo", PureGlobalIdentifierValue.other }, + .{ "name", PureGlobalIdentifierValue.other }, + .{ "navigator", PureGlobalIdentifierValue.other }, + .{ "onabort", PureGlobalIdentifierValue.other }, + .{ "onafterprint", PureGlobalIdentifierValue.other }, + .{ "onanimationend", PureGlobalIdentifierValue.other }, + .{ "onanimationiteration", PureGlobalIdentifierValue.other }, + .{ "onanimationstart", PureGlobalIdentifierValue.other }, + .{ "onbeforeprint", PureGlobalIdentifierValue.other }, + .{ "onbeforeunload", PureGlobalIdentifierValue.other }, + .{ "onblur", PureGlobalIdentifierValue.other }, + .{ "oncanplay", PureGlobalIdentifierValue.other }, + .{ "oncanplaythrough", PureGlobalIdentifierValue.other }, + .{ "onchange", PureGlobalIdentifierValue.other }, + .{ "onclick", PureGlobalIdentifierValue.other }, + .{ "oncontextmenu", PureGlobalIdentifierValue.other }, + .{ "oncuechange", PureGlobalIdentifierValue.other }, + .{ "ondblclick", PureGlobalIdentifierValue.other }, + .{ "ondrag", PureGlobalIdentifierValue.other }, + .{ "ondragend", PureGlobalIdentifierValue.other }, + .{ "ondragenter", PureGlobalIdentifierValue.other }, + .{ "ondragleave", PureGlobalIdentifierValue.other }, + .{ "ondragover", PureGlobalIdentifierValue.other }, + .{ "ondragstart", PureGlobalIdentifierValue.other }, + .{ "ondrop", PureGlobalIdentifierValue.other }, + .{ "ondurationchange", PureGlobalIdentifierValue.other }, + .{ "onemptied", PureGlobalIdentifierValue.other }, + .{ "onended", PureGlobalIdentifierValue.other }, + .{ "onerror", PureGlobalIdentifierValue.other }, + .{ "onfocus", PureGlobalIdentifierValue.other }, + .{ "ongotpointercapture", PureGlobalIdentifierValue.other }, + .{ "onhashchange", PureGlobalIdentifierValue.other }, + .{ "oninput", PureGlobalIdentifierValue.other }, + .{ "oninvalid", PureGlobalIdentifierValue.other }, + .{ "onkeydown", PureGlobalIdentifierValue.other }, + .{ "onkeypress", PureGlobalIdentifierValue.other }, + .{ "onkeyup", PureGlobalIdentifierValue.other }, + .{ "onlanguagechange", PureGlobalIdentifierValue.other }, + .{ "onload", PureGlobalIdentifierValue.other }, + .{ "onloadeddata", PureGlobalIdentifierValue.other }, + .{ "onloadedmetadata", PureGlobalIdentifierValue.other }, + .{ "onloadstart", PureGlobalIdentifierValue.other }, + .{ "onlostpointercapture", PureGlobalIdentifierValue.other }, + .{ "onmessage", PureGlobalIdentifierValue.other }, + .{ "onmousedown", PureGlobalIdentifierValue.other }, + .{ "onmouseenter", PureGlobalIdentifierValue.other }, + .{ "onmouseleave", PureGlobalIdentifierValue.other }, + .{ "onmousemove", PureGlobalIdentifierValue.other }, + .{ "onmouseout", PureGlobalIdentifierValue.other }, + .{ "onmouseover", PureGlobalIdentifierValue.other }, + .{ "onmouseup", PureGlobalIdentifierValue.other }, + .{ "onoffline", PureGlobalIdentifierValue.other }, + .{ "ononline", PureGlobalIdentifierValue.other }, + .{ "onpagehide", PureGlobalIdentifierValue.other }, + .{ "onpageshow", PureGlobalIdentifierValue.other }, + .{ "onpause", PureGlobalIdentifierValue.other }, + .{ "onplay", PureGlobalIdentifierValue.other }, + .{ "onplaying", PureGlobalIdentifierValue.other }, + .{ "onpointercancel", PureGlobalIdentifierValue.other }, + .{ "onpointerdown", PureGlobalIdentifierValue.other }, + .{ "onpointerenter", PureGlobalIdentifierValue.other }, + .{ "onpointerleave", PureGlobalIdentifierValue.other }, + .{ "onpointermove", PureGlobalIdentifierValue.other }, + .{ "onpointerout", PureGlobalIdentifierValue.other }, + .{ "onpointerover", PureGlobalIdentifierValue.other }, + .{ "onpointerup", PureGlobalIdentifierValue.other }, + .{ "onpopstate", PureGlobalIdentifierValue.other }, + .{ "onprogress", PureGlobalIdentifierValue.other }, + .{ "onratechange", PureGlobalIdentifierValue.other }, + .{ "onrejectionhandled", PureGlobalIdentifierValue.other }, + .{ "onreset", PureGlobalIdentifierValue.other }, + .{ "onresize", PureGlobalIdentifierValue.other }, + .{ "onscroll", PureGlobalIdentifierValue.other }, + .{ "onseeked", PureGlobalIdentifierValue.other }, + .{ "onseeking", PureGlobalIdentifierValue.other }, + .{ "onselect", PureGlobalIdentifierValue.other }, + .{ "onstalled", PureGlobalIdentifierValue.other }, + .{ "onstorage", PureGlobalIdentifierValue.other }, + .{ "onsubmit", PureGlobalIdentifierValue.other }, + .{ "onsuspend", PureGlobalIdentifierValue.other }, + .{ "ontimeupdate", PureGlobalIdentifierValue.other }, + .{ "ontoggle", PureGlobalIdentifierValue.other }, + .{ "ontransitioncancel", PureGlobalIdentifierValue.other }, + .{ "ontransitionend", PureGlobalIdentifierValue.other }, + .{ "ontransitionrun", PureGlobalIdentifierValue.other }, + .{ "ontransitionstart", PureGlobalIdentifierValue.other }, + .{ "onunhandledrejection", PureGlobalIdentifierValue.other }, + .{ "onunload", PureGlobalIdentifierValue.other }, + .{ "onvolumechange", PureGlobalIdentifierValue.other }, + .{ "onwaiting", PureGlobalIdentifierValue.other }, + .{ "onwebkitanimationend", PureGlobalIdentifierValue.other }, + .{ "onwebkitanimationiteration", PureGlobalIdentifierValue.other }, + .{ "onwebkitanimationstart", PureGlobalIdentifierValue.other }, + .{ "onwebkittransitionend", PureGlobalIdentifierValue.other }, + .{ "onwheel", PureGlobalIdentifierValue.other }, + .{ "open", PureGlobalIdentifierValue.other }, + .{ "opener", PureGlobalIdentifierValue.other }, + .{ "origin", PureGlobalIdentifierValue.other }, + .{ "outerHeight", PureGlobalIdentifierValue.other }, + .{ "outerWidth", PureGlobalIdentifierValue.other }, + .{ "parent", PureGlobalIdentifierValue.other }, + .{ "performance", PureGlobalIdentifierValue.other }, + .{ "personalbar", PureGlobalIdentifierValue.other }, + .{ "postMessage", PureGlobalIdentifierValue.other }, + .{ "print", PureGlobalIdentifierValue.other }, + .{ "prompt", PureGlobalIdentifierValue.other }, + .{ "releaseEvents", PureGlobalIdentifierValue.other }, + .{ "requestAnimationFrame", PureGlobalIdentifierValue.other }, + .{ "resizeBy", PureGlobalIdentifierValue.other }, + .{ "resizeTo", PureGlobalIdentifierValue.other }, + .{ "screen", PureGlobalIdentifierValue.other }, + .{ "screenLeft", PureGlobalIdentifierValue.other }, + .{ "screenTop", PureGlobalIdentifierValue.other }, + .{ "screenX", PureGlobalIdentifierValue.other }, + .{ "screenY", PureGlobalIdentifierValue.other }, + .{ "scroll", PureGlobalIdentifierValue.other }, + .{ "scrollBy", PureGlobalIdentifierValue.other }, + .{ "scrollTo", PureGlobalIdentifierValue.other }, + .{ "scrollbars", PureGlobalIdentifierValue.other }, + .{ "self", PureGlobalIdentifierValue.other }, + .{ "speechSynthesis", PureGlobalIdentifierValue.other }, + .{ "status", PureGlobalIdentifierValue.other }, + .{ "statusbar", PureGlobalIdentifierValue.other }, + .{ "stop", PureGlobalIdentifierValue.other }, + .{ "toolbar", PureGlobalIdentifierValue.other }, + .{ "top", PureGlobalIdentifierValue.other }, + .{ "webkitURL", PureGlobalIdentifierValue.other }, + .{ "window", PureGlobalIdentifierValue.other }, + .{ "crypto", PureGlobalIdentifierValue.other }, +}); diff --git a/src/defines.zig b/src/defines.zig index 566fe23c65..39b7a07141 100644 --- a/src/defines.zig +++ b/src/defines.zig @@ -10,7 +10,8 @@ const strings = bun.strings; const Ref = @import("ast/base.zig").Ref; -const GlobalDefinesKey = @import("./defines-table.zig").GlobalDefinesKey; +const global_no_side_effect_property_accesses = table.global_no_side_effect_property_accesses; +const global_no_side_effect_function_calls_safe_for_to_string = table.global_no_side_effect_function_calls_safe_for_to_string; const table = @import("./defines-table.zig"); const Globals = struct { @@ -34,56 +35,114 @@ pub const UserDefinesArray = bun.StringArrayHashMap(DefineData); pub const DefineData = struct { value: js_ast.Expr.Data, - valueless: bool = false, - original_name: ?string = null, - // True if accessing this value is known to not have any side effects. For - // example, a bare reference to "Object.create" can be removed because it - // does not have any observable side effects. - can_be_removed_if_unused: bool = false, + // Not using a slice here shrinks the size from 48 bytes to 40 bytes. + original_name_ptr: ?[*]const u8 = null, + original_name_len: u32 = 0, - // True if a call to this value is known to not have any side effects. For - // example, a bare call to "Object()" can be removed because it does not - // have any observable side effects. - call_can_be_unwrapped_if_unused: bool = false, + flags: Flags = .{}, - method_call_must_be_replaced_with_undefined: bool = false, + pub const Flags = packed struct(u8) { + _padding: u3 = 0, - pub fn isUndefined(self: *const DefineData) bool { - return self.valueless; + valueless: bool = false, + + can_be_removed_if_unused: bool = false, + + call_can_be_unwrapped_if_unused: js_ast.E.CallUnwrap = .never, + + method_call_must_be_replaced_with_undefined: bool = false, + }; + + pub const Options = struct { + original_name: ?[]const u8 = null, + value: js_ast.Expr.Data, + valueless: bool = false, + can_be_removed_if_unused: bool = false, + call_can_be_unwrapped_if_unused: js_ast.E.CallUnwrap = .never, + method_call_must_be_replaced_with_undefined: bool = false, + }; + + pub fn init(options: Options) DefineData { + return DefineData{ + .value = options.value, + .flags = .{ + .valueless = options.valueless, + .can_be_removed_if_unused = options.can_be_removed_if_unused, + .call_can_be_unwrapped_if_unused = options.call_can_be_unwrapped_if_unused, + .method_call_must_be_replaced_with_undefined = options.method_call_must_be_replaced_with_undefined, + }, + .original_name_ptr = if (options.original_name) |name| name.ptr else null, + .original_name_len = if (options.original_name) |name| @truncate(name.len) else 0, + }; + } + + pub inline fn original_name(self: *const DefineData) ?[]const u8 { + if (self.original_name_len > 0) { + return self.original_name_ptr.?[0..self.original_name_len]; + } + return null; + } + + /// True if accessing this value is known to not have any side effects. For + /// example, a bare reference to "Object.create" can be removed because it + /// does not have any observable side effects. + pub inline fn can_be_removed_if_unused(self: *const DefineData) bool { + return self.flags.can_be_removed_if_unused; + } + + /// True if a call to this value is known to not have any side effects. For + /// example, a bare call to "Object()" can be removed because it does not + /// have any observable side effects. + pub inline fn call_can_be_unwrapped_if_unused(self: *const DefineData) js_ast.E.CallUnwrap { + return self.flags.call_can_be_unwrapped_if_unused; + } + + pub inline fn method_call_must_be_replaced_with_undefined(self: *const DefineData) bool { + return self.flags.method_call_must_be_replaced_with_undefined; + } + + pub inline fn valueless(self: *const DefineData) bool { + return self.flags.valueless; } pub fn initBoolean(value: bool) DefineData { return .{ .value = .{ .e_boolean = .{ .value = value } }, - .can_be_removed_if_unused = true, + .flags = .{ .can_be_removed_if_unused = true }, }; } pub fn initStaticString(str: *const js_ast.E.String) DefineData { return .{ .value = .{ .e_string = @constCast(str) }, - .can_be_removed_if_unused = true, + .flags = .{ .can_be_removed_if_unused = true }, }; } pub fn merge(a: DefineData, b: DefineData) DefineData { return DefineData{ .value = b.value, - .can_be_removed_if_unused = a.can_be_removed_if_unused, - .call_can_be_unwrapped_if_unused = a.call_can_be_unwrapped_if_unused, - .original_name = b.original_name, - .valueless = a.method_call_must_be_replaced_with_undefined or b.method_call_must_be_replaced_with_undefined, - .method_call_must_be_replaced_with_undefined = a.method_call_must_be_replaced_with_undefined or b.method_call_must_be_replaced_with_undefined, + .flags = .{ + .can_be_removed_if_unused = a.can_be_removed_if_unused(), + .call_can_be_unwrapped_if_unused = a.call_can_be_unwrapped_if_unused(), + + // TODO: investigate if this is correct. This is what it was before. But that looks strange. + .valueless = a.method_call_must_be_replaced_with_undefined() or b.method_call_must_be_replaced_with_undefined(), + + .method_call_must_be_replaced_with_undefined = a.method_call_must_be_replaced_with_undefined() or b.method_call_must_be_replaced_with_undefined(), + }, + .original_name_ptr = b.original_name_ptr, + .original_name_len = b.original_name_len, }; } - pub fn fromMergeableInputEntry(user_defines: *UserDefines, key: []const u8, value_str: []const u8, value_is_undefined: bool, method_call_must_be_replaced_with_undefined: bool, log: *logger.Log, allocator: std.mem.Allocator) !void { + pub fn fromMergeableInputEntry(user_defines: *UserDefines, key: []const u8, value_str: []const u8, value_is_undefined: bool, method_call_must_be_replaced_with_undefined_: bool, log: *logger.Log, allocator: std.mem.Allocator) !void { user_defines.putAssumeCapacity(key, try .parse( key, value_str, value_is_undefined, - method_call_must_be_replaced_with_undefined, + method_call_must_be_replaced_with_undefined_, log, allocator, )); @@ -93,7 +152,7 @@ pub const DefineData = struct { key: []const u8, value_str: []const u8, value_is_undefined: bool, - method_call_must_be_replaced_with_undefined: bool, + method_call_must_be_replaced_with_undefined_: bool, log: *logger.Log, allocator: std.mem.Allocator, ) !DefineData { @@ -133,10 +192,13 @@ pub const DefineData = struct { return .{ .value = value, - .original_name = value_str, - .can_be_removed_if_unused = true, - .valueless = value_is_undefined, - .method_call_must_be_replaced_with_undefined = method_call_must_be_replaced_with_undefined, + .original_name_ptr = if (value_str.len > 0) value_str.ptr else null, + .original_name_len = @truncate(value_str.len), + .flags = .{ + .can_be_removed_if_unused = true, + .valueless = value_is_undefined, + .method_call_must_be_replaced_with_undefined = method_call_must_be_replaced_with_undefined_, + }, }; } const _log = log; @@ -148,9 +210,13 @@ pub const DefineData = struct { const cloned = try expr.data.deepClone(allocator); return .{ .value = cloned, - .can_be_removed_if_unused = expr.isPrimitiveLiteral(), - .valueless = value_is_undefined, - .method_call_must_be_replaced_with_undefined = method_call_must_be_replaced_with_undefined, + .original_name_ptr = if (value_str.len > 0) value_str.ptr else null, + .original_name_len = @truncate(value_str.len), + .flags = .{ + .can_be_removed_if_unused = expr.isPrimitiveLiteral(), + .valueless = value_is_undefined, + .method_call_must_be_replaced_with_undefined = method_call_must_be_replaced_with_undefined_, + }, }; } @@ -203,12 +269,16 @@ pub const Define = struct { pub const Data = DefineData; - pub fn forIdentifier(this: *const Define, name: []const u8) ?IdentifierDefine { - if (this.identifiers.get(name)) |data| { + pub fn forIdentifier(this: *const Define, name: []const u8) ?*const IdentifierDefine { + if (this.identifiers.getPtr(name)) |data| { return data; } - return table.pure_global_identifier_map.get(name); + if (table.pure_global_identifier_map.get(name)) |id| { + return id.value(); + } + + return null; } pub fn insertFromIterator(define: *Define, allocator: std.mem.Allocator, comptime Iterator: type, iter: Iterator) !void { @@ -265,7 +335,30 @@ pub const Define = struct { } } - pub fn init(allocator: std.mem.Allocator, _user_defines: ?UserDefines, string_defines: ?UserDefinesArray, drop_debugger: bool) bun.OOM!*@This() { + fn insertGlobal(define: *Define, allocator: std.mem.Allocator, global: []const string, value_define: *const DefineData) !void { + const key = global[global.len - 1]; + const gpe = try define.dots.getOrPut(key); + if (gpe.found_existing) { + var list = try std.ArrayList(DotDefine).initCapacity(allocator, gpe.value_ptr.*.len + 1); + list.appendSliceAssumeCapacity(gpe.value_ptr.*); + list.appendAssumeCapacity(DotDefine{ + .parts = global[0..global.len], + .data = value_define.*, + }); + + gpe.value_ptr.* = try list.toOwnedSlice(); + } else { + var list = try std.ArrayList(DotDefine).initCapacity(allocator, 1); + list.appendAssumeCapacity(DotDefine{ + .parts = global[0..global.len], + .data = value_define.*, + }); + + gpe.value_ptr.* = try list.toOwnedSlice(); + } + } + + pub fn init(allocator: std.mem.Allocator, _user_defines: ?UserDefines, string_defines: ?UserDefinesArray, drop_debugger: bool, omit_unused_global_calls: bool) bun.OOM!*@This() { const define = try allocator.create(Define); define.allocator = allocator; define.identifiers = bun.StringHashMap(IdentifierDefine).init(allocator); @@ -273,32 +366,34 @@ pub const Define = struct { define.drop_debugger = drop_debugger; try define.dots.ensureTotalCapacity(124); - const value_define = DefineData{ + const value_define = &DefineData{ .value = .{ .e_undefined = .{} }, - .valueless = true, - .can_be_removed_if_unused = true, + .flags = .{ + .valueless = true, + .can_be_removed_if_unused = true, + }, }; // Step 1. Load the globals into the hash tables - for (GlobalDefinesKey) |global| { - const key = global[global.len - 1]; - const gpe = try define.dots.getOrPut(key); - if (gpe.found_existing) { - var list = try std.ArrayList(DotDefine).initCapacity(allocator, gpe.value_ptr.*.len + 1); - list.appendSliceAssumeCapacity(gpe.value_ptr.*); - list.appendAssumeCapacity(DotDefine{ - .parts = global[0..global.len], - .data = value_define, - }); + for (global_no_side_effect_property_accesses) |global| { + try define.insertGlobal(allocator, global, value_define); + } - gpe.value_ptr.* = try list.toOwnedSlice(); - } else { - var list = try std.ArrayList(DotDefine).initCapacity(allocator, 1); - list.appendAssumeCapacity(DotDefine{ - .parts = global[0..global.len], - .data = value_define, - }); + const to_string_safe = &DefineData{ + .value = .{ .e_undefined = .{} }, + .flags = .{ + .valueless = true, + .can_be_removed_if_unused = true, + .call_can_be_unwrapped_if_unused = .if_unused_and_toString_safe, + }, + }; - gpe.value_ptr.* = try list.toOwnedSlice(); + if (omit_unused_global_calls) { + for (global_no_side_effect_function_calls_safe_for_to_string) |global| { + try define.insertGlobal(allocator, global, to_string_safe); + } + } else { + for (global_no_side_effect_function_calls_safe_for_to_string) |global| { + try define.insertGlobal(allocator, global, value_define); } } diff --git a/src/env_loader.zig b/src/env_loader.zig index 78ce9e1cfe..a143d8b6da 100644 --- a/src/env_loader.zig +++ b/src/env_loader.zig @@ -420,11 +420,11 @@ pub const Loader = struct { _ = try to_string.getOrPutValue( key_str, - .{ + .init(.{ .can_be_removed_if_unused = true, - .call_can_be_unwrapped_if_unused = true, + .call_can_be_unwrapped_if_unused = .if_unused, .value = expr_data, - }, + }), ); e_strings = e_strings[1..]; } else { @@ -444,11 +444,11 @@ pub const Loader = struct { _ = try to_string.getOrPutValue( framework_defaults.keys[key_i], - .{ + .init(.{ .can_be_removed_if_unused = true, - .call_can_be_unwrapped_if_unused = true, + .call_can_be_unwrapped_if_unused = .if_unused, .value = expr_data, - }, + }), ); e_strings = e_strings[1..]; } @@ -470,11 +470,11 @@ pub const Loader = struct { _ = try to_string.getOrPutValue( key, - .{ + .init(.{ .can_be_removed_if_unused = true, - .call_can_be_unwrapped_if_unused = true, + .call_can_be_unwrapped_if_unused = .if_unused, .value = expr_data, - }, + }), ); e_strings = e_strings[1..]; } diff --git a/src/js_parser.zig b/src/js_parser.zig index e72026b2e5..bd5079b829 100644 --- a/src/js_parser.zig +++ b/src/js_parser.zig @@ -1741,9 +1741,17 @@ pub const SideEffects = enum(u1) { inline .e_call, .e_new => |call| { // A call that has been marked "__PURE__" can be removed if all arguments // can be removed. The annotation causes us to ignore the target. - if (call.can_be_unwrapped_if_unused) { + if (call.can_be_unwrapped_if_unused != .never) { if (call.args.len > 0) { - return Expr.joinAllWithCommaCallback(call.args.slice(), @TypeOf(p), p, comptime simplifyUnusedExpr, p.allocator); + const joined = Expr.joinAllWithCommaCallback(call.args.slice(), @TypeOf(p), p, comptime simplifyUnusedExpr, p.allocator); + if (joined != null and call.can_be_unwrapped_if_unused == .if_unused_and_toString_safe) { + @branchHint(.unlikely); + // For now, only support this for 1 argument. + if (joined.?.data.isSafeToString()) { + return null; + } + } + return joined; } else { return null; } @@ -4545,7 +4553,7 @@ pub const KnownGlobal = enum { if (n == 0) { // "new WeakSet()" is pure - e.can_be_unwrapped_if_unused = true; + e.can_be_unwrapped_if_unused = .if_unused; return; } @@ -4555,12 +4563,12 @@ pub const KnownGlobal = enum { .e_null, .e_undefined => { // "new WeakSet(null)" is pure // "new WeakSet(void 0)" is pure - e.can_be_unwrapped_if_unused = true; + e.can_be_unwrapped_if_unused = .if_unused; }, .e_array => |array| { if (array.items.len == 0) { // "new WeakSet([])" is pure - e.can_be_unwrapped_if_unused = true; + e.can_be_unwrapped_if_unused = .if_unused; } else { // "new WeakSet([x])" is impure because an exception is thrown if "x" is not an object } @@ -4576,7 +4584,7 @@ pub const KnownGlobal = enum { if (n == 0) { // "new Date()" is pure - e.can_be_unwrapped_if_unused = true; + e.can_be_unwrapped_if_unused = .if_unused; return; } @@ -4590,7 +4598,7 @@ pub const KnownGlobal = enum { // "new Date(true)" is pure // "new Date(false)" is pure // "new Date(undefined)" is pure - e.can_be_unwrapped_if_unused = true; + e.can_be_unwrapped_if_unused = .if_unused; }, else => { // "new Date(x)" is impure because the argument could be a string with side effects @@ -4605,7 +4613,7 @@ pub const KnownGlobal = enum { if (n == 0) { // "new Set()" is pure - e.can_be_unwrapped_if_unused = true; + e.can_be_unwrapped_if_unused = .if_unused; return; } @@ -4615,7 +4623,7 @@ pub const KnownGlobal = enum { // "new Set([a, b, c])" is pure // "new Set(null)" is pure // "new Set(void 0)" is pure - e.can_be_unwrapped_if_unused = true; + e.can_be_unwrapped_if_unused = .if_unused; }, else => { // "new Set(x)" is impure because the iterator for "x" could have side effects @@ -4629,7 +4637,7 @@ pub const KnownGlobal = enum { if (n == 0) { // "new Headers()" is pure - e.can_be_unwrapped_if_unused = true; + e.can_be_unwrapped_if_unused = .if_unused; return; } @@ -4640,7 +4648,7 @@ pub const KnownGlobal = enum { if (n == 0) { // "new Response()" is pure - e.can_be_unwrapped_if_unused = true; + e.can_be_unwrapped_if_unused = .if_unused; return; } @@ -4655,7 +4663,7 @@ pub const KnownGlobal = enum { // "new Response(false)" is pure // "new Response(undefined)" is pure - e.can_be_unwrapped_if_unused = true; + e.can_be_unwrapped_if_unused = .if_unused; }, else => { // "new Response(x)" is impure @@ -4669,7 +4677,7 @@ pub const KnownGlobal = enum { if (n == 0) { // "new TextEncoder()" is pure // "new TextDecoder()" is pure - e.can_be_unwrapped_if_unused = true; + e.can_be_unwrapped_if_unused = .if_unused; return; } @@ -4683,7 +4691,7 @@ pub const KnownGlobal = enum { if (n == 0) { // "new Map()" is pure - e.can_be_unwrapped_if_unused = true; + e.can_be_unwrapped_if_unused = .if_unused; return; } @@ -4692,7 +4700,7 @@ pub const KnownGlobal = enum { .e_null, .e_undefined => { // "new Map(null)" is pure // "new Map(void 0)" is pure - e.can_be_unwrapped_if_unused = true; + e.can_be_unwrapped_if_unused = .if_unused; }, .e_array => |array| { var all_items_are_arrays = true; @@ -4705,7 +4713,7 @@ pub const KnownGlobal = enum { if (all_items_are_arrays) { // "new Map([[a, b], [c, d]])" is pure - e.can_be_unwrapped_if_unused = true; + e.can_be_unwrapped_if_unused = .if_unused; } }, else => { @@ -13031,10 +13039,10 @@ fn NewParser_( expr = try p.parseSuffix(expr, @as(Level, @enumFromInt(@intFromEnum(Level.call) - 1)), errors, flags); switch (expr.data) { .e_call => |ex| { - ex.can_be_unwrapped_if_unused = true; + ex.can_be_unwrapped_if_unused = .if_unused; }, .e_new => |ex| { - ex.can_be_unwrapped_if_unused = true; + ex.can_be_unwrapped_if_unused = .if_unused; }, else => {}, } @@ -16259,8 +16267,8 @@ fn NewParser_( // Substitute user-specified defines for unbound symbols if (p.symbols.items[e_.ref.innerIndex()].kind == .unbound and !result.is_inside_with_scope and !is_delete_target) { if (p.define.forIdentifier(name)) |def| { - if (!def.valueless) { - const newvalue = p.valueForDefine(expr.loc, in.assign_target, is_delete_target, &def); + if (!def.valueless()) { + const newvalue = p.valueForDefine(expr.loc, in.assign_target, is_delete_target, def); // Don't substitute an identifier for a non-identifier if this is an // assignment target, since it'll cause a syntax error @@ -16269,19 +16277,19 @@ fn NewParser_( return newvalue; } - original_name = def.original_name; + original_name = def.original_name(); } // Copy the side effect flags over in case this expression is unused - if (def.can_be_removed_if_unused) { + if (def.can_be_removed_if_unused()) { e_.can_be_removed_if_unused = true; } - if (def.call_can_be_unwrapped_if_unused and !p.options.ignore_dce_annotations) { + if (def.call_can_be_unwrapped_if_unused() == .if_unused and !p.options.ignore_dce_annotations) { e_.call_can_be_unwrapped_if_unused = true; } // If the user passed --drop=console, drop all property accesses to console. - if (def.method_call_must_be_replaced_with_undefined and in.property_access_for_method_call_maybe_should_replace_with_undefined and in.assign_target == .none) { + if (def.method_call_must_be_replaced_with_undefined() and in.property_access_for_method_call_maybe_should_replace_with_undefined and in.assign_target == .none) { p.method_call_must_be_replaced_with_undefined = true; } } @@ -16374,7 +16382,7 @@ fn NewParser_( .target = if (runtime == .classic) target else p.jsxImport(.createElement, expr.loc), .args = ExprNodeList.init(args[0..i]), // Enable tree shaking - .can_be_unwrapped_if_unused = !p.options.ignore_dce_annotations, + .can_be_unwrapped_if_unused = if (!p.options.ignore_dce_annotations) .if_unused else .never, .close_paren_loc = e_.close_tag_loc, }, expr.loc); } @@ -16479,7 +16487,7 @@ fn NewParser_( .target = p.jsxImportAutomatic(expr.loc, is_static_jsx), .args = ExprNodeList.init(args), // Enable tree shaking - .can_be_unwrapped_if_unused = !p.options.ignore_dce_annotations, + .can_be_unwrapped_if_unused = if (!p.options.ignore_dce_annotations) .if_unused else .never, .was_jsx_element = true, .close_paren_loc = e_.close_tag_loc, }, expr.loc); @@ -16934,26 +16942,26 @@ fn NewParser_( const is_call_target = @as(Expr.Tag, p.call_target) == .e_dot and expr.data.e_dot == p.call_target.e_dot; if (p.define.dots.get(e_.name)) |parts| { - for (parts) |define| { + for (parts) |*define| { if (p.isDotDefineMatch(expr, define.parts)) { if (in.assign_target == .none) { // Substitute user-specified defines - if (!define.data.valueless) { + if (!define.data.valueless()) { return p.valueForDefine(expr.loc, in.assign_target, is_delete_target, &define.data); } - if (define.data.method_call_must_be_replaced_with_undefined and in.property_access_for_method_call_maybe_should_replace_with_undefined) { + if (define.data.method_call_must_be_replaced_with_undefined() and in.property_access_for_method_call_maybe_should_replace_with_undefined) { p.method_call_must_be_replaced_with_undefined = true; } } // Copy the side effect flags over in case this expression is unused - if (define.data.can_be_removed_if_unused) { + if (define.data.can_be_removed_if_unused()) { e_.can_be_removed_if_unused = true; } - if (define.data.call_can_be_unwrapped_if_unused and !p.options.ignore_dce_annotations) { - e_.call_can_be_unwrapped_if_unused = true; + if (define.data.call_can_be_unwrapped_if_unused() != .never and !p.options.ignore_dce_annotations) { + e_.call_can_be_unwrapped_if_unused = define.data.call_can_be_unwrapped_if_unused(); } break; @@ -17257,7 +17265,8 @@ fn NewParser_( // Copy the call side effect flag over if this is a known target switch (e_.target.data) { .e_identifier => |ident| { - e_.can_be_unwrapped_if_unused = e_.can_be_unwrapped_if_unused or ident.call_can_be_unwrapped_if_unused; + if (ident.call_can_be_unwrapped_if_unused and e_.can_be_unwrapped_if_unused == .never) + e_.can_be_unwrapped_if_unused = .if_unused; // Detect if this is a direct eval. Note that "(1 ? eval : 0)(x)" will // become "eval(x)" after we visit the target due to dead code elimination, @@ -17293,7 +17302,9 @@ fn NewParser_( } }, .e_dot => |dot| { - e_.can_be_unwrapped_if_unused = e_.can_be_unwrapped_if_unused or dot.call_can_be_unwrapped_if_unused; + if (dot.call_can_be_unwrapped_if_unused != .never and e_.can_be_unwrapped_if_unused == .never) { + e_.can_be_unwrapped_if_unused = dot.call_can_be_unwrapped_if_unused; + } }, else => {}, } @@ -17364,7 +17375,7 @@ fn NewParser_( } if (e_.target.data == .e_require_call_target) { - e_.can_be_unwrapped_if_unused = false; + e_.can_be_unwrapped_if_unused = .never; // Heuristic: omit warnings inside try/catch blocks because presumably // the try/catch statement is there to handle the potential run-time @@ -17972,9 +17983,9 @@ fn NewParser_( .e_call => |ex| { // A call that has been marked "__PURE__" can be removed if all arguments // can be removed. The annotation causes us to ignore the target. - if (ex.can_be_unwrapped_if_unused) { + if (ex.can_be_unwrapped_if_unused != .never) { for (ex.args.slice()) |*arg| { - if (!p.exprCanBeRemovedIfUnusedWithoutDCECheck(arg)) { + if (!(p.exprCanBeRemovedIfUnusedWithoutDCECheck(arg) or (ex.can_be_unwrapped_if_unused == .if_unused_and_toString_safe and arg.data.isSafeToString()))) { return false; } } @@ -17985,9 +17996,9 @@ fn NewParser_( // A call that has been marked "__PURE__" can be removed if all arguments // can be removed. The annotation causes us to ignore the target. - if (ex.can_be_unwrapped_if_unused) { + if (ex.can_be_unwrapped_if_unused != .never) { for (ex.args.slice()) |*arg| { - if (!p.exprCanBeRemovedIfUnusedWithoutDCECheck(arg)) { + if (!(p.exprCanBeRemovedIfUnusedWithoutDCECheck(arg) or (ex.can_be_unwrapped_if_unused == .if_unused_and_toString_safe and arg.data.isSafeToString()))) { return false; } } @@ -21662,7 +21673,7 @@ fn NewParser_( return p.handleIdentifier( loc, define_data.value.e_identifier, - define_data.original_name.?, + define_data.original_name().?, IdentifierOpts{ .assign_target = assign_target, .is_delete_target = is_delete_target, diff --git a/src/js_printer.zig b/src/js_printer.zig index f84580df6e..e37bef9d4f 100644 --- a/src/js_printer.zig +++ b/src/js_printer.zig @@ -2203,7 +2203,7 @@ fn NewPrinter( } }, .e_new => |e| { - const has_pure_comment = e.can_be_unwrapped_if_unused and p.options.print_dce_annotations; + const has_pure_comment = e.can_be_unwrapped_if_unused == .if_unused and p.options.print_dce_annotations; const wrap = level.gte(.call) or (has_pure_comment and level.gte(.postfix)); if (wrap) { @@ -2253,7 +2253,7 @@ fn NewPrinter( wrap = true; } - const has_pure_comment = e.can_be_unwrapped_if_unused and p.options.print_dce_annotations; + const has_pure_comment = e.can_be_unwrapped_if_unused == .if_unused and p.options.print_dce_annotations; if (has_pure_comment and level.gte(.postfix)) { wrap = true; } diff --git a/src/options.zig b/src/options.zig index 674ab709d5..a287515563 100644 --- a/src/options.zig +++ b/src/options.zig @@ -1401,6 +1401,7 @@ pub fn definesFromTransformOptions( framework_env: ?*const Env, NODE_ENV: ?string, drop: []const []const u8, + omit_unused_global_calls: bool, ) !*defines.Define { const input_user_define = maybe_input_define orelse std.mem.zeroes(Api.StringMap); @@ -1483,11 +1484,11 @@ pub fn definesFromTransformOptions( if (target.isBun()) { if (!user_defines.contains("window")) { - _ = try environment_defines.getOrPutValue("window", .{ + _ = try environment_defines.getOrPutValue("window", .init(.{ .valueless = true, .original_name = "window", .value = .{ .e_undefined = .{} }, - }); + })); } } @@ -1502,6 +1503,7 @@ pub fn definesFromTransformOptions( resolved_defines, environment_defines, drop_debugger, + omit_unused_global_calls, ); } @@ -1863,6 +1865,7 @@ pub const BundleOptions = struct { break :node_env "\"development\""; }, this.drop, + this.dead_code_elimination and this.minify_syntax, ); this.defines_loaded = true; } diff --git a/test/bundler/bundler_minify.test.ts b/test/bundler/bundler_minify.test.ts index 06f23814dc..7cd6c18c2b 100644 --- a/test/bundler/bundler_minify.test.ts +++ b/test/bundler/bundler_minify.test.ts @@ -554,7 +554,7 @@ describe("bundler", () => { export function jsx(type, props) { return {type, props}; } - export const Fragment = Symbol.for("jsx-runtime"); + export const Fragment = (globalThis.doNotDCE = Symbol.for("jsx-runtime")); `, "/node_modules/dev-trap/package.json": `{ "name": "dev-trap", diff --git a/test/bundler/bundler_minify_symbol_for.test.ts b/test/bundler/bundler_minify_symbol_for.test.ts new file mode 100644 index 0000000000..daa79ec4da --- /dev/null +++ b/test/bundler/bundler_minify_symbol_for.test.ts @@ -0,0 +1,340 @@ +import { describe, expect } from "bun:test"; +import { itBundled } from "./expectBundled"; + +describe("bundler", () => { + describe("minify/Symbol.for", () => { + // Test basic Symbol.for removal when unused + itBundled("minify/SymbolForUnused", { + files: { + "/entry.js": /* js */ ` + // These should be removed when minifySyntax is true + Symbol.for("test1"); + Symbol.for("test2"); + Symbol.for(\`test3\`); + Symbol.for("test" + 4); // This has a side effect (string concatenation) + + // Keep reference to prove concatenation happened + var sideEffect = "test" + 4; + Symbol.for(sideEffect); + + // These should NOT be removed (used values) + const s1 = Symbol.for("used1"); + let s2 = Symbol.for("used2"); + var s3 = Symbol.for("used3"); + + // Function argument - should not be removed + console.log(Symbol.for("argument")); + + // Property access - should not be removed + const obj = { prop: Symbol.for("property") }; + + // Return value - should not be removed + function getSymbol() { + return Symbol.for("return"); + } + + capture(s1, s2, s3, obj.prop, getSymbol(), sideEffect); + `, + }, + minifySyntax: true, + onAfterBundle(api) { + const output = api.readFile("/out.js"); + + // Should remove unused Symbol.for calls + expect(output).not.toContain('Symbol.for("test1")'); + expect(output).not.toContain('Symbol.for("test2")'); + expect(output).not.toContain("Symbol.for(`test3`)"); + + // Should keep the concatenation because sideEffect variable is used + expect(output).toContain("test4"); + + // Should keep used Symbol.for calls + expect(output).toContain('Symbol.for("used1")'); + expect(output).toContain('Symbol.for("used2")'); + expect(output).toContain('Symbol.for("used3")'); + expect(output).toContain('Symbol.for("argument")'); + expect(output).toContain('Symbol.for("property")'); + expect(output).toContain('Symbol.for("return")'); + }, + }); + + // Test that Symbol.for is not removed when minifySyntax is false + itBundled("minify/SymbolForNoMinifySyntax", { + files: { + "/entry.js": /* js */ ` + Symbol.for("test1"); + Symbol.for("test2"); + const s = Symbol.for("test3"); + capture(s); + `, + }, + minifySyntax: false, + onAfterBundle(api) { + const output = api.readFile("/out.js"); + + // Should keep all Symbol.for calls when minifySyntax is false + expect(output).toContain('Symbol.for("test1")'); + expect(output).toContain('Symbol.for("test2")'); + expect(output).toContain('Symbol.for("test3")'); + }, + }); + + // Test interaction with other minification options + itBundled("minify/SymbolForWithWhitespace", { + files: { + "/entry.js": /* js */ ` + // Unused calls should be removed + Symbol.for("remove-me-1"); + Symbol.for("remove-me-2"); + + // Used call should remain + const sym = Symbol.for("keep-me"); + + // Test with complex expressions + const ab = "a" + "b"; + Symbol.for(ab); // Keep the variable to ensure concatenation happens + Symbol.for(\`template\`); + + capture(sym, ab); + `, + }, + minifySyntax: true, + minifyWhitespace: true, + onAfterBundle(api) { + const output = api.readFile("/out.js"); + + // Should remove unused calls + expect(output).not.toContain("remove-me-1"); + expect(output).not.toContain("remove-me-2"); + + // Should keep used call + expect(output).toContain('Symbol.for("keep-me")'); + + // Should keep side effect (the concatenation is kept because ab is used) + expect(output).toContain("ab"); + }, + }); + + // Test edge cases + itBundled("minify/SymbolForEdgeCases", { + files: { + "/entry.js": /* js */ ` + // Optional chaining - these are preserved because optional chaining has observable behavior + Symbol?.for("optional1"); + Symbol?.for?.("optional2"); + + // In conditional - these should be optimized based on the condition + true && Symbol.for("conditional1"); + false || Symbol.for("conditional2"); + + // In ternary - these should be optimized based on the condition + true ? Symbol.for("ternary1") : null; + false ? null : Symbol.for("ternary2"); + + // Nested calls + Symbol.for(Symbol.for("nested")); + + // With spread + const arr = [...[Symbol.for("spread")]]; + + // Property key + const obj = { + [Symbol.for("key")]: "value" + }; + + capture(arr, obj); + `, + }, + minifySyntax: true, + onAfterBundle(api) { + const output = api.readFile("/out.js"); + + // Optional chaining preserves the call because it has observable behavior (checking if Symbol exists) + expect(output).toContain("optional1"); + expect(output).toContain("optional2"); + + // All the conditional/ternary expressions were optimized away completely + // because they evaluate to unused Symbol.for calls + expect(output).not.toContain("conditional1"); + expect(output).not.toContain("conditional2"); + expect(output).not.toContain("ternary1"); + expect(output).not.toContain("ternary2"); + + // Nested call was also optimized away + expect(output).not.toContain("nested"); + + // Used in spread - should keep + expect(output).toContain('Symbol.for("spread")'); + + // Used as property key - should keep + expect(output).toContain('Symbol.for("key")'); + }, + }); + + // Test that Symbol.keyFor is not affected (it's still in the property access list) + itBundled("minify/SymbolKeyForNotAffected", { + files: { + "/entry.js": /* js */ ` + // Symbol.keyFor should still be removed as a property access + Symbol.keyFor; + + // But not when called + const sym = Symbol.for("test"); + const key = Symbol.keyFor(sym); + + capture(key); + `, + }, + minifySyntax: true, + onAfterBundle(api) { + const output = api.readFile("/out.js"); + + // The unused property access "Symbol.keyFor;" should be removed + // But the function call "Symbol.keyFor(sym)" should remain + // So we should find exactly one occurrence of "Symbol.keyFor" + const keyForMatches = output.match(/Symbol\.keyFor/g) || []; + expect(keyForMatches.length).toBe(1); + + // Function call should remain + expect(output).toContain("Symbol.keyFor("); + }, + }); + + // Test interaction with production mode + itBundled("minify/SymbolForProduction", { + files: { + "/entry.js": /* js */ ` + // Unused + Symbol.for("remove-in-prod"); + + // Used + const s = Symbol.for("keep-in-prod"); + + // Side effects + Symbol.for(someGlobal); + + capture(s); + `, + }, + production: true, // This enables minifySyntax + onAfterBundle(api) { + const output = api.readFile("/out.js"); + + // Should remove unused + expect(output).not.toContain("remove-in-prod"); + + // Should keep used + expect(output).toContain("keep-in-prod"); + + // Should keep side effects + expect(output).toContain("someGlobal"); + }, + }); + + // Test with bundling disabled (transform mode) + itBundled("minify/SymbolForTransformMode", { + files: { + "/entry.js": /* js */ ` + Symbol.for("unused"); + const used = Symbol.for("used"); + export { used }; + `, + }, + bundling: false, + minifySyntax: true, + onAfterBundle(api) { + const output = api.readFile("/out.js"); + + // Should remove unused in transform mode too + expect(output).not.toContain('"unused"'); + + // Should keep used + expect(output).toContain('Symbol.for("used")'); + }, + }); + + // Test interaction with tree shaking + itBundled("minify/SymbolForTreeShaking", { + files: { + "/entry.js": /* js */ ` + import { sym } from "./lib.js"; + + // This should be removed + Symbol.for("entry-unused"); + + capture(sym); + `, + "/lib.js": /* js */ ` + // This should be removed (unused export) + export const unused = Symbol.for("lib-unused-export"); + + // This should be kept (used export) + export const sym = Symbol.for("lib-used-export"); + + // This should be removed (not exported) + Symbol.for("lib-internal"); + `, + }, + minifySyntax: true, + treeShaking: true, + onAfterBundle(api) { + const output = api.readFile("/out.js"); + + // Should remove all unused Symbol.for calls + expect(output).not.toContain("entry-unused"); + expect(output).not.toContain("lib-unused-export"); + expect(output).not.toContain("lib-internal"); + + // Should keep used Symbol.for call + expect(output).toContain("lib-used-export"); + }, + }); + + // Test that Symbol.for is still called at runtime when overridden + itBundled("minify/SymbolForRuntimeOverride", { + files: { + "/entry.js": /* js */ ` + let callCount = 0; + const originalSymbolFor = Symbol.for; + + // Override Symbol.for to count calls + Symbol.for = function(key) { + callCount++; + return originalSymbolFor.call(this, key); + }; + + // These unused calls should be removed at bundle time + Symbol.for("unused1"); + Symbol.for("unused2"); + + // These used calls should remain and increment callCount + const s1 = Symbol.for("used1"); + const s2 = Symbol.for("used2"); + + // Restore original + Symbol.for = originalSymbolFor; + + // Verify that Symbol.for was called for the used symbols + if (callCount !== 2) { + throw new Error(\`Expected 2 calls to Symbol.for, got \${callCount}\`); + } + + // Verify the symbols work correctly + if (s1 !== Symbol.for("used1")) { + throw new Error("Symbol s1 mismatch"); + } + if (s2 !== Symbol.for("used2")) { + throw new Error("Symbol s2 mismatch"); + } + + console.log("PASS"); + `, + }, + + minifySyntax: true, + run: { + stdout: "PASS", + }, + }); + }); +}); diff --git a/test/no-validate-exceptions.txt b/test/no-validate-exceptions.txt index 753e96060f..02785f95d5 100644 --- a/test/no-validate-exceptions.txt +++ b/test/no-validate-exceptions.txt @@ -20,6 +20,7 @@ test/bundler/bundler_html.test.ts test/bundler/bundler_html_server.test.ts test/bundler/bundler_jsx.test.ts test/bundler/bundler_minify.test.ts +test/bundler/bundler_minify_symbol_for.test.ts test/bundler/bundler_naming.test.ts test/bundler/bundler_plugin.test.ts test/bundler/bundler_regressions.test.ts