diff --git a/.cursor/rules/zig-javascriptcore-classes.mdc b/.cursor/rules/zig-javascriptcore-classes.mdc index 4c99f4929a..965932a988 100644 --- a/.cursor/rules/zig-javascriptcore-classes.mdc +++ b/.cursor/rules/zig-javascriptcore-classes.mdc @@ -65,21 +65,27 @@ The Zig files implement the native functionality: ```zig // Example: TextDecoder.zig pub const TextDecoder = struct { + // Expose generated bindings as `js` namespace with trait conversion methods + pub const js = JSC.Codegen.JSTextDecoder; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; + // Internal state encoding: []const u8, fatal: bool, ignoreBOM: bool, - - // Use generated bindings - pub usingnamespace JSC.Codegen.JSTextDecoder; - pub usingnamespace bun.New(@This()); - + // Constructor implementation - note use of globalObject pub fn constructor( globalObject: *JSGlobalObject, callFrame: *JSC.CallFrame, ) bun.JSError!*TextDecoder { // Implementation + + return bun.new(TextDecoder, .{ + // Fields + }); } // Prototype methods - note return type includes JSError @@ -101,22 +107,22 @@ pub const TextDecoder = struct { } // Cleanup - note standard pattern of using deinit/deref - pub fn deinit(this: *TextDecoder) void { + fn deinit(this: *TextDecoder) void { // Release any retained resources + // Free the pointer at the end. + bun.destroy(this); } + // Finalize - called by JS garbage collector. This should call deinit, or deref if reference counted. pub fn finalize(this: *TextDecoder) void { this.deinit(); - // Or sometimes this is used to free memory instead - bun.default_allocator.destroy(this); } }; ``` Key components in the Zig file: - The struct containing native state -- `usingnamespace JSC.Codegen.JS` to include generated code -- `usingnamespace bun.New(@This())` for object creation helpers +- `pub const js = JSC.Codegen.JS` to include generated code - Constructor and methods using `bun.JSError!JSValue` return type for proper error handling - Consistent use of `globalObject` parameter name instead of `ctx` - Methods matching the JavaScript interface @@ -395,12 +401,16 @@ To create a new class binding in Bun: 2. **Implement the native functionality** in a `.zig` file: ```zig pub const MyClass = struct { + // Generated bindings + pub const js = JSC.Codegen.JSMyClass; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; + // State value: []const u8, - // Generated bindings - pub usingnamespace JSC.Codegen.JSMyClass; - pub usingnamespace bun.New(@This()); + pub const new = bun.TrivialNew(@This()); // Constructor pub fn constructor( @@ -432,7 +442,7 @@ To create a new class binding in Bun: pub fn finalize(this: *MyClass) void { this.deinit(); - bun.default_allocator.destroy(this); + bun.destroy(this); } }; ``` @@ -485,4 +495,4 @@ For each Zig class, the system generates: - **Child Visitor Methods**: `visitChildrenImpl` and `visitAdditionalChildren` - **Heap Analysis**: `analyzeHeap` for debugging memory issues -This architecture makes it possible to implement high-performance native functionality in Zig while exposing a clean, idiomatic JavaScript API to users. \ No newline at end of file +This architecture makes it possible to implement high-performance native functionality in Zig while exposing a clean, idiomatic JavaScript API to users. diff --git a/LATEST b/LATEST index 434dcac4fa..732aa7d7d5 100644 --- a/LATEST +++ b/LATEST @@ -1 +1 @@ -1.2.9 \ No newline at end of file +1.2.10 \ No newline at end of file diff --git a/build.zig b/build.zig index 6a9d2051e3..bc5c4fcc28 100644 --- a/build.zig +++ b/build.zig @@ -18,7 +18,7 @@ const OperatingSystem = @import("src/env.zig").OperatingSystem; const pathRel = fs.path.relative; -/// Do not rename this constant. It is scanned by some scripts to determine which zig version to install. +/// When updating this, make sure to adjust SetupZig.cmake const recommended_zig_version = "0.14.0"; comptime { @@ -465,29 +465,40 @@ fn getTranslateC(b: *Build, target: std.Build.ResolvedTarget, optimize: std.buil } pub fn addBunObject(b: *Build, opts: *BunBuildOptions) *Compile { - const obj = b.addObject(.{ - .name = if (opts.optimize == .Debug) "bun-debug" else "bun", - .root_source_file = switch (opts.os) { - .wasm => b.path("root_wasm.zig"), - else => b.path("src/main.zig"), - // else => b.path("root_css.zig"), - }, + // Create `@import("bun")`, containing most of Bun's code. + const bun = b.createModule(.{ + .root_source_file = b.path("src/bun.zig"), + }); + bun.addImport("bun", bun); // allow circular "bun" import + addInternalImports(b, bun, opts); + + const root = b.createModule(.{ + .root_source_file = b.path("src/main.zig"), + + // Root module gets compilation flags. Forwarded as default to dependencies. .target = opts.target, .optimize = opts.optimize, - .use_llvm = !opts.no_llvm, - .use_lld = if (opts.os == .mac) false else !opts.no_llvm, + }); + root.addImport("bun", bun); - // https://github.com/ziglang/zig/issues/17430 - .pic = true, - - .omit_frame_pointer = false, - .strip = false, // stripped at the end + const obj = b.addObject(.{ + .name = if (opts.optimize == .Debug) "bun-debug" else "bun", + .root_module = root, }); configureObj(b, opts, obj); return obj; } fn configureObj(b: *Build, opts: *BunBuildOptions, obj: *Compile) void { + // Flags on root module get used for the compilation + obj.root_module.omit_frame_pointer = false; + obj.root_module.strip = false; // stripped at the end + // https://github.com/ziglang/zig/issues/17430 + obj.root_module.pic = true; + + // Object options + obj.use_llvm = !opts.no_llvm; + obj.use_lld = if (opts.os == .mac) false else !opts.no_llvm; if (opts.enable_asan) { if (@hasField(Build.Module, "sanitize_address")) { obj.root_module.sanitize_address = true; @@ -498,7 +509,6 @@ fn configureObj(b: *Build, opts: *BunBuildOptions, obj: *Compile) void { } obj.bundle_compiler_rt = false; obj.bundle_ubsan_rt = false; - obj.root_module.omit_frame_pointer = false; // Link libc if (opts.os != .wasm) { @@ -508,6 +518,7 @@ fn configureObj(b: *Build, opts: *BunBuildOptions, obj: *Compile) void { // Disable stack probing on x86 so we don't need to include compiler_rt if (opts.arch.isX86()) { + // TODO: enable on debug please. obj.root_module.stack_check = false; obj.root_module.stack_protector = false; } @@ -522,15 +533,18 @@ fn configureObj(b: *Build, opts: *BunBuildOptions, obj: *Compile) void { obj.root_module.valgrind = true; } } - addInternalPackages(b, obj, opts); - obj.root_module.addImport("build_options", opts.buildOptionsModule(b)); - - const translate_c = getTranslateC(b, opts.target, opts.optimize); - obj.root_module.addImport("translated-c-headers", translate_c.createModule()); } const ObjectFormat = enum { + /// Emitting LLVM bc files could allow a stronger LTO pass, however it + /// doesn't yet work. It is left accessible with `-Dobj_format=bc` or in + /// CMake with `-DZIG_OBJECT_FORMAT=bc`. + /// + /// To use LLVM bitcode from Zig, more work needs to be done. Currently, an install of + /// LLVM 18.1.7 does not compatible with what bitcode Zig 0.13 outputs (has LLVM 18.1.7) + /// Change to "bc" to experiment, "Invalid record" means it is not valid output. bc, + /// Emit a .o / .obj file for the bun-zig object. obj, }; @@ -560,16 +574,21 @@ fn exists(path: []const u8) bool { return true; } -fn addInternalPackages(b: *Build, obj: *Compile, opts: *BunBuildOptions) void { +fn addInternalImports(b: *Build, mod: *Module, opts: *BunBuildOptions) void { const os = opts.os; + mod.addImport("build_options", opts.buildOptionsModule(b)); + + const translate_c = getTranslateC(b, opts.target, opts.optimize); + mod.addImport("translated-c-headers", translate_c.createModule()); + const zlib_internal_path = switch (os) { .windows => "src/deps/zlib.win32.zig", .linux, .mac => "src/deps/zlib.posix.zig", else => null, }; if (zlib_internal_path) |path| { - obj.root_module.addAnonymousImport("zlib-internal", .{ + mod.addAnonymousImport("zlib-internal", .{ .root_source_file = b.path(path), }); } @@ -579,7 +598,7 @@ fn addInternalPackages(b: *Build, obj: *Compile, opts: *BunBuildOptions) void { .windows => "src/async/windows_event_loop.zig", else => "src/async/stub_event_loop.zig", }; - obj.root_module.addAnonymousImport("async", .{ + mod.addAnonymousImport("async", .{ .root_source_file = b.path(async_path), }); @@ -627,7 +646,7 @@ fn addInternalPackages(b: *Build, obj: *Compile, opts: *BunBuildOptions) void { entry.import else entry.file; - obj.root_module.addAnonymousImport(import_path, .{ + mod.addAnonymousImport(import_path, .{ .root_source_file = .{ .cwd_relative = path }, }); } @@ -637,16 +656,37 @@ fn addInternalPackages(b: *Build, obj: *Compile, opts: *BunBuildOptions) void { .{ .import = "completions-zsh", .file = b.path("completions/bun.zsh") }, .{ .import = "completions-fish", .file = b.path("completions/bun.fish") }, }) |entry| { - obj.root_module.addAnonymousImport(entry.import, .{ + mod.addAnonymousImport(entry.import, .{ .root_source_file = entry.file, }); } if (os == .windows) { - obj.root_module.addAnonymousImport("bun_shim_impl.exe", .{ + mod.addAnonymousImport("bun_shim_impl.exe", .{ .root_source_file = opts.windowsShim(b).exe.getEmittedBin(), }); } + + // Finally, make it so all modules share the same import table. + propagateImports(mod) catch @panic("OOM"); +} + +/// Makes all imports of `source_mod` visible to all of its dependencies. +/// Does not replace existing imports. +fn propagateImports(source_mod: *Module) !void { + var seen = std.AutoHashMap(*Module, void).init(source_mod.owner.graph.arena); + defer seen.deinit(); + var queue = std.ArrayList(*Module).init(source_mod.owner.graph.arena); + defer queue.deinit(); + try queue.appendSlice(source_mod.import_table.values()); + while (queue.pop()) |mod| { + if ((try seen.getOrPut(mod)).found_existing) continue; + try queue.appendSlice(mod.import_table.values()); + + for (source_mod.import_table.keys(), source_mod.import_table.values()) |k, v| + if (mod.import_table.get(k) == null) + mod.addImport(k, v); + } } fn validateGeneratedPath(path: []const u8) void { @@ -675,30 +715,34 @@ const WindowsShim = struct { const exe = b.addExecutable(.{ .name = "bun_shim_impl", - .root_source_file = path, - .target = target, - .optimize = .ReleaseFast, + .root_module = b.createModule(.{ + .root_source_file = path, + .target = target, + .optimize = .ReleaseFast, + .unwind_tables = .none, + .omit_frame_pointer = true, + .strip = true, + .sanitize_thread = false, + .single_threaded = true, + .link_libc = false, + }), + .linkage = .static, .use_llvm = true, .use_lld = true, - .unwind_tables = .none, - .omit_frame_pointer = true, - .strip = true, - .linkage = .static, - .sanitize_thread = false, - .single_threaded = true, - .link_libc = false, }); const dbg = b.addExecutable(.{ .name = "bun_shim_debug", - .root_source_file = path, - .target = target, - .optimize = .Debug, + .root_module = b.createModule(.{ + .root_source_file = path, + .target = target, + .optimize = .Debug, + .single_threaded = true, + .link_libc = false, + }), + .linkage = .static, .use_llvm = true, .use_lld = true, - .linkage = .static, - .single_threaded = true, - .link_libc = false, }); return .{ .exe = exe, .dbg = dbg }; diff --git a/bun.lock b/bun.lock index 2f08f1d900..5e7baad5b7 100644 --- a/bun.lock +++ b/bun.lock @@ -27,10 +27,8 @@ }, "packages/bun-types": { "name": "bun-types", - "version": "1.2.5", "dependencies": { "@types/node": "*", - "@types/ws": "*", }, "devDependencies": { "@biomejs/biome": "^1.5.3", @@ -166,8 +164,6 @@ "@types/semver": ["@types/semver@7.5.8", "", {}, "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ=="], - "@types/ws": ["@types/ws@8.5.11", "", { "dependencies": { "@types/node": "*" } }, "sha512-4+q7P5h3SpJxaBft0Dzpbr6lmMaqh0Jr2tbhJZ/luAwvD7ohSCniYkwz/pLxuT2h0EOa6QADgJj1Ko+TzRfZ+w=="], - "@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@7.16.1", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "7.16.1", "@typescript-eslint/type-utils": "7.16.1", "@typescript-eslint/utils": "7.16.1", "@typescript-eslint/visitor-keys": "7.16.1", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", "ts-api-utils": "^1.3.0" }, "peerDependencies": { "@typescript-eslint/parser": "^7.0.0", "eslint": "^8.56.0" } }, "sha512-SxdPak/5bO0EnGktV05+Hq8oatjAYVY3Zh2bye9pGZy6+jwyR3LG3YKkV4YatlsgqXP28BTeVm9pqwJM96vf2A=="], "@typescript-eslint/parser": ["@typescript-eslint/parser@7.16.1", "", { "dependencies": { "@typescript-eslint/scope-manager": "7.16.1", "@typescript-eslint/types": "7.16.1", "@typescript-eslint/typescript-estree": "7.16.1", "@typescript-eslint/visitor-keys": "7.16.1", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.56.0" } }, "sha512-u+1Qx86jfGQ5i4JjK33/FnawZRpsLxRnKzGE6EABZ40KxVT/vWsiZFEBBHjFOljmmV3MBYOHEKi0Jm9hbAOClA=="], @@ -916,8 +912,6 @@ "@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="], - "@types/ws/@types/node": ["@types/node@20.12.14", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-scnD59RpYD91xngrQQLGkE+6UrHUPzeKZWhhjBSa3HSkwjbQc38+q3RoIVEwxQGRw3M+j5hpNAM+lgV3cVormg=="], - "@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], "@typescript-eslint/visitor-keys/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="], @@ -1008,8 +1002,6 @@ "@definitelytyped/utils/which/isexe": ["isexe@3.1.1", "", {}, "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ=="], - "@types/ws/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], - "@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="], "are-we-there-yet/readable-stream/isarray": ["isarray@1.0.0", "", {}, "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="], diff --git a/cmake/Globals.cmake b/cmake/Globals.cmake index e9a74a1380..56e0a43544 100644 --- a/cmake/Globals.cmake +++ b/cmake/Globals.cmake @@ -423,7 +423,7 @@ function(register_command) # libbun-profile.a is now over 5gb in size, compress it first list(APPEND CMD_COMMANDS COMMAND ${CMAKE_COMMAND} -E chdir ${BUILD_PATH} rm -r ${BUILD_PATH}/codegen) list(APPEND CMD_COMMANDS COMMAND ${CMAKE_COMMAND} -E chdir ${BUILD_PATH} rm -r ${CACHE_PATH}) - list(APPEND CMD_COMMANDS COMMAND ${CMAKE_COMMAND} -E chdir ${BUILD_PATH} gzip -6 libbun-profile.a) + list(APPEND CMD_COMMANDS COMMAND ${CMAKE_COMMAND} -E chdir ${BUILD_PATH} gzip -1 libbun-profile.a) list(APPEND CMD_COMMANDS COMMAND ${CMAKE_COMMAND} -E chdir ${BUILD_PATH} buildkite-agent artifact upload libbun-profile.a.gz) else() list(APPEND CMD_COMMANDS COMMAND ${CMAKE_COMMAND} -E chdir ${BUILD_PATH} buildkite-agent artifact upload ${filename}) diff --git a/docs/api/redis.md b/docs/api/redis.md index 366541c133..929babb318 100644 --- a/docs/api/redis.md +++ b/docs/api/redis.md @@ -21,28 +21,6 @@ const exists = await redis.exists("greeting"); await redis.del("greeting"); ``` -{% features title="Features" %} - -{% icon size=20 name="Bolt" /%} Fast native implementation using Zig and JavaScriptCore - -{% icon size=20 name="Link" /%} Automatic pipelining for better performance - -{% icon size=20 name="EthernetPort" /%} Auto-reconnect with exponential backoff - -{% icon size=20 name="Omega" /%} Support for RESP3 protocol - -{% icon size=20 name="Lock" /%} TLS support - -{% icon size=20 name="Clock" /%} Connection management with configurable timeouts - -{% icon size=20 name="IndentDecrease" /%} Offline command queue - -{% icon size=20 name="Settings" /%} Automatic configuration with environment variables - -{% icon size=20 name="Hash" /%} Support for hash, set, and other Redis data structures - -{% /features %} - ## Getting Started To use the Redis client, you first need to create a connection: diff --git a/docs/project/bindgen.md b/docs/project/bindgen.md index 83ee48d63a..7952b497c7 100644 --- a/docs/project/bindgen.md +++ b/docs/project/bindgen.md @@ -32,7 +32,7 @@ pub fn add(global: *JSC.JSGlobalObject, a: i32, b: i32) !i32 { const gen = bun.gen.math; // "math" being this file's basename const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; ``` diff --git a/misctools/features.zig b/misctools/features.zig index 7bedbd042e..2a2f3be834 100644 --- a/misctools/features.zig +++ b/misctools/features.zig @@ -1,7 +1,7 @@ const std = @import("std"); const path_handler = @import("../src/resolver/resolve_path.zig"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/misctools/generate-add-completions.ts b/misctools/generate-add-completions.ts index 8605cae027..f9057de69e 100644 --- a/misctools/generate-add-completions.ts +++ b/misctools/generate-add-completions.ts @@ -98,7 +98,7 @@ chunks.push(`// Auto-generated file. Do not edit. // This used to be a comptime block, but it made the build too slow. // Compressing the completions list saves about 100 KB of binary size. const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const zstd = bun.zstd; const Environment = bun.Environment; diff --git a/misctools/http_bench.zig b/misctools/http_bench.zig index 3cd147d2ea..20d693e902 100644 --- a/misctools/http_bench.zig +++ b/misctools/http_bench.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/misctools/machbench.zig b/misctools/machbench.zig index 8a5f20d494..874f8a6c43 100644 --- a/misctools/machbench.zig +++ b/misctools/machbench.zig @@ -1,6 +1,6 @@ // most of this file is copy pasted from other files in misctools const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/misctools/readlink-getfd.zig b/misctools/readlink-getfd.zig index 4522fdc640..60edaaa5e6 100644 --- a/misctools/readlink-getfd.zig +++ b/misctools/readlink-getfd.zig @@ -1,7 +1,7 @@ const std = @import("std"); const path_handler = @import("../src/resolver/resolve_path.zig"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/misctools/readlink-realpath.zig b/misctools/readlink-realpath.zig index 827db30dc7..243b13af4b 100644 --- a/misctools/readlink-realpath.zig +++ b/misctools/readlink-realpath.zig @@ -1,7 +1,7 @@ const std = @import("std"); const path_handler = @import("../src/resolver/resolve_path.zig"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/misctools/tgz.zig b/misctools/tgz.zig index 6a3f9b5722..9ddfeeb2ca 100644 --- a/misctools/tgz.zig +++ b/misctools/tgz.zig @@ -1,7 +1,7 @@ const std = @import("std"); const path_handler = @import("../src/resolver/resolve_path.zig"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/package.json b/package.json index a260dbcf29..a0161a693f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "private": true, "name": "bun", - "version": "1.2.10", + "version": "1.2.11", "workspaces": [ "./packages/bun-types" ], diff --git a/packages/bun-types/bun.d.ts b/packages/bun-types/bun.d.ts index 1bbd646049..2b348dcc4a 100644 --- a/packages/bun-types/bun.d.ts +++ b/packages/bun-types/bun.d.ts @@ -27,7 +27,7 @@ declare module "bun" { | ReadableStreamDefaultReadValueResult | ReadableStreamDefaultReadDoneResult; type ReadableStreamReader = ReadableStreamDefaultReader; - type Transferable = ArrayBuffer | import("worker_threads").MessagePort; + type Transferable = ArrayBuffer | MessagePort; type MessageEventSource = Bun.__internal.UseLibDomIfAvailable<"MessageEventSource", undefined>; type Encoding = "utf-8" | "windows-1252" | "utf-16"; type UncaughtExceptionOrigin = "uncaughtException" | "unhandledRejection"; @@ -57,7 +57,7 @@ declare module "bun" { * * Uses the lib.dom.d.ts definition if it exists, otherwise defines it locally. * - * This is to avoid type conflicts between lib.dom.d.ts and @types/bun. + * This is to avoid type conflicts between lib.dom.d.ts and \@types/bun. * * Unfortunately some symbols cannot be defined when both Bun types and lib.dom.d.ts types are loaded, * and since we can't redeclare the symbol in a way that satisfies both, we need to fallback @@ -162,17 +162,6 @@ declare module "bun" { open: Event; } - interface EventInit { - bubbles?: boolean; - cancelable?: boolean; - composed?: boolean; - } - - interface EventListenerOptions { - /** Not directly used by Node.js. Added for API completeness. Default: `false`. */ - capture?: boolean; - } - interface AddEventListenerOptions extends EventListenerOptions { /** When `true`, the listener is automatically removed when it is first invoked. Default: `false`. */ once?: boolean; @@ -560,7 +549,6 @@ declare module "bun" { * * @returns The width of the string in columns * - * ## Examples * @example * ```ts * import { stringWidth } from "bun"; @@ -571,7 +559,6 @@ declare module "bun" { * console.log(stringWidth("\u001b[31mhello\u001b[39m", { countAnsiEscapeCodes: false })); // 5 * console.log(stringWidth("\u001b[31mhello\u001b[39m", { countAnsiEscapeCodes: true })); // 13 * ``` - * */ function stringWidth( /** @@ -594,7 +581,10 @@ declare module "bun" { }, ): number; - const TOML: { + /** + * TOML related APIs + */ + namespace TOML { /** * Parse a TOML string into a JavaScript object. * @@ -603,8 +593,8 @@ declare module "bun" { * @param input The TOML string to parse * @returns A JavaScript object */ - parse(input: string): object; - }; + export function parse(input: string): object; + } /** * Synchronously resolve a `moduleId` as though it were imported from `parent` @@ -866,8 +856,7 @@ declare module "bun" { * @param multipartBoundaryExcludingDashes Optional boundary to use for multipart form data. If none is provided, assumes it is a URLEncoded form. * @returns A promise that resolves with the data encoded into a {@link FormData} object. * - * ## Multipart form data example - * + * @example Multipart form data example * ```ts * // without dashes * const boundary = "WebKitFormBoundary" + Math.random().toString(16).slice(2); @@ -876,8 +865,8 @@ declare module "bun" { * const formData = await Bun.readableStreamToFormData(stream, boundary); * formData.get("foo"); // "bar" * ``` - * ## URL-encoded form data example * + * @example URL-encoded form data example * ```ts * const stream = new Response("hello=123").body; * const formData = await Bun.readableStreamToFormData(stream); @@ -1015,7 +1004,8 @@ declare module "bun" { end(): ArrayBuffer | Uint8Array; } - const dns: { + /** DNS Related APIs */ + namespace dns { /** * Lookup the IP address for a hostname * @@ -1060,7 +1050,7 @@ declare module "bun" { * console.log(address); // "19.42.52.62" * ``` */ - lookup( + function lookup( hostname: string, options?: { /** @@ -1129,12 +1119,12 @@ declare module "bun" { * await fetch('https://example.com'); * ``` */ - prefetch(hostname: string): void; + function prefetch(hostname: string): void; /** * **Experimental API** */ - getCacheStats(): { + function getCacheStats(): { /** * The number of times a cached DNS entry that was already resolved was used. */ @@ -1146,10 +1136,10 @@ declare module "bun" { totalCount: number; }; - ADDRCONFIG: number; - ALL: number; - V4MAPPED: number; - }; + const ADDRCONFIG: number; + const ALL: number; + const V4MAPPED: number; + } interface DNSLookup { /** @@ -1198,7 +1188,7 @@ declare module "bun" { * ``` */ interface BunFile extends Blob { - /**.p + /** * Offset any operation on the file starting at `begin` and ending at `end`. `end` is relative to 0 * * Similar to [`TypedArray.subarray`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/subarray). Does not copy the file, open the file, or modify the file. @@ -1211,7 +1201,6 @@ declare module "bun" { */ slice(begin?: number, end?: number, contentType?: string): BunFile; - /** */ /** * Offset any operation on the file starting at `begin` * @@ -1225,6 +1214,8 @@ declare module "bun" { slice(begin?: number, contentType?: string): BunFile; /** + * Slice the file from the beginning to the end, optionally with a new MIME type. + * * @param contentType - MIME type for the new BunFile */ slice(contentType?: string): BunFile; @@ -1285,7 +1276,7 @@ declare module "bun" { unlink(): Promise; /** - * Deletes the file. ( same as unlink ) + * Deletes the file (same as unlink) */ delete(): Promise; @@ -1682,22 +1673,6 @@ declare module "bun" { */ maxAge?: number; } - interface CSRF { - /** - * Generate a CSRF token. - * @param secret The secret to use for the token. If not provided, a random default secret will be generated in memory and used. - * @param options The options for the token. - * @returns The generated token. - */ - generate(secret?: string, options?: CSRFGenerateOptions): string; - /** - * Verify a CSRF token. - * @param token The token to verify. - * @param options The options for the token. - * @returns True if the token is valid, false otherwise. - */ - verify(token: string, options?: CSRFVerifyOptions): boolean; - } /** * SQL client @@ -1725,7 +1700,23 @@ declare module "bun" { * * @category Security */ - var CSRF: CSRF; + var CSRF: { + /** + * Generate a CSRF token. + * @param secret The secret to use for the token. If not provided, a random default secret will be generated in memory and used. + * @param options The options for the token. + * @returns The generated token. + */ + generate(secret?: string, options?: CSRFGenerateOptions): string; + + /** + * Verify a CSRF token. + * @param token The token to verify. + * @param options The options for the token. + * @returns True if the token is valid, false otherwise. + */ + verify(token: string, options?: CSRFVerifyOptions): boolean; + }; /** * This lets you use macros as regular imports @@ -2088,6 +2079,7 @@ declare module "bun" { * @see {@link publicPath} to customize the base url of linked source maps */ sourcemap?: "none" | "linked" | "inline" | "external" | "linked" | boolean; + /** * package.json `exports` conditions used when resolving imports * @@ -2116,6 +2108,7 @@ declare module "bun" { * ``` */ env?: "inline" | "disable" | `${string}*`; + /** * Whether to enable minification. * @@ -2131,16 +2124,19 @@ declare module "bun" { syntax?: boolean; identifiers?: boolean; }; + /** * Ignore dead code elimination/tree-shaking annotations such as @__PURE__ and package.json * "sideEffects" fields. This should only be used as a temporary workaround for incorrect * annotations in libraries. */ ignoreDCEAnnotations?: boolean; + /** * Force emitting @__PURE__ annotations even if minify.whitespace is true. */ emitDCEAnnotations?: boolean; + // treeshaking?: boolean; // jsx?: @@ -2167,10 +2163,12 @@ declare module "bun" { * @default false */ bytecode?: boolean; + /** * Add a banner to the bundled code such as "use client"; */ banner?: string; + /** * Add a footer to the bundled code such as a comment block like * @@ -2201,10 +2199,9 @@ declare module "bun" { * @category Security */ namespace Password { - type AlgorithmLabel = "bcrypt" | "argon2id" | "argon2d" | "argon2i"; - interface Argon2Algorithm { algorithm: "argon2id" | "argon2d" | "argon2i"; + /** * Memory cost, which defines the memory usage, given in kibibytes. */ @@ -2218,11 +2215,14 @@ declare module "bun" { interface BCryptAlgorithm { algorithm: "bcrypt"; + /** * A number between 4 and 31. The default is 10. */ cost?: number; } + + type AlgorithmLabel = (BCryptAlgorithm | Argon2Algorithm)["algorithm"]; } /** @@ -2233,7 +2233,7 @@ declare module "bun" { * @see [Bun.password API docs](https://bun.sh/guides/util/hash-a-password) * * The underlying implementation of these functions are provided by the Zig - * Standard Library. Thanks to @jedisct1 and other Zig contributors for their + * Standard Library. Thanks to \@jedisct1 and other Zig contributors for their * work on this. * * ### Example with argon2 @@ -2325,9 +2325,9 @@ declare module "bun" { */ password: Bun.StringOrBuffer, /** - * @default "argon2id" - * * When using bcrypt, passwords exceeding 72 characters will be SHA512'd before + * + * @default "argon2id" */ algorithm?: Password.AlgorithmLabel | Password.Argon2Algorithm | Password.BCryptAlgorithm, ): Promise; @@ -2338,7 +2338,7 @@ declare module "bun" { * instead which runs in a worker thread. * * The underlying implementation of these functions are provided by the Zig - * Standard Library. Thanks to @jedisct1 and other Zig contributors for their + * Standard Library. Thanks to \@jedisct1 and other Zig contributors for their * work on this. * * ### Example with argon2 @@ -2363,7 +2363,13 @@ declare module "bun" { * ``` */ verifySync( + /** + * The password to verify. + */ password: Bun.StringOrBuffer, + /** + * The hash to verify against. + */ hash: Bun.StringOrBuffer, /** * If not specified, the algorithm will be inferred from the hash. @@ -2377,7 +2383,7 @@ declare module "bun" { * instead which runs in a worker thread. * * The underlying implementation of these functions are provided by the Zig - * Standard Library. Thanks to @jedisct1 and other Zig contributors for their + * Standard Library. Thanks to \@jedisct1 and other Zig contributors for their * work on this. * * ### Example with argon2 @@ -2409,10 +2415,11 @@ declare module "bun" { * mistake to hash an empty password. */ password: Bun.StringOrBuffer, + /** - * @default "argon2id" - * * When using bcrypt, passwords exceeding 72 characters will be SHA256'd before + * + * @default "argon2id" */ algorithm?: Password.AlgorithmLabel | Password.Argon2Algorithm | Password.BCryptAlgorithm, ): string; @@ -4257,6 +4264,211 @@ declare module "bun" { compact?: boolean; } + type WebSocketOptionsProtocolsOrProtocol = + | { + /** + * Protocols to use for the WebSocket connection + */ + protocols?: string | string[]; + } + | { + /** + * Protocol to use for the WebSocket connection + */ + protocol?: string; + }; + + type WebSocketOptionsTLS = { + /** + * Options for the TLS connection + */ + tls?: { + /** + * Whether to reject the connection if the certificate is not valid + * + * @default true + */ + rejectUnauthorized?: boolean; + }; + }; + + type WebSocketOptionsHeaders = { + /** + * Headers to send to the server + */ + headers?: import("node:http").OutgoingHttpHeaders; + }; + + /** + * Constructor options for the `Bun.WebSocket` client + */ + type WebSocketOptions = WebSocketOptionsProtocolsOrProtocol & WebSocketOptionsTLS & WebSocketOptionsHeaders; + + interface WebSocketEventMap { + close: CloseEvent; + error: Event; + message: MessageEvent; + open: Event; + } + + /** + * A WebSocket client implementation + * + * @example + * ```ts + * const ws = new WebSocket("ws://localhost:8080", { + * headers: { + * "x-custom-header": "hello", + * }, + * }); + * + * ws.addEventListener("open", () => { + * console.log("Connected to server"); + * }); + * + * ws.addEventListener("message", (event) => { + * console.log("Received message:", event.data); + * }); + * + * ws.send("Hello, server!"); + * ws.terminate(); + * ``` + */ + interface WebSocket extends EventTarget { + /** + * The URL of the WebSocket connection + */ + readonly url: string; + + /** + * Legacy URL property (same as url) + * @deprecated Use url instead + */ + readonly URL: string; + + /** + * The current state of the connection + */ + readonly readyState: + | typeof WebSocket.CONNECTING + | typeof WebSocket.OPEN + | typeof WebSocket.CLOSING + | typeof WebSocket.CLOSED; + + /** + * The number of bytes of data that have been queued using send() but not yet transmitted to the network + */ + readonly bufferedAmount: number; + + /** + * The protocol selected by the server + */ + readonly protocol: string; + + /** + * The extensions selected by the server + */ + readonly extensions: string; + + /** + * The type of binary data being received. + */ + binaryType: "arraybuffer" | "nodebuffer"; + + /** + * Event handler for open event + */ + onopen: ((this: WebSocket, ev: Event) => any) | null; + + /** + * Event handler for message event + */ + onmessage: ((this: WebSocket, ev: MessageEvent) => any) | null; + + /** + * Event handler for error event + */ + onerror: ((this: WebSocket, ev: Event) => any) | null; + + /** + * Event handler for close event + */ + onclose: ((this: WebSocket, ev: CloseEvent) => any) | null; + + /** + * Transmits data to the server + * @param data The data to send to the server + */ + send(data: string | ArrayBufferLike | ArrayBufferView): void; + + /** + * Closes the WebSocket connection + * @param code A numeric value indicating the status code + * @param reason A human-readable string explaining why the connection is closing + */ + close(code?: number, reason?: string): void; + + /** + * Sends a ping frame to the server + * @param data Optional data to include in the ping frame + */ + ping(data?: string | ArrayBufferLike | ArrayBufferView): void; + + /** + * Sends a pong frame to the server + * @param data Optional data to include in the pong frame + */ + pong(data?: string | ArrayBufferLike | ArrayBufferView): void; + + /** + * Immediately terminates the connection + */ + terminate(): void; + + /** + * Registers an event handler of a specific event type on the WebSocket. + * @param type A case-sensitive string representing the event type to listen for + * @param listener The function to be called when the event occurs + * @param options An options object that specifies characteristics about the event listener + */ + addEventListener( + type: K, + listener: (this: WebSocket, ev: WebSocketEventMap[K]) => any, + options?: boolean | AddEventListenerOptions, + ): void; + addEventListener( + type: string, + listener: EventListenerOrEventListenerObject, + options?: boolean | AddEventListenerOptions, + ): void; + + /** + * Removes an event listener previously registered with addEventListener() + * @param type A case-sensitive string representing the event type to remove + * @param listener The function to remove from the event target + * @param options An options object that specifies characteristics about the event listener + */ + removeEventListener( + type: K, + listener: (this: WebSocket, ev: WebSocketEventMap[K]) => any, + options?: boolean | EventListenerOptions, + ): void; + removeEventListener( + type: string, + listener: EventListenerOrEventListenerObject, + options?: boolean | EventListenerOptions, + ): void; + + /** @deprecated Use instance property instead */ + readonly CONNECTING: 0; + /** @deprecated Use instance property instead */ + readonly OPEN: 1; + /** @deprecated Use instance property instead */ + readonly CLOSING: 2; + /** @deprecated Use instance property instead */ + readonly CLOSED: 3; + } + /** * Pretty-print an object the same as {@link console.log} to a `string` * @@ -5502,6 +5714,12 @@ declare module "bun" { */ shutdown(halfClose?: boolean): void; + // -1 = detached + // 0 = closed + // 1 = open + // -2 = closing + // 2 = everything else + // positive = open readonly readyState: "open" | "closing" | "closed"; /** @@ -5845,68 +6063,159 @@ declare module "bun" { } interface SocketOptions { + /** + * Handlers for socket events + */ socket: SocketHandler; + /** + * The per-instance data context + */ data?: Data; } - // interface TCPSocketOptions extends SocketOptions { - // hostname: string; - // port: number; - // } interface TCPSocketListenOptions extends SocketOptions { + /** + * The hostname to listen on + */ hostname: string; + /** + * The port to listen on + */ port: number; + /** + * The TLS configuration object with which to create the server + */ tls?: TLSOptions; + /** + * Whether to use exclusive mode. + * + * When set to `true`, the socket binds exclusively to the specified address:port + * combination, preventing other processes from binding to the same port. + * + * When `false` (default), other sockets may be able to bind to the same port + * depending on the operating system's socket sharing capabilities and settings. + * + * Exclusive mode is useful in scenarios where you want to ensure only one + * instance of your server can bind to a specific port at a time. + * + * @default false + */ exclusive?: boolean; + /** + * Whether to allow half-open connections. + * + * A half-open connection occurs when one end of the connection has called `close()` + * or sent a FIN packet, while the other end remains open. When set to `true`: + * + * - The socket won't automatically send FIN when the remote side closes its end + * - The local side can continue sending data even after the remote side has closed + * - The application must explicitly call `end()` to fully close the connection + * + * When `false` (default), the socket automatically closes both ends of the connection + * when either side closes. + * + * @default false + */ allowHalfOpen?: boolean; } interface TCPSocketConnectOptions extends SocketOptions { + /** + * The hostname to connect to + */ hostname: string; + /** + * The port to connect to + */ port: number; + /** + * TLS Configuration with which to create the socket + */ tls?: boolean; + /** + * Whether to use exclusive mode. + * + * When set to `true`, the socket binds exclusively to the specified address:port + * combination, preventing other processes from binding to the same port. + * + * When `false` (default), other sockets may be able to bind to the same port + * depending on the operating system's socket sharing capabilities and settings. + * + * Exclusive mode is useful in scenarios where you want to ensure only one + * instance of your server can bind to a specific port at a time. + * + * @default false + */ exclusive?: boolean; + /** + * Whether to allow half-open connections. + * + * A half-open connection occurs when one end of the connection has called `close()` + * or sent a FIN packet, while the other end remains open. When set to `true`: + * + * - The socket won't automatically send FIN when the remote side closes its end + * - The local side can continue sending data even after the remote side has closed + * - The application must explicitly call `end()` to fully close the connection + * + * When `false` (default), the socket automatically closes both ends of the connection + * when either side closes. + * + * @default false + */ allowHalfOpen?: boolean; } interface UnixSocketOptions extends SocketOptions { - tls?: TLSOptions; + /** + * The unix socket to listen on or connect to + */ unix: string; + /** + * TLS Configuration with which to create the socket + */ + tls?: TLSOptions; } interface FdSocketOptions extends SocketOptions { + /** + * TLS Configuration with which to create the socket + */ tls?: TLSOptions; + /** + * The file descriptor to connect to + */ fd: number; } /** - * Create a TCP client that connects to a server + * Create a TCP client that connects to a server via a TCP socket * - * @param options The options to use when creating the client - * @param options.socket The socket handler to use - * @param options.data The per-instance data context - * @param options.hostname The hostname to connect to - * @param options.port The port to connect to - * @param options.tls The TLS configuration object - * @param options.unix The unix socket to connect to + * @category HTTP & Networking */ function connect(options: TCPSocketConnectOptions): Promise>; + /** + * Create a TCP client that connects to a server via a unix socket + * + * @category HTTP & Networking + */ function connect(options: UnixSocketOptions): Promise>; /** * Create a TCP server that listens on a port * - * @param options The options to use when creating the server - * @param options.socket The socket handler to use - * @param options.data The per-instance data context - * @param options.hostname The hostname to connect to - * @param options.port The port to connect to - * @param options.tls The TLS configuration object - * @param options.unix The unix socket to connect to + * @category HTTP & Networking */ function listen(options: TCPSocketListenOptions): TCPSocketListener; + /** + * Create a TCP server that listens on a unix socket + * + * @category HTTP & Networking + */ function listen(options: UnixSocketOptions): UnixSocketListener; + /** + * @category HTTP & Networking + */ namespace udp { type Data = string | ArrayBufferView | ArrayBufferLike; @@ -5984,6 +6293,8 @@ declare module "bun" { * @param options.port The port to listen on * @param options.binaryType The binary type to use for the socket * @param options.connect The hostname and port to connect to + * + * @category HTTP & Networking */ export function udpSocket( options: udp.SocketOptions, @@ -7060,34 +7371,133 @@ declare module "bun" { type CookieSameSite = "strict" | "lax" | "none"; + /** + * A class for working with a single cookie + * + * @example + * ```js + * const cookie = new Bun.Cookie("name", "value"); + * console.log(cookie.toString()); // "name=value; Path=/; SameSite=Lax" + * ``` + */ class Cookie { + /** + * Create a new cookie + * @param name - The name of the cookie + * @param value - The value of the cookie + * @param options - Optional cookie attributes + */ constructor(name: string, value: string, options?: CookieInit); + + /** + * Create a new cookie from a cookie string + * @param cookieString - The cookie string + */ constructor(cookieString: string); + + /** + * Create a new cookie from a cookie object + * @param cookieObject - The cookie object + */ constructor(cookieObject?: CookieInit); + /** + * The name of the cookie + */ readonly name: string; + + /** + * The value of the cookie + */ value: string; + + /** + * The domain of the cookie + */ domain?: string; + + /** + * The path of the cookie + */ path: string; + + /** + * The expiration date of the cookie + */ expires?: Date; + + /** + * Whether the cookie is secure + */ secure: boolean; + + /** + * The same-site attribute of the cookie + */ sameSite: CookieSameSite; + + /** + * Whether the cookie is partitioned + */ partitioned: boolean; + + /** + * The maximum age of the cookie in seconds + */ maxAge?: number; + + /** + * Whether the cookie is HTTP-only + */ httpOnly: boolean; + /** + * Whether the cookie is expired + */ isExpired(): boolean; + /** + * Serialize the cookie to a string + * + * @example + * ```ts + * const cookie = Bun.Cookie.from("session", "abc123", { + * domain: "example.com", + * path: "/", + * secure: true, + * httpOnly: true + * }).serialize(); // "session=abc123; Domain=example.com; Path=/; Secure; HttpOnly; SameSite=Lax" + * ``` + */ serialize(): string; + + /** + * Serialize the cookie to a string + * + * Alias of {@link Cookie.serialize} + */ toString(): string; + + /** + * Serialize the cookie to a JSON object + */ toJSON(): CookieInit; + /** + * Parse a cookie string into a Cookie object + * @param cookieString - The cookie string + */ static parse(cookieString: string): Cookie; + + /** + * Create a new cookie from a name and value and optional options + */ static from(name: string, value: string, options?: CookieInit): Cookie; } /** * A Map-like interface for working with collections of cookies. + * * Implements the `Iterable` interface, allowing use with `for...of` loops. */ class CookieMap implements Iterable<[string, string]> { diff --git a/packages/bun-types/devserver.d.ts b/packages/bun-types/devserver.d.ts index 24879853f2..19e91d1852 100644 --- a/packages/bun-types/devserver.d.ts +++ b/packages/bun-types/devserver.d.ts @@ -46,8 +46,6 @@ interface ImportMeta { * * In production, `data` is inlined to be `{}`. This is handy because Bun * knows it can minify `{}.prop ??= value` into `value` in production. - * - * */ data: any; diff --git a/packages/bun-types/globals.d.ts b/packages/bun-types/globals.d.ts index 444889085c..a8702dfff4 100644 --- a/packages/bun-types/globals.d.ts +++ b/packages/bun-types/globals.d.ts @@ -3,16 +3,15 @@ declare module "bun" { type NodeWorkerThreadsWorker = import("node:worker_threads").Worker; type LibWorkerOrBunWorker = Bun.__internal.UseLibDomIfAvailable<"Worker", Bun.Worker>; - type NodePerfHooksPerformance = import("node:perf_hooks").Performance; type LibPerformanceOrNodePerfHooksPerformance = Bun.__internal.UseLibDomIfAvailable< "Performance", - NodePerfHooksPerformance + import("perf_hooks").Performance >; type NodeCryptoWebcryptoSubtleCrypto = import("crypto").webcrypto.SubtleCrypto; type NodeCryptoWebcryptoCryptoKey = import("crypto").webcrypto.CryptoKey; - type LibEmptyOrWSWebSocket = LibDomIsLoaded extends true ? {} : import("ws").WebSocket; + type LibEmptyOrBunWebSocket = LibDomIsLoaded extends true ? {} : Bun.WebSocket; type LibEmptyOrNodeUtilTextEncoder = LibDomIsLoaded extends true ? {} : import("node:util").TextEncoder; @@ -26,10 +25,6 @@ declare module "bun" { ? {} : import("node:stream/web").WritableStream; - type LibEmptyOrNodeTransformStream = LibDomIsLoaded extends true - ? {} - : import("node:stream/web").TransformStream; - type LibEmptyOrNodeMessagePort = LibDomIsLoaded extends true ? {} : import("node:worker_threads").MessagePort; } } @@ -68,15 +63,71 @@ declare var Worker: Bun.__internal.UseLibDomIfAvailable< } >; -interface WebSocket extends Bun.__internal.LibEmptyOrWSWebSocket {} +/** + * A WebSocket client implementation. + */ +interface WebSocket extends Bun.__internal.LibEmptyOrBunWebSocket {} /** * A WebSocket client implementation - * - * If `DOM` is included in tsconfig `lib`, this falls back to the default DOM global `WebSocket`. - * Otherwise (when outside of a browser environment), this will be the `WebSocket` - * implementation from the `ws` package, which Bun implements. */ -declare var WebSocket: Bun.__internal.UseLibDomIfAvailable<"WebSocket", typeof import("ws").WebSocket>; +declare var WebSocket: Bun.__internal.UseLibDomIfAvailable< + "WebSocket", + { + prototype: WebSocket; + + /** + * Creates a new WebSocket instance with the given URL and options. + * + * @param url The URL to connect to. + * @param options The options to use for the connection. + * + * @example + * ```ts + * const ws = new WebSocket("wss://dev.local", { + * protocols: ["proto1", "proto2"], + * headers: { + * "Cookie": "session=123456", + * }, + * }); + * ``` + */ + new (url: string | URL, options?: Bun.WebSocketOptions): WebSocket; + + /** + * Creates a new WebSocket instance with the given URL and protocols. + * + * @param url The URL to connect to. + * @param protocols The protocols to use for the connection. + * + * @example + * ```ts + * const ws = new WebSocket("wss://dev.local"); + * const ws = new WebSocket("wss://dev.local", ["proto1", "proto2"]); + * ``` + */ + new (url: string | URL, protocols?: string | string[]): WebSocket; + + /** + * The connection is not yet open + */ + readonly CONNECTING: 0; + + /** + * The connection is open and ready to communicate + */ + readonly OPEN: 1; + + /** + * The connection is in the process of closing + */ + readonly CLOSING: 2; + + /** + * The connection is closed or couldn't be opened + */ + readonly CLOSED: 3; + } +>; interface Crypto { readonly subtle: SubtleCrypto; @@ -225,26 +276,24 @@ interface File extends Blob { readonly lastModified: number; readonly name: string; } - -declare var File: typeof globalThis extends { onabort: any } - ? typeof globalThis extends { File: infer T } - ? T - : never - : { - prototype: File; - /** - * Create a new [File](https://developer.mozilla.org/en-US/docs/Web/API/File) - * - * @param `parts` - An array of strings, numbers, BufferSource, or [Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob) objects - * @param `name` - The name of the file - * @param `options` - An object containing properties to be added to the [File](https://developer.mozilla.org/en-US/docs/Web/API/File) - */ - new ( - parts: Bun.BlobPart[], - name: string, - options?: BlobPropertyBag & { lastModified?: Date | number | undefined }, - ): File; - }; +declare var File: Bun.__internal.UseLibDomIfAvailable< + "File", + { + prototype: File; + /** + * Create a new [File](https://developer.mozilla.org/en-US/docs/Web/API/File) + * + * @param `parts` - An array of strings, numbers, BufferSource, or [Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob) objects + * @param `name` - The name of the file + * @param `options` - An object containing properties to be added to the [File](https://developer.mozilla.org/en-US/docs/Web/API/File) + */ + new ( + parts: Bun.BlobPart[], + name: string, + options?: BlobPropertyBag & { lastModified?: Date | number | undefined }, + ): File; + } +>; /** * ShadowRealms are a distinct global environment, with its own global object @@ -1783,14 +1832,40 @@ interface BunFetchRequestInit extends RequestInit { /** * Override http_proxy or HTTPS_PROXY * This is a custom property that is not part of the Fetch API specification. + * + * @example + * ```js + * const response = await fetch("http://example.com", { + * proxy: "https://username:password@127.0.0.1:8080" + * }); + * ``` */ proxy?: string; /** * Override the default S3 options + * + * @example + * ```js + * const response = await fetch("s3://bucket/key", { + * s3: { + * accessKeyId: "AKIAIOSFODNN7EXAMPLE", + * secretAccessKey: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", + * region: "us-east-1", + * } + * }); + * ``` */ s3?: Bun.S3Options; + /** + * Make the request over a Unix socket + * + * @example + * ```js + * const response = await fetch("http://example.com", { unix: "/path/to/socket" }); + * ``` + */ unix?: string; } diff --git a/packages/bun-types/jsc.d.ts b/packages/bun-types/jsc.d.ts index 2a07534586..56128914e4 100644 --- a/packages/bun-types/jsc.d.ts +++ b/packages/bun-types/jsc.d.ts @@ -8,24 +8,8 @@ declare module "bun:jsc" { function fullGC(): number; function edenGC(): number; function heapSize(): number; - function heapStats(): { - heapSize: number; - heapCapacity: number; - extraMemorySize: number; - objectCount: number; - protectedObjectCount: number; - globalObjectCount: number; - protectedGlobalObjectCount: number; - objectTypeCounts: Record; - protectedObjectTypeCounts: Record; - }; - function memoryUsage(): { - current: number; - peak: number; - currentCommit: number; - peakCommit: number; - pageFaults: number; - }; + function heapStats(): HeapStats; + function memoryUsage(): MemoryUsage; function getRandomSeed(): number; function setRandomSeed(value: number): void; function isRope(input: string): boolean; @@ -78,6 +62,26 @@ declare module "bun:jsc" { */ function setTimeZone(timeZone: string): string; + interface HeapStats { + heapSize: number; + heapCapacity: number; + extraMemorySize: number; + objectCount: number; + protectedObjectCount: number; + globalObjectCount: number; + protectedGlobalObjectCount: number; + objectTypeCounts: Record; + protectedObjectTypeCounts: Record; + } + + interface MemoryUsage { + current: number; + peak: number; + currentCommit: number; + peakCommit: number; + pageFaults: number; + } + interface SamplingProfile { /** * A formatted summary of the top functions diff --git a/packages/bun-types/package.json b/packages/bun-types/package.json index e95f395985..6804292f4d 100644 --- a/packages/bun-types/package.json +++ b/packages/bun-types/package.json @@ -15,8 +15,7 @@ ], "homepage": "https://bun.sh", "dependencies": { - "@types/node": "*", - "@types/ws": "*" + "@types/node": "*" }, "devDependencies": { "@biomejs/biome": "^1.5.3", diff --git a/packages/bun-types/sqlite.d.ts b/packages/bun-types/sqlite.d.ts index 80d54006d1..3d38ba7960 100644 --- a/packages/bun-types/sqlite.d.ts +++ b/packages/bun-types/sqlite.d.ts @@ -13,15 +13,15 @@ * * The following types can be used when binding parameters: * - * | JavaScript type | SQLite type | - * | -------------- | ----------- | - * | `string` | `TEXT` | - * | `number` | `INTEGER` or `DECIMAL` | - * | `boolean` | `INTEGER` (1 or 0) | - * | `Uint8Array` | `BLOB` | - * | `Buffer` | `BLOB` | - * | `bigint` | `INTEGER` | - * | `null` | `NULL` | + * | JavaScript type | SQLite type | + * | --------------- | ---------------------- | + * | `string` | `TEXT` | + * | `number` | `INTEGER` or `DECIMAL` | + * | `boolean` | `INTEGER` (1 or 0) | + * | `Uint8Array` | `BLOB` | + * | `Buffer` | `BLOB` | + * | `bigint` | `INTEGER` | + * | `null` | `NULL` | */ declare module "bun:sqlite" { /** @@ -159,6 +159,20 @@ declare module "bun:sqlite" { * * This does not cache the query, so if you want to run a query multiple times, you should use {@link prepare} instead. * + * Under the hood, this calls `sqlite3_prepare_v3` followed by `sqlite3_step` and `sqlite3_finalize`. + * + * The following types can be used when binding parameters: + * + * | JavaScript type | SQLite type | + * | --------------- | ---------------------- | + * | `string` | `TEXT` | + * | `number` | `INTEGER` or `DECIMAL` | + * | `boolean` | `INTEGER` (1 or 0) | + * | `Uint8Array` | `BLOB` | + * | `Buffer` | `BLOB` | + * | `bigint` | `INTEGER` | + * | `null` | `NULL` | + * * @example * ```ts * db.run("CREATE TABLE foo (bar TEXT)"); @@ -184,30 +198,15 @@ declare module "bun:sqlite" { * - `CREATE TEMPORARY TABLE` * * @param sql The SQL query to run - * * @param bindings Optional bindings for the query * * @returns `Database` instance - * - * Under the hood, this calls `sqlite3_prepare_v3` followed by `sqlite3_step` and `sqlite3_finalize`. - * - * * The following types can be used when binding parameters: - * - * | JavaScript type | SQLite type | - * | -------------- | ----------- | - * | `string` | `TEXT` | - * | `number` | `INTEGER` or `DECIMAL` | - * | `boolean` | `INTEGER` (1 or 0) | - * | `Uint8Array` | `BLOB` | - * | `Buffer` | `BLOB` | - * | `bigint` | `INTEGER` | - * | `null` | `NULL` | */ - run(sqlQuery: string, ...bindings: ParamsType[]): Changes; + run(sql: string, ...bindings: ParamsType[]): Changes; /** - This is an alias of {@link Database.prototype.run} + * This is an alias of {@link Database.run} */ - exec(sqlQuery: string, ...bindings: ParamsType[]): Changes; + exec(sql: string, ...bindings: ParamsType[]): Changes; /** * Compile a SQL query and return a {@link Statement} object. This is the @@ -216,6 +215,8 @@ declare module "bun:sqlite" { * This **does not execute** the query, but instead prepares it for later * execution and caches the compiled query if possible. * + * Under the hood, this calls `sqlite3_prepare_v3`. + * * @example * ```ts * // compile the query @@ -228,21 +229,19 @@ declare module "bun:sqlite" { * ``` * * @param sql The SQL query to compile - * * @returns `Statment` instance - * - * Under the hood, this calls `sqlite3_prepare_v3`. */ query( - sqlQuery: string, - ): // eslint-disable-next-line @definitelytyped/no-single-element-tuple-type - Statement; + sql: string, + ): Statement; /** * Compile a SQL query and return a {@link Statement} object. * * This does not cache the compiled query and does not execute the query. * + * Under the hood, this calls `sqlite3_prepare_v3`. + * * @example * ```ts * // compile the query @@ -254,15 +253,12 @@ declare module "bun:sqlite" { * @param sql The SQL query to compile * @param params Optional bindings for the query * - * @returns `Statment` instance - * - * Under the hood, this calls `sqlite3_prepare_v3`. + * @returns A {@link Statement} instance */ prepare( - sqlQuery: string, + sql: string, params?: ParamsType, - ): // eslint-disable-next-line @definitelytyped/no-single-element-tuple-type - Statement; + ): Statement; /** * Is the database in a transaction? @@ -646,15 +642,15 @@ declare module "bun:sqlite" { * * The following types can be used when binding parameters: * - * | JavaScript type | SQLite type | - * | -------------- | ----------- | - * | `string` | `TEXT` | - * | `number` | `INTEGER` or `DECIMAL` | - * | `boolean` | `INTEGER` (1 or 0) | - * | `Uint8Array` | `BLOB` | - * | `Buffer` | `BLOB` | - * | `bigint` | `INTEGER` | - * | `null` | `NULL` | + * | JavaScript type | SQLite type | + * | --------------- | ---------------------- | + * | `string` | `TEXT` | + * | `number` | `INTEGER` or `DECIMAL` | + * | `boolean` | `INTEGER` (1 or 0) | + * | `Uint8Array` | `BLOB` | + * | `Buffer` | `BLOB` | + * | `bigint` | `INTEGER` | + * | `null` | `NULL` | */ get(...params: ParamsType): ReturnType | null; @@ -687,15 +683,15 @@ declare module "bun:sqlite" { * * The following types can be used when binding parameters: * - * | JavaScript type | SQLite type | - * | -------------- | ----------- | - * | `string` | `TEXT` | - * | `number` | `INTEGER` or `DECIMAL` | - * | `boolean` | `INTEGER` (1 or 0) | - * | `Uint8Array` | `BLOB` | - * | `Buffer` | `BLOB` | - * | `bigint` | `INTEGER` | - * | `null` | `NULL` | + * | JavaScript type | SQLite type | + * | --------------- | ---------------------- | + * | `string` | `TEXT` | + * | `number` | `INTEGER` or `DECIMAL` | + * | `boolean` | `INTEGER` (1 or 0) | + * | `Uint8Array` | `BLOB` | + * | `Buffer` | `BLOB` | + * | `bigint` | `INTEGER` | + * | `null` | `NULL` | */ run(...params: ParamsType): Changes; @@ -727,15 +723,15 @@ declare module "bun:sqlite" { * * The following types can be used when binding parameters: * - * | JavaScript type | SQLite type | - * | ---------------|-------------| - * | `string` | `TEXT` | - * | `number` | `INTEGER` or `DECIMAL` | - * | `boolean` | `INTEGER` (1 or 0) | - * | `Uint8Array` | `BLOB` | - * | `Buffer` | `BLOB` | - * | `bigint` | `INTEGER` | - * | `null` | `NULL` | + * | JavaScript type | SQLite type | + * | --------------- | ---------------------- | + * | `string` | `TEXT` | + * | `number` | `INTEGER` or `DECIMAL` | + * | `boolean` | `INTEGER` (1 or 0) | + * | `Uint8Array` | `BLOB` | + * | `Buffer` | `BLOB` | + * | `bigint` | `INTEGER` | + * | `null` | `NULL` | */ values(...params: ParamsType): Array>; diff --git a/packages/bun-types/test.d.ts b/packages/bun-types/test.d.ts index 5e77272b38..a3717b06be 100644 --- a/packages/bun-types/test.d.ts +++ b/packages/bun-types/test.d.ts @@ -426,8 +426,13 @@ declare module "bun:test" { * * @param label the label for the test * @param fn the test function + * @param options the test timeout or options */ - failing(label: string, fn?: (() => void | Promise) | ((done: (err?: unknown) => void) => void)): void; + failing( + label: string, + fn?: (() => void | Promise) | ((done: (err?: unknown) => void) => void), + options?: number | TestOptions, + ): void; /** * Runs this test, if `condition` is true. * diff --git a/src/Global.zig b/src/Global.zig index ba7521919d..221708b3bd 100644 --- a/src/Global.zig +++ b/src/Global.zig @@ -5,7 +5,7 @@ const Output = @import("output.zig"); const use_mimalloc = bun.use_mimalloc; const StringTypes = @import("./string_types.zig"); const Mimalloc = bun.Mimalloc; -const bun = @import("root").bun; +const bun = @import("bun"); const version_string = Environment.version_string; diff --git a/src/HTMLScanner.zig b/src/HTMLScanner.zig index ad93c49d0b..cf6036b315 100644 --- a/src/HTMLScanner.zig +++ b/src/HTMLScanner.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const ImportRecord = @import("./import_record.zig").ImportRecord; const ImportKind = @import("./import_record.zig").ImportKind; diff --git a/src/Mutex.zig b/src/Mutex.zig index 7ca748a64a..75d961b6bb 100644 --- a/src/Mutex.zig +++ b/src/Mutex.zig @@ -24,7 +24,7 @@ const std = @import("std"); const builtin = @import("builtin"); -const bun = @import("root").bun; +const bun = @import("bun"); const assert = bun.assert; const testing = std.testing; const Thread = std.Thread; diff --git a/src/OutputFile.zig b/src/OutputFile.zig index 22a30d06d1..c8a87cf6dc 100644 --- a/src/OutputFile.zig +++ b/src/OutputFile.zig @@ -46,10 +46,10 @@ pub const FileOperation = struct { close_handle_on_complete: bool = false, autowatch: bool = true, - pub fn fromFile(fd: anytype, pathname: string) FileOperation { + pub fn fromFile(fd: bun.FD, pathname: string) FileOperation { return .{ + .fd = fd, .pathname = pathname, - .fd = bun.toFD(fd), }; } @@ -166,7 +166,7 @@ pub fn initFile(file: std.fs.File, pathname: string, size: usize) OutputFile { pub fn initFileWithDir(file: std.fs.File, pathname: string, size: usize, dir: std.fs.Dir) OutputFile { var res = initFile(file, pathname, size); - res.value.copy.dir_handle = bun.toFD(dir.fd); + res.value.copy.dir_handle = .fromStdDir(dir); return res; } @@ -220,8 +220,8 @@ pub fn init(options: Options) OutputFile { .buffer => |buffer| Value{ .buffer = .{ .allocator = buffer.allocator, .bytes = buffer.data } }, .file => |file| Value{ .copy = brk: { - var op = FileOperation.fromFile(file.file.handle, options.output_path); - op.dir = bun.toFD(file.dir.fd); + var op = FileOperation.fromFile(.fromStdFile(file.file), options.output_path); + op.dir = .fromStdDir(file.dir); break :brk op; }, }, @@ -261,17 +261,17 @@ pub fn writeToDisk(f: OutputFile, root_dir: std.fs.Dir, root_dir_path: []const u } }, .encoding = .buffer, .mode = if (f.is_executable) 0o755 else 0o644, - .dirfd = bun.toFD(root_dir.fd), + .dirfd = .fromStdDir(root_dir), .file = .{ .path = .{ .string = JSC.PathString.init(rel_path), } }, }).unwrap(); }, .move => |value| { - try f.moveTo(root_dir_path, value.pathname, bun.toFD(root_dir.fd)); + try f.moveTo(root_dir_path, value.pathname, .fromStdDir(root_dir)); }, .copy => |value| { - try f.copyTo(root_dir_path, value.pathname, bun.toFD(root_dir.fd)); + try f.copyTo(root_dir_path, value.pathname, .fromStdDir(root_dir)); }, .pending => unreachable, } @@ -282,15 +282,11 @@ pub fn moveTo(file: *const OutputFile, _: string, rel_path: []const u8, dir: Fil } pub fn copyTo(file: *const OutputFile, _: string, rel_path: []const u8, dir: FileDescriptorType) !void { - const file_out = (try dir.asDir().createFile(rel_path, .{})); - - const fd_out = file_out.handle; + const fd_out = bun.FD.fromStdFile(try dir.stdDir().createFile(rel_path, .{})); var do_close = false; - const fd_in = (try std.fs.openFileAbsolute(file.src_path.text, .{ .mode = .read_only })).handle; + const fd_in = bun.FD.fromStdFile(try std.fs.openFileAbsolute(file.src_path.text, .{ .mode = .read_only })); if (Environment.isWindows) { - Fs.FileSystem.setMaxFd(fd_out); - Fs.FileSystem.setMaxFd(fd_in); do_close = Fs.FileSystem.instance.fs.needToCloseFiles(); // use paths instead of bun.getFdPathW() @@ -299,8 +295,8 @@ pub fn copyTo(file: *const OutputFile, _: string, rel_path: []const u8, dir: Fil defer { if (do_close) { - _ = bun.sys.close(bun.toFD(fd_out)); - _ = bun.sys.close(bun.toFD(fd_in)); + fd_out.close(); + fd_in.close(); } } @@ -317,7 +313,7 @@ pub fn toJS( .noop => JSC.JSValue.undefined, .copy => |copy| brk: { const file_blob = JSC.WebCore.Blob.Store.initFile( - if (copy.fd != .zero) + if (copy.fd.isValid()) JSC.Node.PathOrFileDescriptor{ .fd = copy.fd, } @@ -421,7 +417,7 @@ pub fn toBlob( .noop => @panic("Cannot convert noop output file to blob"), .copy => |copy| brk: { const file_blob = try JSC.WebCore.Blob.Store.initFile( - if (copy.fd != .zero) + if (copy.fd.isValid()) JSC.Node.PathOrFileDescriptor{ .fd = copy.fd, } @@ -487,7 +483,7 @@ const string = []const u8; const FileDescriptorType = bun.FileDescriptor; const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const Fs = bun.fs; const Loader = @import("./options.zig").Loader; diff --git a/src/Progress.zig b/src/Progress.zig index 9fbbe12a77..e1dd688148 100644 --- a/src/Progress.zig +++ b/src/Progress.zig @@ -20,7 +20,7 @@ const windows = std.os.windows; const testing = std.testing; const assert = bun.assert; const Progress = @This(); -const bun = @import("root").bun; +const bun = @import("bun"); /// `null` if the current node (and its children) should /// not print on update() diff --git a/src/StandaloneModuleGraph.zig b/src/StandaloneModuleGraph.zig index 779e48a288..4148c57793 100644 --- a/src/StandaloneModuleGraph.zig +++ b/src/StandaloneModuleGraph.zig @@ -1,7 +1,7 @@ //! Originally, we tried using LIEF to inject the module graph into a MachO segment //! But this incurred a fixed 350ms overhead on every build, which is unacceptable //! so we give up on codesigning support on macOS for now until we can find a better solution -const bun = @import("root").bun; +const bun = @import("bun"); const std = @import("std"); const Schema = bun.Schema.Api; const strings = bun.strings; @@ -486,7 +486,7 @@ pub const StandaloneModuleGraph = struct { // Make the file writable so we can delete it _ = Syscall.fchmod(fd, 0o777); } - _ = Syscall.close(fd); + fd.close(); _ = Syscall.unlink(name); } }.toClean; @@ -579,7 +579,7 @@ pub const StandaloneModuleGraph = struct { } unreachable; }; - const self_fd = brk2: { + const self_fd: bun.FileDescriptor = brk2: { for (0..3) |retry| { switch (Syscall.open(self_exe, bun.O.CLOEXEC | bun.O.RDONLY, 0)) { .result => |res| break :brk2 res, @@ -601,9 +601,9 @@ pub const StandaloneModuleGraph = struct { unreachable; }; - defer _ = Syscall.close(self_fd); + defer self_fd.close(); - bun.copyFile(self_fd.cast(), fd.cast()).unwrap() catch |err| { + bun.copyFile(self_fd, fd).unwrap() catch |err| { Output.prettyErrorln("error: failed to copy bun executable into temporary file: {s}", .{@errorName(err)}); cleanup(zname, fd); Global.exit(1); @@ -659,7 +659,7 @@ pub const StandaloneModuleGraph = struct { Global.exit(1); }; if (comptime !Environment.isWindows) { - _ = bun.C.fchmod(cloned_executable_fd.int(), 0o777); + _ = bun.C.fchmod(cloned_executable_fd.native(), 0o777); } return cloned_executable_fd; }, @@ -727,7 +727,7 @@ pub const StandaloneModuleGraph = struct { // the final 8 bytes in the file are the length of the module graph with padding, excluding the trailer and offsets _ = Syscall.write(cloned_executable_fd, std.mem.asBytes(&total_byte_count)); if (comptime !Environment.isWindows) { - _ = bun.C.fchmod(cloned_executable_fd.int(), 0o777); + _ = bun.C.fchmod(cloned_executable_fd.native(), 0o777); } return cloned_executable_fd; @@ -791,7 +791,7 @@ pub const StandaloneModuleGraph = struct { .{ .windows_hide_console = windows_hide_console }, target, ); - fd.assertKind(.system); + bun.debugAssert(fd.kind == .system); if (Environment.isWindows) { var outfile_buf: bun.OSPathBuffer = undefined; @@ -803,7 +803,7 @@ pub const StandaloneModuleGraph = struct { break :brk outfile_buf_u16[0..outfile_w.len :0]; }; - bun.C.moveOpenedFileAtLoose(fd, bun.toFD(root_dir.fd), outfile_slice, true).unwrap() catch |err| { + bun.C.moveOpenedFileAtLoose(fd, .fromStdDir(root_dir), outfile_slice, true).unwrap() catch |err| { if (err == error.EISDIR) { Output.errGeneric("{} is a directory. Please choose a different --outfile or delete the directory", .{bun.fmt.utf16(outfile_slice)}); } else { @@ -814,7 +814,7 @@ pub const StandaloneModuleGraph = struct { Global.exit(1); }; - _ = bun.sys.close(fd); + fd.close(); if (windows_icon) |icon_utf8| { var icon_buf: bun.OSPathBuffer = undefined; @@ -836,7 +836,7 @@ pub const StandaloneModuleGraph = struct { fd, bun.FD.cwd(), bun.sliceTo(&(try std.posix.toPosixPath(temp_location)), 0), - bun.toFD(root_dir.fd), + .fromStdDir(root_dir), bun.sliceTo(&(try std.posix.toPosixPath(std.fs.path.basename(outfile))), 0), ) catch |err| { if (err == error.IsDir) { @@ -871,7 +871,7 @@ pub const StandaloneModuleGraph = struct { // Do not invoke libuv here. const self_exe = openSelf() catch return null; - defer _ = Syscall.close(self_exe); + defer self_exe.close(); var trailer_bytes: [4096]u8 = undefined; std.posix.lseek_END(self_exe.cast(), -4096) catch return null; @@ -1010,7 +1010,7 @@ pub const StandaloneModuleGraph = struct { switch (Environment.os) { .linux => { if (std.fs.openFileAbsoluteZ("/proc/self/exe", .{})) |easymode| { - return bun.toFD(easymode.handle); + return .fromStdFile(easymode); } else |_| { if (bun.argv.len > 0) { // The user doesn't have /proc/ mounted, so now we just guess and hope for the best. @@ -1021,7 +1021,7 @@ pub const StandaloneModuleGraph = struct { "", bun.argv[0], )) |path| { - return bun.toFD((try std.fs.cwd().openFileZ(path, .{})).handle); + return .fromStdFile(try std.fs.cwd().openFileZ(path, .{})); } } @@ -1033,7 +1033,7 @@ pub const StandaloneModuleGraph = struct { // opened with no modification. const self_exe_path = try bun.selfExePath(); const file = try std.fs.openFileAbsoluteZ(self_exe_path.ptr, .{}); - return bun.toFD(file.handle); + return .fromStdFile(file); }, .windows => { const image_path_unicode_string = std.os.windows.peb().ProcessParameters.ImagePathName; @@ -1050,7 +1050,7 @@ pub const StandaloneModuleGraph = struct { } return bun.sys.openFileAtWindows( - bun.FileDescriptor.cwd(), + .cwd(), nt_path, .{ .access_mask = w.SYNCHRONIZE | w.GENERIC_READ, diff --git a/src/StaticHashMap.zig b/src/StaticHashMap.zig index e45a5823f7..31f6700ab8 100644 --- a/src/StaticHashMap.zig +++ b/src/StaticHashMap.zig @@ -6,7 +6,7 @@ const mem = std.mem; const math = std.math; const testing = std.testing; -const bun = @import("root").bun; +const bun = @import("bun"); const assert = bun.assert; pub fn AutoHashMap(comptime K: type, comptime V: type, comptime max_load_percentage: comptime_int) type { diff --git a/src/Watcher.zig b/src/Watcher.zig index 46c0a1c83d..1a04beafa2 100644 --- a/src/Watcher.zig +++ b/src/Watcher.zig @@ -111,7 +111,7 @@ pub fn deinit(this: *Watcher, close_descriptors: bool) void { if (close_descriptors and this.running) { const fds = this.watchlist.items(.fd); for (fds) |fd| { - _ = bun.sys.close(fd); + fd.close(); } } this.watchlist.deinit(this.allocator); @@ -236,7 +236,7 @@ fn threadMain(this: *Watcher) !void { if (this.close_descriptors) { const fds = this.watchlist.items(.fd); for (fds) |fd| { - _ = bun.sys.close(fd); + fd.close(); } } this.watchlist.deinit(this.allocator); @@ -271,7 +271,7 @@ pub fn flushEvictions(this: *Watcher) void { // on mac and linux we can just close the file descriptor // we don't need to call inotify_rm_watch on linux because it gets removed when the file descriptor is closed if (fds[item].isValid()) { - _ = bun.sys.close(fds[item]); + fds[item].close(); } } last_item = item; @@ -347,7 +347,7 @@ fn appendFileAssumeCapacity( event.fflags = std.c.NOTE.WRITE | std.c.NOTE.RENAME | std.c.NOTE.DELETE; // id - event.ident = @intCast(fd.int()); + event.ident = @intCast(fd.native()); // Store the hash for fast filtering later event.udata = @as(usize, @intCast(watchlist_id)); @@ -358,7 +358,7 @@ fn appendFileAssumeCapacity( // - We register the event here. // our while(true) loop above receives notification of changes to any of the events created here. _ = std.posix.system.kevent( - this.platform.fd.cast(), + this.platform.fd.unwrap().?.native(), @as([]KEvent, events[0..1]).ptr, 1, @as([]KEvent, events[0..1]).ptr, @@ -399,7 +399,7 @@ fn appendDirectoryAssumeCapacity( } const fd = brk: { - if (stored_fd != .zero) break :brk stored_fd; + if (stored_fd.isValid()) break :brk stored_fd; break :brk switch (bun.sys.openA(file_path, 0, 0)) { .err => |err| return .{ .err = err }, .result => |fd| fd, @@ -443,7 +443,7 @@ fn appendDirectoryAssumeCapacity( event.fflags = std.c.NOTE.WRITE | std.c.NOTE.RENAME | std.c.NOTE.DELETE; // id - event.ident = @intCast(fd.int()); + event.ident = @intCast(fd.native()); // Store the hash for fast filtering later event.udata = @as(usize, @intCast(watchlist_id)); @@ -454,7 +454,7 @@ fn appendDirectoryAssumeCapacity( // - We register the event here. // our while(true) loop above receives notification of changes to any of the events created here. _ = std.posix.system.kevent( - this.platform.fd.cast(), + this.platform.fd.unwrap().?.native(), @as([]KEvent, events[0..1]).ptr, 1, @as([]KEvent, events[0..1]).ptr, @@ -505,7 +505,7 @@ pub fn appendFileMaybeLock( if (autowatch_parent_dir) { var watchlist_slice = this.watchlist.slice(); - if (dir_fd != .zero) { + if (dir_fd.isValid()) { const fds = watchlist_slice.items(.fd); if (std.mem.indexOfScalar(bun.FileDescriptor, fds, dir_fd)) |i| { parent_watch_item = @as(WatchItemIndex, @truncate(i)); @@ -607,7 +607,7 @@ pub fn addFile( if (this.indexOf(hash)) |index| { if (comptime FeatureFlags.atomic_file_watcher) { // On Linux, the file descriptor might be out of date. - if (fd.int() > 0) { + if (fd.isValid()) { var fds = this.watchlist.items(.fd); fds[index] = fd; } @@ -665,7 +665,7 @@ pub fn onMaybeWatchDirectory(watch: *Watcher, file_path: string, dir_fd: bun.Sto } const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/src/allocators.zig b/src/allocators.zig index a6b7da8bbb..323754c800 100644 --- a/src/allocators.zig +++ b/src/allocators.zig @@ -3,7 +3,7 @@ const std = @import("std"); const FeatureFlags = @import("./feature_flags.zig"); const Environment = @import("./env.zig"); const FixedBufferAllocator = std.heap.FixedBufferAllocator; -const bun = @import("root").bun; +const bun = @import("bun"); const OOM = bun.OOM; pub fn isSliceInBufferT(comptime T: type, slice: []const T, buffer: []const T) bool { diff --git a/src/allocators/AllocationScope.zig b/src/allocators/AllocationScope.zig index 62d06f6d1e..91ccad5fda 100644 --- a/src/allocators/AllocationScope.zig +++ b/src/allocators/AllocationScope.zig @@ -237,6 +237,6 @@ pub inline fn downcast(a: Allocator) ?*AllocationScope { const std = @import("std"); const Allocator = std.mem.Allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const Output = bun.Output; const StoredTrace = bun.crash_handler.StoredTrace; diff --git a/src/allocators/NullableAllocator.zig b/src/allocators/NullableAllocator.zig index bb78e45e9d..c613f7e6ab 100644 --- a/src/allocators/NullableAllocator.zig +++ b/src/allocators/NullableAllocator.zig @@ -1,6 +1,6 @@ //! A nullable allocator the same size as `std.mem.Allocator`. const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const NullableAllocator = @This(); diff --git a/src/allocators/linux_memfd_allocator.zig b/src/allocators/linux_memfd_allocator.zig index dfff46427f..f3823a11a9 100644 --- a/src/allocators/linux_memfd_allocator.zig +++ b/src/allocators/linux_memfd_allocator.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const std = @import("std"); /// When cloning large amounts of data potentially multiple times, we can @@ -23,14 +23,14 @@ pub const LinuxMemFdAllocator = struct { pub const ref = RefCount.ref; pub const deref = RefCount.deref; - fd: bun.FileDescriptor = .zero, ref_count: RefCount, + fd: bun.FileDescriptor = .invalid, size: usize = 0, var memfd_counter = std.atomic.Value(usize).init(0); fn deinit(this: *LinuxMemFdAllocator) void { - _ = bun.sys.close(this.fd); + this.fd.close(); bun.destroy(this); } @@ -153,13 +153,13 @@ pub const LinuxMemFdAllocator = struct { } bun.Output.debugWarn("Failed to write to memfd: {}", .{err}); - _ = bun.sys.close(fd); + fd.close(); return .{ .err = err }; }, .result => |result| { if (result == 0) { bun.Output.debugWarn("Failed to write to memfd: EOF", .{}); - _ = bun.sys.close(fd); + fd.close(); return .{ .err = bun.sys.Error.fromCode(.NOMEM, .write) }; } written += @intCast(result); diff --git a/src/allocators/max_heap_allocator.zig b/src/allocators/max_heap_allocator.zig index 124a1acc55..01c463580d 100644 --- a/src/allocators/max_heap_allocator.zig +++ b/src/allocators/max_heap_allocator.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const std = @import("std"); /// Single allocation only. diff --git a/src/allocators/memory_allocator.zig b/src/allocators/memory_allocator.zig index 82b8170bc4..a6785c4f16 100644 --- a/src/allocators/memory_allocator.zig +++ b/src/allocators/memory_allocator.zig @@ -1,7 +1,7 @@ const mem = @import("std").mem; const builtin = @import("std").builtin; const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const log = bun.Output.scoped(.mimalloc, true); const assert = bun.assert; const Allocator = mem.Allocator; diff --git a/src/allocators/mimalloc_arena.zig b/src/allocators/mimalloc_arena.zig index 6fd0c532fd..d19a303830 100644 --- a/src/allocators/mimalloc_arena.zig +++ b/src/allocators/mimalloc_arena.zig @@ -7,7 +7,7 @@ const Environment = @import("../env.zig"); const FeatureFlags = @import("../feature_flags.zig"); const Allocator = mem.Allocator; const assert = bun.assert; -const bun = @import("root").bun; +const bun = @import("bun"); const log = bun.Output.scoped(.mimalloc, true); pub const Arena = struct { diff --git a/src/analytics/analytics_thread.zig b/src/analytics/analytics_thread.zig index ef07b5edc5..a876548c0f 100644 --- a/src/analytics/analytics_thread.zig +++ b/src/analytics/analytics_thread.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/src/api/schema.zig b/src/api/schema.zig index b569cc3dc3..cab9d1dee7 100644 --- a/src/api/schema.zig +++ b/src/api/schema.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const js_ast = bun.JSAst; const OOM = bun.OOM; diff --git a/src/ast/base.zig b/src/ast/base.zig index b1cc26244d..6bb0f8ff89 100644 --- a/src/ast/base.zig +++ b/src/ast/base.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const unicode = std.unicode; const js_ast = bun.JSAst; diff --git a/src/async/posix_event_loop.zig b/src/async/posix_event_loop.zig index 343843ca63..470830bf4f 100644 --- a/src/async/posix_event_loop.zig +++ b/src/async/posix_event_loop.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const Output = bun.Output; const JSC = bun.JSC; const uws = bun.uws; @@ -957,7 +957,7 @@ pub const FilePoll = struct { pub fn unregisterWithFd(this: *FilePoll, loop: *Loop, fd: bun.FileDescriptor, force_unregister: bool) JSC.Maybe(void) { if (Environment.allow_assert) { - bun.assert(fd.int() >= 0 and fd != bun.invalid_fd); + bun.assert(fd.native() >= 0 and fd != bun.invalid_fd); } defer this.deactivate(loop); @@ -1105,7 +1105,7 @@ pub const LinuxWaker = struct { fd: bun.FileDescriptor, pub fn init() !Waker { - return initWithFileDescriptor(bun.toFD(try std.posix.eventfd(0, 0))); + return initWithFileDescriptor(.fromNative(try std.posix.eventfd(0, 0))); } pub fn getFd(this: *const Waker) bun.FileDescriptor { @@ -1151,7 +1151,7 @@ pub const KEventWaker = struct { } pub fn getFd(this: *const Waker) bun.FileDescriptor { - return bun.toFD(this.kq); + return .fromNative(this.kq); } pub fn wait(this: Waker) void { @@ -1210,15 +1210,15 @@ pub const Closer = struct { pub fn close( fd: bun.FileDescriptor, /// for compatibility with windows version - _: anytype, + _: void, ) void { - bun.assert(fd != bun.invalid_fd); + bun.assert(fd.isValid()); JSC.WorkPool.schedule(&Closer.new(.{ .fd = fd }).task); } fn onClose(task: *JSC.WorkPoolTask) void { const closer: *Closer = @fieldParentPtr("task", task); defer bun.destroy(closer); - _ = bun.sys.close(closer.fd); + closer.fd.close(); } }; diff --git a/src/async/windows_event_loop.zig b/src/async/windows_event_loop.zig index ecb3b2c21a..302014c136 100644 --- a/src/async/windows_event_loop.zig +++ b/src/async/windows_event_loop.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const Output = bun.Output; const JSC = bun.JSC; const uws = bun.uws; @@ -190,7 +190,7 @@ pub const FilePoll = struct { // TODO(@paperclover): This cast is extremely suspicious. At best, `fd` is // the wrong type (it should be a uv handle), at worst this code is a // crash due to invalid memory access. - uv.uv_unref(@ptrFromInt(@intFromEnum(this.fd))); + uv.uv_unref(@ptrFromInt(@as(u64, @bitCast(this.fd)))); return true; } @@ -394,12 +394,11 @@ pub const Waker = struct { pub const Closer = struct { io_request: uv.fs_t, - pub fn close(fd: uv.uv_file, loop: *uv.Loop) void { + pub fn close(fd: bun.FileDescriptor, loop: *uv.Loop) void { const closer = bun.new(Closer, .{ .io_request = std.mem.zeroes(uv.fs_t) }); - // data is not overridden by libuv when calling uv_fs_close, its ok to set it here closer.io_request.data = closer; - if (uv.uv_fs_close(loop, &closer.io_request, fd, onClose).errEnum()) |err| { + if (uv.uv_fs_close(loop, &closer.io_request, fd.uv(), onClose).errEnum()) |err| { Output.debugWarn("libuv close() failed = {}", .{err}); bun.destroy(closer); } @@ -408,7 +407,7 @@ pub const Closer = struct { fn onClose(req: *uv.fs_t) callconv(.C) void { var closer: *Closer = @fieldParentPtr("io_request", req); bun.assert(closer == @as(*Closer, @alignCast(@ptrCast(req.data.?)))); - bun.sys.syslog("uv_fs_close({}) = {}", .{ bun.toFD(req.file.fd), req.result }); + bun.sys.syslog("uv_fs_close({}) = {}", .{ bun.FD.fromUV(req.file.fd), req.result }); if (comptime Environment.allow_assert) { if (closer.io_request.result.errEnum()) |err| { diff --git a/src/baby_list.zig b/src/baby_list.zig index bb491e6b90..4e95e7d9f2 100644 --- a/src/baby_list.zig +++ b/src/baby_list.zig @@ -1,7 +1,7 @@ const std = @import("std"); const Environment = @import("./env.zig"); const strings = @import("./string_immutable.zig"); -const bun = @import("root").bun; +const bun = @import("bun"); /// This is like ArrayList except it stores the length and capacity as u32 /// In practice, it is very unusual to have lengths above 4 GB diff --git a/src/bake/DevServer.zig b/src/bake/DevServer.zig index 95d68ea7cb..736fc56e85 100644 --- a/src/bake/DevServer.zig +++ b/src/bake/DevServer.zig @@ -5262,10 +5262,10 @@ const DirectoryWatchStore = struct { errdefer store.watches.swapRemoveAt(gop.index); // Try to use an existing open directory handle - const cache_fd = if (dev.server_transpiler.resolver.readDirInfo(dir_name_to_watch) catch null) |cache| fd: { - const fd = cache.getFileDescriptor(); - break :fd if (fd == .zero) null else fd; - } else null; + const cache_fd = if (dev.server_transpiler.resolver.readDirInfo(dir_name_to_watch) catch null) |cache| + cache.getFileDescriptor().unwrapValid() + else + null; const fd, const owned_fd = if (Watcher.requires_file_descriptors) if (cache_fd) |fd| .{ fd, false } @@ -5296,7 +5296,7 @@ const DirectoryWatchStore = struct { }, }, } else .{ bun.invalid_fd, false }; - errdefer _ = if (Watcher.requires_file_descriptors) if (owned_fd) bun.sys.close(fd); + errdefer if (Watcher.requires_file_descriptors) if (owned_fd) fd.close(); if (Watcher.requires_file_descriptors) debug.log("-> fd: {} ({s})", .{ fd, @@ -5351,7 +5351,7 @@ const DirectoryWatchStore = struct { store.owner().bun_watcher.removeAtIndex(entry.watch_index, 0, &.{}, .file); - defer _ = if (entry.dir_fd_owned) bun.sys.close(entry.dir); + defer if (entry.dir_fd_owned) entry.dir.close(); alloc.free(store.watches.keys()[entry_index]); store.watches.swapRemoveAt(entry_index); @@ -7603,7 +7603,7 @@ const Mutex = bun.Mutex; const ArrayListUnmanaged = std.ArrayListUnmanaged; const AutoArrayHashMapUnmanaged = std.AutoArrayHashMapUnmanaged; -const bun = @import("root").bun; +const bun = @import("bun"); const Environment = bun.Environment; const assert = bun.assert; const assert_eql = bun.assert_eql; diff --git a/src/bake/FrameworkRouter.zig b/src/bake/FrameworkRouter.zig index 00ada78cba..7a43987536 100644 --- a/src/bake/FrameworkRouter.zig +++ b/src/bake/FrameworkRouter.zig @@ -1080,9 +1080,9 @@ fn scanInner( /// production usage. It uses a slower but easier to use pattern for object /// creation. A production-grade JS api would be able to re-use objects. pub const JSFrameworkRouter = struct { - pub const codegen = JSC.Codegen.JSFrameworkFileSystemRouter; - pub const toJS = codegen.toJS; - pub const fromJS = codegen.fromJS; + pub const js = JSC.Codegen.JSFrameworkFileSystemRouter; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; files: std.ArrayListUnmanaged(bun.String), router: FrameworkRouter, @@ -1097,7 +1097,7 @@ pub const JSFrameworkRouter = struct { pub fn getBindings(global: *JSC.JSGlobalObject) JSC.JSValue { return JSC.JSObject.create(.{ .parseRoutePattern = global.createHostFunction("parseRoutePattern", parseRoutePattern, 1), - .FrameworkRouter = codegen.getConstructor(global), + .FrameworkRouter = js.getConstructor(global), }, global).toJS(); } @@ -1321,7 +1321,7 @@ const std = @import("std"); const mem = std.mem; const Allocator = mem.Allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const strings = bun.strings; const Resolver = bun.resolver.Resolver; const DirInfo = bun.resolver.DirInfo; diff --git a/src/bake/bake.zig b/src/bake/bake.zig index eec9f07262..4040543639 100644 --- a/src/bake/bake.zig +++ b/src/bake/bake.zig @@ -876,7 +876,7 @@ pub fn printWarning() void { const std = @import("std"); const Allocator = std.mem.Allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const Environment = bun.Environment; const JSC = bun.JSC; diff --git a/src/bake/production.zig b/src/bake/production.zig index fdec16e74f..f886753780 100644 --- a/src/bake/production.zig +++ b/src/bake/production.zig @@ -854,7 +854,7 @@ const TypeAndFlags = packed struct(i32) { const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Environment = bun.Environment; const Output = bun.Output; const OutputFile = bun.options.OutputFile; diff --git a/src/base64/base64.zig b/src/base64/base64.zig index 3b4a816b9f..cbf41186ff 100644 --- a/src/base64/base64.zig +++ b/src/base64/base64.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const mixed_decoder = brk: { var decoder = zig_base64.standard.decoderWithIgnore("\xff \t\r\n" ++ [_]u8{ diff --git a/src/bit_set.zig b/src/bit_set.zig index 88c499df5f..21c283a8b8 100644 --- a/src/bit_set.zig +++ b/src/bit_set.zig @@ -37,7 +37,7 @@ const std = @import("std"); const Allocator = std.mem.Allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const Environment = bun.Environment; /// Returns the optimal static bit set type for the specified number diff --git a/src/bitflags.zig b/src/bitflags.zig deleted file mode 100644 index 908179686a..0000000000 --- a/src/bitflags.zig +++ /dev/null @@ -1,116 +0,0 @@ -const std = @import("std"); - -pub fn Bitflags(comptime T: type) type { - const tyinfo = @typeInfo(T); - const IntType = tyinfo.@"struct".backing_integer.?; - const IntTypeInfo = @typeInfo(IntType); - const IntRepresentingNumOfBits = std.math.IntFittingRange(0, IntTypeInfo.int.bits); - - return struct { - pub const IMPL_BITFLAGS: u0 = 0; - - pub inline fn empty() T { - return @bitCast(@as(IntType, 0)); - } - - pub inline fn intersects(lhs: T, rhs: T) bool { - return asBits(lhs) & asBits(rhs) != 0; - } - - pub inline fn fromName(comptime name: []const u8) T { - var this: T = .{}; - @field(this, name) = true; - return this; - } - - pub inline fn fromNames(comptime names: []const []const u8) T { - var this: T = .{}; - inline for (names) |name| { - @field(this, name) = true; - } - return this; - } - - pub fn bitwiseOr(lhs: T, rhs: T) T { - return @bitCast(@as(IntType, @bitCast(lhs)) | @as(IntType, @bitCast(rhs))); - } - - pub fn bitwiseAnd(lhs: T, rhs: T) T { - return @bitCast(@as(IntType, asBits(lhs) & asBits(rhs))); - } - - pub inline fn intersect(lhs: T, rhs: T) T { - return bitwiseAnd(lhs, rhs); - } - - pub inline fn insert(this: *T, other: T) void { - this.* = bitwiseOr(this.*, other); - } - - pub inline fn remove(this: *T, other: T) void { - this.* = @bitCast(asBits(this.*) & ~asBits(other)); - } - - pub inline fn maskOut(this: T, other: T) T { - return @bitCast(asBits(this) & ~asBits(other)); - } - - pub fn contains(lhs: T, rhs: T) bool { - return @as(IntType, @bitCast(lhs)) & @as(IntType, @bitCast(rhs)) != 0; - } - - pub inline fn leadingZeroes(this: T) IntRepresentingNumOfBits { - return @clz(asBits(this)); - } - - pub inline fn all() T { - var ret: T = @bitCast(@as(IntType, 0)); - @setEvalBranchQuota(5000); - inline for (std.meta.fields(T)) |field| { - if (comptime !std.mem.eql(u8, field.name, "__unused")) { - @field(ret, field.name) = true; - } - } - return ret; - } - - pub inline fn not(this: T) T { - return fromBitsTruncate(~asBits(this)); - } - - pub inline fn difference(lhs: T, rhs: T) T { - // 1100 1100 1100 - // 1010 0101 0100 - return @bitCast(asBits(lhs) & asBits(not(rhs))); - } - - /// Convert from a bits value, unsetting any unknown bits. - pub inline fn fromBitsTruncate(bits: IntType) T { - return bitwiseAnd(@bitCast(bits), all()); - } - - pub inline fn asBits(this: T) IntType { - return @as(IntType, @bitCast(this)); - } - - pub fn isEmpty(this: T) bool { - return asBits(this) == 0; - } - - pub fn eq(lhs: T, rhs: T) bool { - return asBits(lhs) == asBits(rhs); - } - - pub fn eql(lhs: T, rhs: T) bool { - return eq(lhs, rhs); - } - - pub fn neq(lhs: T, rhs: T) bool { - return asBits(lhs) != asBits(rhs); - } - - pub fn hash(this: *const T, hasher: *std.hash.Wyhash) void { - hasher.update(std.mem.asBytes(this)); - } - }; -} diff --git a/src/bits.zig b/src/bits.zig new file mode 100644 index 0000000000..1ac2fdc97d --- /dev/null +++ b/src/bits.zig @@ -0,0 +1,60 @@ +//! Bitfield helper functions. T should be a packed struct of booleans. + +/// If the right side is known at compile time, you should just perform field accesses +/// +/// intersects(T, a, .{ .flag = true }) --> a.flag +/// +pub inline fn intersects(comptime T: type, lhs: T, rhs: T) bool { + return asInt(T, lhs) & asInt(T, rhs) != 0; +} + +pub inline fn @"and"(comptime T: type, lhs: T, rhs: T) T { + return fromInt(T, asInt(T, lhs) & asInt(T, rhs)); +} + +pub inline fn @"or"(comptime T: type, lhs: T, rhs: T) T { + return fromInt(T, asInt(T, lhs) | asInt(T, rhs)); +} + +pub inline fn invert(comptime T: type, value: T) T { + return fromInt(T, ~asInt(T, value)); +} + +/// Prefer a property assignment when possible +/// +/// insert(T, &a, .{ .flag = true }) --> a.flag = true; +/// +pub inline fn insert(comptime T: type, lhs: *T, rhs: T) void { + lhs.* = @"or"(T, lhs.*, rhs); +} + +pub inline fn contains(comptime T: type, lhs: T, rhs: T) bool { + return (asInt(T, lhs) & asInt(T, rhs)) != 0; +} + +pub inline fn maskOut(comptime T: type, lhs: *T, rhs: T) T { + return @"and"(T, lhs, invert(T, rhs)); +} + +pub inline fn remove(comptime T: type, lhs: *T, rhs: T) void { + lhs.* = @"and"(T, lhs.*, invert(T, rhs)); +} + +pub inline fn leadingZeros(comptime T: type, value: T) LeadingZerosInt(T) { + return @clz(asInt(T, value)); +} + +pub fn LeadingZerosInt(comptime T: type) type { + const backing_int = @typeInfo(T).@"struct".backing_integer.?; + return std.math.IntFittingRange(0, @typeInfo(backing_int).int.bits); +} + +pub inline fn fromInt(comptime T: type, bits: @typeInfo(T).@"struct".backing_integer.?) T { + return @bitCast(bits); +} + +pub inline fn asInt(comptime T: type, value: T) @typeInfo(T).@"struct".backing_integer.? { + return @bitCast(value); +} + +const std = @import("std"); diff --git a/src/boringssl.zig b/src/boringssl.zig index fe4c63e203..d74cacad3f 100644 --- a/src/boringssl.zig +++ b/src/boringssl.zig @@ -5,7 +5,7 @@ const boring = @import("./deps/boringssl.translated.zig"); pub const c = boring; const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const c_ares = @import("./deps/c_ares.zig"); const strings = bun.strings; const builtin = @import("builtin"); diff --git a/src/brotli.zig b/src/brotli.zig index 8cd6d0eba6..f6bf49b7a4 100644 --- a/src/brotli.zig +++ b/src/brotli.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const std = @import("std"); pub const c = struct { pub usingnamespace @import("./deps/brotli_decoder.zig"); diff --git a/src/btjs.zig b/src/btjs.zig index a222644145..07ff6fcd52 100644 --- a/src/btjs.zig +++ b/src/btjs.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); extern const jsc_llint_begin: u8; extern const jsc_llint_end: u8; diff --git a/src/bun.js/BuildMessage.zig b/src/bun.js/BuildMessage.zig index 64d21b80ca..71a014b6c7 100644 --- a/src/bun.js/BuildMessage.zig +++ b/src/bun.js/BuildMessage.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const logger = bun.logger; const std = @import("std"); const Fs = bun.fs; @@ -12,13 +12,16 @@ const ZigString = JSC.ZigString; const JSValue = JSC.JSValue; pub const BuildMessage = struct { + pub const js = JSC.Codegen.JSBuildMessage; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; + msg: logger.Msg, // resolve_result: Resolver.Result, allocator: std.mem.Allocator, logged: bool = false, - pub usingnamespace JSC.Codegen.JSBuildMessage; - pub fn constructor(globalThis: *JSC.JSGlobalObject, _: *JSC.CallFrame) bun.JSError!*BuildMessage { return globalThis.throw("BuildMessage is not constructable", .{}); } diff --git a/src/bun.js/ConsoleObject.zig b/src/bun.js/ConsoleObject.zig index a26b673496..d1dd76ea4b 100644 --- a/src/bun.js/ConsoleObject.zig +++ b/src/bun.js/ConsoleObject.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const Output = bun.Output; const ConsoleObject = @This(); @@ -1003,6 +1003,9 @@ pub const Formatter = struct { stack_check: bun.StackCheck = .{ .cached_stack_end = std.math.maxInt(usize) }, can_throw_stack_overflow: bool = false, error_display_level: FormatOptions.ErrorDisplayLevel = .full, + /// If ArrayBuffer-like objects contain ascii text, the buffer is printed as a string. + /// Set true in the error printer so that ShellError prints a more readable message. + format_buffer_as_text: bool = false, pub fn deinit(this: *Formatter) void { if (bun.take(&this.map_node)) |node| { @@ -3342,6 +3345,17 @@ pub const Formatter = struct { const arrayBuffer = value.asArrayBuffer(this.globalThis).?; const slice = arrayBuffer.byteSlice(); + if (this.format_buffer_as_text and jsType == .Uint8Array and bun.strings.isValidUTF8(slice)) { + if (comptime enable_ansi_colors) { + writer.writeAll(Output.prettyFmt("", true)); + } + JSPrinter.writeJSONString(slice, Writer, writer_, .utf8) catch {}; + if (comptime enable_ansi_colors) { + writer.writeAll(Output.prettyFmt("", true)); + } + return; + } + writer.writeAll( if (arrayBuffer.typed_array_type == .Uint8Array and arrayBuffer.value.isBuffer(this.globalThis)) @@ -3353,6 +3367,7 @@ pub const Formatter = struct { writer.print("({d}) []", .{arrayBuffer.len}); return; } + writer.print("({d}) [ ", .{arrayBuffer.len}); switch (jsType) { diff --git a/src/bun.js/ResolveMessage.zig b/src/bun.js/ResolveMessage.zig index bcbb5c70a9..5d1ca78266 100644 --- a/src/bun.js/ResolveMessage.zig +++ b/src/bun.js/ResolveMessage.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const logger = bun.logger; const std = @import("std"); const Fs = bun.fs; @@ -11,13 +11,16 @@ const default_allocator = bun.default_allocator; const ZigString = JSC.ZigString; pub const ResolveMessage = struct { + pub const js = JSC.Codegen.JSResolveMessage; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; + msg: logger.Msg, allocator: std.mem.Allocator, referrer: ?Fs.Path = null, logged: bool = false, - pub usingnamespace JSC.Codegen.JSResolveMessage; - pub fn constructor(globalThis: *JSC.JSGlobalObject, _: *JSC.CallFrame) bun.JSError!*ResolveMessage { return globalThis.throw("ResolveMessage is not constructable", .{}); } diff --git a/src/bun.js/RuntimeTranspilerCache.zig b/src/bun.js/RuntimeTranspilerCache.zig index 22d93515e2..048a37fef2 100644 --- a/src/bun.js/RuntimeTranspilerCache.zig +++ b/src/bun.js/RuntimeTranspilerCache.zig @@ -12,7 +12,7 @@ /// Version 13: Hoist `import.meta.require` definition, see #15738 const expected_version = 13; -const bun = @import("root").bun; +const bun = @import("bun"); const std = @import("std"); const Output = bun.Output; const JSC = bun.JSC; @@ -172,7 +172,7 @@ pub const RuntimeTranspilerCache = struct { // First we open the tmpfile, to avoid any other work in the event of failure. var tmpfile = try bun.Tmpfile.create(destination_dir, tmpfilename).unwrap(); defer { - _ = bun.sys.close(tmpfile.fd); + tmpfile.fd.close(); } { errdefer { @@ -483,13 +483,13 @@ pub const RuntimeTranspilerCache = struct { ) !Entry { var metadata_bytes_buf: [Metadata.size * 2]u8 = undefined; const cache_fd = try bun.sys.open(cache_file_path.sliceAssumeZ(), bun.O.RDONLY, 0).unwrap(); - defer _ = bun.sys.close(cache_fd); + defer cache_fd.close(); errdefer { // On any error, we delete the cache file _ = bun.sys.unlink(cache_file_path.sliceAssumeZ()); } - const file = cache_fd.asFile(); + const file = cache_fd.stdFile(); const metadata_bytes = try file.preadAll(&metadata_bytes_buf, 0); if (comptime bun.Environment.isWindows) try file.seekTo(0); var metadata_stream = std.io.fixedBufferStream(metadata_bytes_buf[0..metadata_bytes]); @@ -551,13 +551,13 @@ pub const RuntimeTranspilerCache = struct { if (std.fs.path.dirname(cache_file_path)) |dirname| { var dir = try std.fs.cwd().makeOpenPath(dirname, .{ .access_sub_paths = true }); errdefer dir.close(); - break :brk try bun.toLibUVOwnedFD(dir.fd); + break :brk try bun.FD.fromStdDir(dir).makeLibUVOwned(); } break :brk bun.FD.cwd(); }; defer { - if (cache_dir_fd != bun.FD.cwd()) _ = bun.sys.close(cache_dir_fd); + if (cache_dir_fd != bun.FD.cwd()) cache_dir_fd.close(); } try Entry.save( diff --git a/src/bun.js/Strong.zig b/src/bun.js/Strong.zig index 5c6b5a66fa..8912f892ee 100644 --- a/src/bun.js/Strong.zig +++ b/src/bun.js/Strong.zig @@ -107,5 +107,5 @@ const Impl = opaque { extern fn Bun__StrongRef__clear(this: *Impl) void; }; -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; diff --git a/src/bun.js/Weak.zig b/src/bun.js/Weak.zig index c8e724f11a..8adc71e2a6 100644 --- a/src/bun.js/Weak.zig +++ b/src/bun.js/Weak.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; pub const WeakRefType = enum(u32) { diff --git a/src/bun.js/api/BunObject.zig b/src/bun.js/api/BunObject.zig index 1bcec556f8..427f5c994b 100644 --- a/src/bun.js/api/BunObject.zig +++ b/src/bun.js/api/BunObject.zig @@ -595,7 +595,7 @@ pub fn getMain(globalThis: *JSC.JSGlobalObject, _: *JSC.JSObject) JSC.JSValue { 0, ).unwrap() catch break :use_resolved_path; - defer _ = bun.sys.close(fd); + defer fd.close(); if (comptime Environment.isWindows) { var wpath: bun.WPathBuffer = undefined; const fdpath = bun.getFdPathW(fd, &wpath) catch break :use_resolved_path; @@ -625,7 +625,7 @@ pub fn getArgv(globalThis: *JSC.JSGlobalObject, _: *JSC.JSObject) JSC.JSValue { const Editor = @import("../../open.zig").Editor; -pub fn openInEditor(globalThis: js.JSContextRef, callframe: *JSC.CallFrame) bun.JSError!JSValue { +pub fn openInEditor(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) bun.JSError!JSValue { var edit = &VirtualMachine.get().rareData().editor_context; const args = callframe.arguments_old(4); var arguments = JSC.Node.ArgumentsSlice.init(globalThis.bunVM(), args.slice()); @@ -818,7 +818,7 @@ fn doResolve(globalThis: *JSC.JSGlobalObject, arguments: []const JSValue) bun.JS ); } -fn doResolveWithArgs(ctx: js.JSContextRef, specifier: bun.String, from: bun.String, is_esm: bool, comptime is_file_path: bool, is_user_require_resolve: bool) bun.JSError!JSC.JSValue { +fn doResolveWithArgs(ctx: *JSC.JSGlobalObject, specifier: bun.String, from: bun.String, is_esm: bool, comptime is_file_path: bool, is_user_require_resolve: bool) bun.JSError!JSC.JSValue { var errorable: ErrorableString = undefined; var query_string = ZigString.Empty; @@ -1242,11 +1242,11 @@ pub fn mmapFile(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) bun. } pub fn getTranspilerConstructor(globalThis: *JSC.JSGlobalObject, _: *JSC.JSObject) JSC.JSValue { - return JSC.API.JSTranspiler.getConstructor(globalThis); + return JSC.API.JSTranspiler.js.getConstructor(globalThis); } pub fn getFileSystemRouter(globalThis: *JSC.JSGlobalObject, _: *JSC.JSObject) JSC.JSValue { - return JSC.API.FileSystemRouter.getConstructor(globalThis); + return JSC.API.FileSystemRouter.js.getConstructor(globalThis); } pub fn getHashObject(globalThis: *JSC.JSGlobalObject, _: *JSC.JSObject) JSC.JSValue { @@ -1258,10 +1258,10 @@ pub fn getTOMLObject(globalThis: *JSC.JSGlobalObject, _: *JSC.JSObject) JSC.JSVa } pub fn getGlobConstructor(globalThis: *JSC.JSGlobalObject, _: *JSC.JSObject) JSC.JSValue { - return JSC.API.Glob.getConstructor(globalThis); + return JSC.API.Glob.js.getConstructor(globalThis); } pub fn getS3ClientConstructor(globalThis: *JSC.JSGlobalObject, _: *JSC.JSObject) JSC.JSValue { - return JSC.WebCore.S3Client.getConstructor(globalThis); + return JSC.WebCore.S3Client.js.getConstructor(globalThis); } pub fn getS3DefaultClient(globalThis: *JSC.JSGlobalObject, _: *JSC.JSObject) JSC.JSValue { @@ -1281,7 +1281,7 @@ pub fn getValkeyDefaultClient(globalThis: *JSC.JSGlobalObject, _: *JSC.JSObject) } pub fn getValkeyClientConstructor(globalThis: *JSC.JSGlobalObject, _: *JSC.JSObject) JSC.JSValue { - return JSC.API.Valkey.getConstructor(globalThis); + return JSC.API.Valkey.js.getConstructor(globalThis); } pub fn getEmbeddedFiles(globalThis: *JSC.JSGlobalObject, _: *JSC.JSObject) JSC.JSValue { @@ -1755,7 +1755,7 @@ const conv = std.builtin.CallingConvention.Unspecified; const S3File = @import("../webcore/S3File.zig"); const Bun = @This(); const default_allocator = bun.default_allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const uv = bun.windows.libuv; const Environment = bun.Environment; const Global = bun.Global; @@ -1793,7 +1793,6 @@ const Request = WebCore.Request; const Response = WebCore.Response; const Headers = WebCore.Headers; const Fetch = WebCore.Fetch; -const js = bun.JSC.C; const JSC = bun.JSC; const JSError = @import("../base.zig").JSError; @@ -1802,7 +1801,6 @@ const getAllocator = @import("../base.zig").getAllocator; const JSValue = bun.JSC.JSValue; const JSGlobalObject = bun.JSC.JSGlobalObject; -const ExceptionValueRef = bun.JSC.ExceptionValueRef; const JSPrivateDataPtr = bun.JSC.JSPrivateDataPtr; const ConsoleObject = bun.JSC.ConsoleObject; const Node = bun.JSC.Node; diff --git a/src/bun.js/api/FFIObject.zig b/src/bun.js/api/FFIObject.zig index a225e6e33d..04755067b3 100644 --- a/src/bun.js/api/FFIObject.zig +++ b/src/bun.js/api/FFIObject.zig @@ -628,7 +628,7 @@ const JSGlobalObject = JSC.JSGlobalObject; const JSObject = JSC.JSObject; const JSValue = JSC.JSValue; const JSC = bun.JSC; -const bun = @import("root").bun; +const bun = @import("bun"); const FFIObject = @This(); const Bun = JSC.API.Bun; diff --git a/src/bun.js/api/HashObject.zig b/src/bun.js/api/HashObject.zig index 6dc1567879..8b86258806 100644 --- a/src/bun.js/api/HashObject.zig +++ b/src/bun.js/api/HashObject.zig @@ -140,5 +140,5 @@ const JSValue = JSC.JSValue; const JSGlobalObject = JSC.JSGlobalObject; const JSObject = JSC.JSObject; const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const ZigString = JSC.ZigString; diff --git a/src/bun.js/api/JSBundler.zig b/src/bun.js/api/JSBundler.zig index ebf5b15dd7..53a7c9923f 100644 --- a/src/bun.js/api/JSBundler.zig +++ b/src/bun.js/api/JSBundler.zig @@ -2,10 +2,9 @@ const std = @import("std"); const Api = @import("../../api/schema.zig").Api; const QueryStringMap = @import("../../url.zig").QueryStringMap; const CombinedScanner = @import("../../url.zig").CombinedScanner; -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const JSC = bun.JSC; -const js = JSC.C; const WebCore = @import("../webcore/response.zig"); const Transpiler = bun.transpiler; const options = @import("../../options.zig"); @@ -341,13 +340,13 @@ pub const JSBundler = struct { defer path.deinit(); - var dir = std.fs.cwd().openDir(path.slice(), .{}) catch |err| { + var dir = bun.FD.fromStdDir(std.fs.cwd().openDir(path.slice(), .{}) catch |err| { return globalThis.throwPretty("{s}: failed to open root directory: {s}", .{ @errorName(err), path.slice() }); - }; + }); defer dir.close(); var rootdir_buf: bun.PathBuffer = undefined; - const rootdir = bun.getFdPath(bun.toFD(dir.fd), &rootdir_buf) catch |err| { + const rootdir = dir.getFdPath(&rootdir_buf) catch |err| { return globalThis.throwPretty("{s}: failed to get full root directory path: {s}", .{ @errorName(err), path.slice() }); }; try this.rootdir.appendSliceExact(rootdir); @@ -1090,7 +1089,10 @@ pub const JSBundler = struct { const Blob = JSC.WebCore.Blob; pub const BuildArtifact = struct { - pub usingnamespace JSC.Codegen.JSBuildArtifact; + pub const js = JSC.Codegen.JSBuildArtifact; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; blob: JSC.WebCore.Blob, loader: options.Loader = .file, diff --git a/src/bun.js/api/JSTranspiler.zig b/src/bun.js/api/JSTranspiler.zig index 7332f95548..7f665b6e8b 100644 --- a/src/bun.js/api/JSTranspiler.zig +++ b/src/bun.js/api/JSTranspiler.zig @@ -2,10 +2,9 @@ const std = @import("std"); const Api = @import("../../api/schema.zig").Api; const QueryStringMap = @import("../../url.zig").QueryStringMap; const CombinedScanner = @import("../../url.zig").CombinedScanner; -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const JSC = bun.JSC; -const js = JSC.C; const WebCore = @import("../webcore/response.zig"); const Transpiler = bun.transpiler; const options = @import("../../options.zig"); @@ -40,7 +39,10 @@ const JSLexer = bun.js_lexer; const Expr = JSAst.Expr; const JSTranspiler = @This(); -pub usingnamespace JSC.Codegen.JSTranspiler; +pub const js = JSC.Codegen.JSTranspiler; +pub const toJS = js.toJS; +pub const fromJS = js.fromJS; +pub const fromJSDirect = js.fromJSDirect; transpiler: bun.transpiler.Transpiler, arena: bun.ArenaAllocator, @@ -159,7 +161,7 @@ pub const TransformTask = struct { const parse_options = Transpiler.Transpiler.ParseOptions{ .allocator = allocator, .macro_remappings = this.macro_map, - .dirname_fd = .zero, + .dirname_fd = .invalid, .file_descriptor = null, .loader = this.loader, .jsx = jsx, @@ -304,7 +306,7 @@ fn exportReplacementValue(value: JSValue, globalThis: *JSGlobalObject) bun.JSErr return null; } -fn transformOptionsFromJSC(globalObject: JSC.C.JSContextRef, temp_allocator: std.mem.Allocator, args: *JSC.Node.ArgumentsSlice) (bun.JSError || bun.OOM)!TranspilerOptions { +fn transformOptionsFromJSC(globalObject: *JSC.JSGlobalObject, temp_allocator: std.mem.Allocator, args: *JSC.Node.ArgumentsSlice) (bun.JSError || bun.OOM)!TranspilerOptions { const globalThis = globalObject; const object = args.next() orelse return TranspilerOptions{ .log = logger.Log.init(temp_allocator) }; if (object.isUndefinedOrNull()) return TranspilerOptions{ .log = logger.Log.init(temp_allocator) }; @@ -807,7 +809,7 @@ fn getParseResult(this: *JSTranspiler, allocator: std.mem.Allocator, code: []con const parse_options = Transpiler.Transpiler.ParseOptions{ .allocator = allocator, .macro_remappings = this.transpiler_options.macro_map, - .dirname_fd = .zero, + .dirname_fd = .invalid, .file_descriptor = null, .loader = loader orelse this.transpiler_options.default_loader, .jsx = jsx, diff --git a/src/bun.js/api/TOMLObject.zig b/src/bun.js/api/TOMLObject.zig index ea51e33eb4..8323880bfe 100644 --- a/src/bun.js/api/TOMLObject.zig +++ b/src/bun.js/api/TOMLObject.zig @@ -64,7 +64,7 @@ const JSObject = JSC.JSObject; const std = @import("std"); const ZigString = JSC.ZigString; const logger = bun.logger; -const bun = @import("root").bun; +const bun = @import("bun"); const js_printer = bun.js_printer; const default_allocator = bun.default_allocator; const TOMLParser = @import("../../toml/toml_parser.zig").TOML; diff --git a/src/bun.js/api/Timer.zig b/src/bun.js/api/Timer.zig index 2c572940ca..43e32b8d51 100644 --- a/src/bun.js/api/Timer.zig +++ b/src/bun.js/api/Timer.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const VirtualMachine = JSC.VirtualMachine; const JSValue = JSC.JSValue; @@ -565,7 +565,10 @@ pub const TimeoutObject = struct { pub const ref = RefCount.ref; pub const deref = RefCount.deref; - pub usingnamespace JSC.Codegen.JSTimeout; + pub const js = JSC.Codegen.JSTimeout; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; ref_count: RefCount, event_loop_timer: EventLoopTimer = .{ @@ -584,10 +587,10 @@ pub const TimeoutObject = struct { ) JSValue { // internals are initialized by init() const timeout = bun.new(TimeoutObject, .{ .ref_count = .init(), .internals = undefined }); - const js = timeout.toJS(globalThis); - defer js.ensureStillAlive(); + const js_value = timeout.toJS(globalThis); + defer js_value.ensureStillAlive(); timeout.internals.init( - js, + js_value, globalThis, id, kind, @@ -595,7 +598,7 @@ pub const TimeoutObject = struct { callback, arguments_array_or_zero, ); - return js; + return js_value; } fn deinit(this: *TimeoutObject) void { @@ -654,7 +657,10 @@ pub const ImmediateObject = struct { pub const ref = RefCount.ref; pub const deref = RefCount.deref; - pub usingnamespace JSC.Codegen.JSImmediate; + pub const js = JSC.Codegen.JSImmediate; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; ref_count: RefCount, event_loop_timer: EventLoopTimer = .{ @@ -671,10 +677,10 @@ pub const ImmediateObject = struct { ) JSValue { // internals are initialized by init() const immediate = bun.new(ImmediateObject, .{ .ref_count = .init(), .internals = undefined }); - const js = immediate.toJS(globalThis); - defer js.ensureStillAlive(); + const js_value = immediate.toJS(globalThis); + defer js_value.ensureStillAlive(); immediate.internals.init( - js, + js_value, globalThis, id, .setImmediate, @@ -682,7 +688,7 @@ pub const ImmediateObject = struct { callback, arguments_array_or_zero, ); - return js; + return js_value; } fn deinit(this: *ImmediateObject) void { @@ -951,8 +957,8 @@ const TimerObjectInternals = struct { if (kind == .setImmediate) { if (arguments != .zero) - ImmediateObject.argumentsSetCached(timer_js, globalThis, arguments); - ImmediateObject.callbackSetCached(timer_js, globalThis, callback); + ImmediateObject.js.argumentsSetCached(timer_js, globalThis, arguments); + ImmediateObject.js.callbackSetCached(timer_js, globalThis, callback); const parent: *ImmediateObject = @fieldParentPtr("internals", this); vm.enqueueImmediateTask(parent); this.setEnableKeepingEventLoopAlive(vm, true); @@ -960,8 +966,8 @@ const TimerObjectInternals = struct { parent.ref(); } else { if (arguments != .zero) - TimeoutObject.argumentsSetCached(timer_js, globalThis, arguments); - TimeoutObject.callbackSetCached(timer_js, globalThis, callback); + TimeoutObject.js.argumentsSetCached(timer_js, globalThis, arguments); + TimeoutObject.js.callbackSetCached(timer_js, globalThis, callback); // this increments the refcount this.reschedule(vm); } diff --git a/src/bun.js/api/UnsafeObject.zig b/src/bun.js/api/UnsafeObject.zig index 9e8d8a2c85..497f6a0fe7 100644 --- a/src/bun.js/api/UnsafeObject.zig +++ b/src/bun.js/api/UnsafeObject.zig @@ -72,5 +72,5 @@ const JSValue = JSC.JSValue; const JSGlobalObject = JSC.JSGlobalObject; const JSObject = JSC.JSObject; const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const ZigString = JSC.ZigString; diff --git a/src/bun.js/api/bun/dns_resolver.zig b/src/bun.js/api/bun/dns_resolver.zig index fc2d5f6a5c..dca95ee845 100644 --- a/src/bun.js/api/bun/dns_resolver.zig +++ b/src/bun.js/api/bun/dns_resolver.zig @@ -1,6 +1,6 @@ const Bun = @This(); const default_allocator = bun.default_allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const Environment = bun.Environment; const Global = bun.Global; @@ -120,13 +120,20 @@ const LibInfo = struct { } bun.assert(request.backend.libinfo.machport != null); - var poll = bun.Async.FilePoll.init(this.vm, bun.toFD(std.math.maxInt(i32) - 1), .{}, GetAddrInfoRequest, request); + var poll = bun.Async.FilePoll.init( + this.vm, + // TODO: WHAT????????? + .fromNative(std.math.maxInt(i32) - 1), + .{}, + GetAddrInfoRequest, + request, + ); request.backend.libinfo.file_poll = poll; const rc = poll.registerWithFd( this.vm.event_loop_handle.?, .machport, .one_shot, - bun.toFD(@as(i32, @intCast(@intFromPtr(request.backend.libinfo.machport)))), + .fromNative(@intCast(@intFromPtr(request.backend.libinfo.machport))), ); bun.assert(rc == .result); @@ -1572,7 +1579,7 @@ pub const InternalDNS = struct { } const fake_fd: i32 = @intCast(@intFromPtr(machport)); - var poll = bun.Async.FilePoll.init(loop, bun.toFD(fake_fd), .{}, InternalDNSRequest, req); + var poll = bun.Async.FilePoll.init(loop, .fromNative(fake_fd), .{}, InternalDNSRequest, req); const rc = poll.register(loop.loop(), .machport, true); if (rc == .err) { @@ -1802,7 +1809,10 @@ pub const DNSResolver = struct { pending_addr_cache_cares: AddrPendingCache, pending_nameinfo_cache_cares: NameInfoPendingCache, - pub usingnamespace JSC.Codegen.JSDNSResolver; + pub const js = JSC.Codegen.JSDNSResolver; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; const PollsMap = std.AutoArrayHashMap(c_ares.ares_socket_t, *PollType); @@ -2366,7 +2376,7 @@ pub const DNSResolver = struct { vm.eventLoop().enter(); defer vm.eventLoop().exit(); var channel = this.channel orelse { - _ = this.polls.orderedRemove(poll.fd.int()); + _ = this.polls.orderedRemove(poll.fd.native()); poll.deinit(); return; }; @@ -2375,7 +2385,7 @@ pub const DNSResolver = struct { defer this.deref(); channel.process( - poll.fd.int(), + poll.fd.native(), poll.isReadable(), poll.isWritable(), ); @@ -2436,7 +2446,7 @@ pub const DNSResolver = struct { const poll_entry = this.polls.getOrPut(fd) catch unreachable; if (!poll_entry.found_existing) { - poll_entry.value_ptr.* = Async.FilePoll.init(vm, bun.toFD(fd), .{}, DNSResolver, this); + poll_entry.value_ptr.* = Async.FilePoll.init(vm, .fromNative(fd), .{}, DNSResolver, this); } var poll = poll_entry.value_ptr.*; diff --git a/src/bun.js/api/bun/h2_frame_parser.zig b/src/bun.js/api/bun/h2_frame_parser.zig index f9e65dd6b0..c1882820bb 100644 --- a/src/bun.js/api/bun/h2_frame_parser.zig +++ b/src/bun.js/api/bun/h2_frame_parser.zig @@ -1,5 +1,5 @@ const getAllocator = @import("../../base.zig").getAllocator; -const bun = @import("root").bun; +const bun = @import("bun"); const Output = bun.Output; const std = @import("std"); const Allocator = std.mem.Allocator; @@ -654,7 +654,11 @@ const Handlers = struct { pub const H2FrameParser = struct { pub const log = Output.scoped(.H2FrameParser, false); const Self = @This(); - pub usingnamespace JSC.Codegen.JSH2FrameParser; + pub const js = JSC.Codegen.JSH2FrameParser; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; + const RefCount = bun.ptr.RefCount(@This(), "ref_count", deinit, .{}); pub const ref = RefCount.ref; pub const deref = RefCount.deref; @@ -4230,9 +4234,7 @@ pub const H2FrameParser = struct { this.detach(true); } - pub fn finalize( - this: *H2FrameParser, - ) void { + pub fn finalize(this: *H2FrameParser) void { log("finalize", .{}); this.deref(); } @@ -4240,7 +4242,7 @@ pub const H2FrameParser = struct { pub fn createNodeHttp2Binding(global: *JSC.JSGlobalObject) JSC.JSValue { return JSC.JSArray.create(global, &.{ - H2FrameParser.getConstructor(global), + H2FrameParser.js.getConstructor(global), JSC.JSFunction.create(global, "assertSettings", jsAssertSettings, 1, .{}), JSC.JSFunction.create(global, "getPackedSettings", jsGetPackedSettings, 1, .{}), JSC.JSFunction.create(global, "getUnpackedSettings", jsGetUnpackedSettings, 1, .{}), diff --git a/src/bun.js/api/bun/lshpack.zig b/src/bun.js/api/bun/lshpack.zig index 9fdb1cab53..c7b78c7e1f 100644 --- a/src/bun.js/api/bun/lshpack.zig +++ b/src/bun.js/api/bun/lshpack.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const lshpack_header = extern struct { name: [*]const u8 = undefined, diff --git a/src/bun.js/api/bun/process.zig b/src/bun.js/api/bun/process.zig index f955d7f7b5..2fabfad1cd 100644 --- a/src/bun.js/api/bun/process.zig +++ b/src/bun.js/api/bun/process.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const std = @import("std"); const PosixSpawn = bun.spawn; const Environment = bun.Environment; @@ -339,7 +339,7 @@ pub const Process = struct { const poll = if (this.poller == .fd) this.poller.fd else - bun.Async.FilePoll.init(this.event_loop, bun.toFD(watchfd), .{}, Process, this); + bun.Async.FilePoll.init(this.event_loop, .fromNative(watchfd), .{}, Process, this); this.poller = .{ .fd = poll }; this.poller.fd.enableKeepingProcessAlive(this.event_loop); @@ -462,9 +462,9 @@ pub const Process = struct { } if (comptime Environment.isLinux) { - if (this.pidfd != bun.invalid_fd.int() and this.pidfd > 0) { - _ = bun.sys.close(bun.toFD(this.pidfd)); - this.pidfd = @intCast(bun.invalid_fd.int()); + if (this.pidfd != bun.invalid_fd.value.as_system and this.pidfd > 0) { + bun.FD.fromNative(this.pidfd).close(); + this.pidfd = bun.invalid_fd.value.as_system; } } } @@ -904,7 +904,7 @@ const WaiterThreadPosix = struct { if (comptime Environment.isLinux) { const linux = std.os.linux; - instance.eventfd = bun.toFD(try std.posix.eventfd(0, linux.EFD.NONBLOCK | linux.EFD.CLOEXEC | 0)); + instance.eventfd = .fromNative(try std.posix.eventfd(0, linux.EFD.NONBLOCK | linux.EFD.CLOEXEC | 0)); } var thread = try std.Thread.spawn(.{ .stack_size = stack_size }, loop, .{}); @@ -1101,7 +1101,7 @@ pub const PosixSpawnResult = struct { pub fn close(this: *WindowsSpawnResult) void { for (this.extra_pipes.items) |fd| { - _ = bun.sys.close(fd); + fd.close(); } this.extra_pipes.clearAndFree(); @@ -1257,7 +1257,7 @@ pub fn spawnProcessPosix( to_set_cloexec.clearAndFree(); for (to_close_at_end.items) |fd| { - _ = bun.sys.close(fd); + fd.close(); } to_close_at_end.clearAndFree(); } @@ -1266,7 +1266,7 @@ pub fn spawnProcessPosix( errdefer { for (to_close_on_error.items) |fd| { - _ = bun.sys.close(fd); + fd.close(); } } defer to_close_on_error.clearAndFree(); @@ -1286,7 +1286,7 @@ pub fn spawnProcessPosix( for (0..3) |i| { const stdio = stdios[i]; - const fileno = bun.toFD(@as(i32, @intCast(i))); + const fileno = bun.FD.fromNative(@intCast(i)); const flag = if (i == 0) @as(u32, bun.O.RDONLY) else @as(u32, bun.O.WRONLY); switch (stdio_options[i]) { @@ -1335,8 +1335,7 @@ pub fn spawnProcessPosix( const fds: [2]bun.FileDescriptor = brk: { const pair = try bun.sys.socketpair(std.posix.AF.UNIX, std.posix.SOCK.STREAM, 0, .blocking).unwrap(); - - break :brk .{ bun.toFD(pair[if (i == 0) 1 else 0]), bun.toFD(pair[if (i == 0) 0 else 1]) }; + break :brk .{ pair[if (i == 0) 1 else 0], pair[if (i == 0) 0 else 1] }; }; if (i == 0) { @@ -1399,7 +1398,7 @@ pub fn spawnProcessPosix( } for (options.extra_fds, 0..) |ipc, i| { - const fileno = bun.toFD(@as(i32, @intCast(3 + i))); + const fileno = bun.FD.fromNative(@intCast(3 + i)); switch (ipc) { .dup2 => @panic("TODO dup2 extra fd"), @@ -1452,7 +1451,7 @@ pub fn spawnProcessPosix( defer { if (failed_after_spawn) { for (to_close_on_error.items) |fd| { - _ = bun.sys.close(fd); + fd.close(); } to_close_on_error.clearAndFree(); } @@ -1526,7 +1525,7 @@ pub fn spawnProcessWindows( defer { for (uv_files_to_close.items) |fd| { - bun.Async.Closer.close(fd, loop); + bun.Async.Closer.close(.fromUV(fd), loop); } uv_files_to_close.clearAndFree(); } @@ -1613,7 +1612,7 @@ pub fn spawnProcessWindows( }, .pipe => |fd| { stdio.flags = uv.UV_INHERIT_FD; - stdio.data.fd = bun.uvfdcast(fd); + stdio.data.fd = fd.uv(); }, } @@ -1669,7 +1668,7 @@ pub fn spawnProcessWindows( }, .pipe => |fd| { stdio.flags = uv.StdioFlags.inherit_fd; - stdio.data.fd = bun.uvfdcast(fd); + stdio.data.fd = fd.uv(); }, } } @@ -1701,14 +1700,12 @@ pub fn spawnProcessWindows( if (failed) { if (dup_fds[0] != -1) { - const r = bun.FDImpl.fromUV(dup_fds[0]).encode(); - _ = bun.sys.close(r); + bun.FD.fromUV(dup_fds[0]).close(); } } if (dup_fds[1] != -1) { - const w = bun.FDImpl.fromUV(dup_fds[1]).encode(); - _ = bun.sys.close(w); + bun.FD.fromUV(dup_fds[1]).close(); } } if (process.poller.uv.spawn(loop, &uv_process_options).toError(.uv_spawn)) |err| { @@ -1732,9 +1729,7 @@ pub fn spawnProcessWindows( if (dup_src != null and i == dup_src.?) { result_stdio.* = .unavailable; } else if (dup_tgt != null and i == dup_tgt.?) { - result_stdio.* = .{ - .buffer_fd = bun.FDImpl.fromUV(dup_fds[0]).encode(), - }; + result_stdio.* = .{ .buffer_fd = .fromUV(dup_fds[0]) }; } else switch (stdio_options[i]) { .buffer => { result_stdio.* = .{ .buffer = @ptrCast(stdio.data.stream) }; @@ -1832,8 +1827,8 @@ pub const sync = struct { err: bun.C.E = .SUCCESS, context: *SyncWindowsProcess, - onDoneCallback: *const fn (*SyncWindowsProcess, tag: bun.FDTag, chunks: []const []u8, err: bun.C.E) void = &SyncWindowsProcess.onReaderDone, - tag: bun.FDTag = .none, + onDoneCallback: *const fn (*SyncWindowsProcess, tag: SyncWindowsProcess.OutFd, chunks: []const []u8, err: bun.C.E) void = &SyncWindowsProcess.onReaderDone, + tag: SyncWindowsProcess.OutFd, pub const new = bun.TrivialNew(@This()); @@ -1873,6 +1868,8 @@ pub const sync = struct { pub const new = bun.TrivialNew(@This()); pub const deinit = bun.TrivialDeinit(@This()); + const OutFd = enum { stdout, stderr }; + stderr: []const []u8 = &.{}, stdout: []const []u8 = &.{}, err: bun.C.E = .SUCCESS, @@ -1887,7 +1884,7 @@ pub const sync = struct { this.process.deref(); } - pub fn onReaderDone(this: *SyncWindowsProcess, tag: bun.FDTag, chunks: []const []u8, err: bun.C.E) void { + pub fn onReaderDone(this: *SyncWindowsProcess, tag: OutFd, chunks: []const []u8, err: bun.C.E) void { switch (tag) { .stderr => { this.stderr = chunks; @@ -1895,7 +1892,6 @@ pub const sync = struct { .stdout => { this.stdout = chunks; }, - else => unreachable, } if (err != .SUCCESS) { this.err = err; @@ -2098,13 +2094,13 @@ pub const sync = struct { for (out_fds) |fd| { if (fd != bun.invalid_fd) { - _ = bun.sys.close(fd); + fd.close(); } } if (comptime Environment.isLinux) { if (process.pidfd) |pidfd| { - _ = bun.sys.close(bun.toFD(pidfd)); + bun.FD.fromNative(pidfd).close(); } } } @@ -2139,7 +2135,7 @@ pub const sync = struct { .result => |bytes_read| { bytes.items.len += bytes_read; if (bytes_read == 0) { - _ = bun.sys.close(fd.*); + fd.*.close(); fd.* = bun.invalid_fd; out_fd.* = bun.invalid_fd; break; diff --git a/src/bun.js/api/bun/socket.zig b/src/bun.js/api/bun/socket.zig index 8f198ae70c..fbb32fc90c 100644 --- a/src/bun.js/api/bun/socket.zig +++ b/src/bun.js/api/bun/socket.zig @@ -1,5 +1,5 @@ const default_allocator = bun.default_allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const Environment = bun.Environment; const Global = bun.Global; @@ -524,7 +524,10 @@ pub const Listener = struct { strong_data: JSC.Strong = .empty, strong_self: JSC.Strong = .empty, - pub usingnamespace JSC.Codegen.JSListener; + pub const js = JSC.Codegen.JSListener; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; pub const ListenerType = union(enum) { uws: *uws.ListenSocket, @@ -1107,7 +1110,7 @@ pub const Listener = struct { break :brk (pipe_name != null); }, .fd => |fd| brk: { - const uvfd = bun.uvfdcast(fd); + const uvfd = fd.uv(); const fd_type = uv.uv_guess_handle(uvfd); if (fd_type == uv.Handle.Type.named_pipe) { break :brk true; @@ -1117,7 +1120,7 @@ pub const Listener = struct { const osfd: uv.uv_os_fd_t = @ptrFromInt(@as(usize, @intCast(uvfd))); if (bun.windows.GetFileType(osfd) == bun.windows.FILE_TYPE_PIPE) { // yay its a named pipe lets make it a libuv fd - connection.fd = bun.FDImpl.fromUV(uv.uv_open_osfhandle(osfd)).encode(); + connection.fd = bun.FD.fromNative(osfd).makeLibUVOwned() catch @panic("failed to allocate file descriptor"); break :brk true; } } @@ -4497,8 +4500,8 @@ pub fn jsCreateSocketPair(global: *JSC.JSGlobalObject, _: *JSC.CallFrame) bun.JS return global.throwValue(err.toJSC(global)); } - _ = bun.sys.setNonblocking(bun.toFD(fds_[0])); - _ = bun.sys.setNonblocking(bun.toFD(fds_[1])); + _ = bun.FD.fromNative(fds_[0]).updateNonblocking(true); + _ = bun.FD.fromNative(fds_[1]).updateNonblocking(true); const array = JSC.JSValue.createEmptyArray(global, 2); array.putIndex(global, 0, JSC.jsNumber(fds_[0])); diff --git a/src/bun.js/api/bun/socket/SocketAddress.zig b/src/bun.js/api/bun/socket/SocketAddress.zig index cb4ad1fe4c..3ff29a9485 100644 --- a/src/bun.js/api/bun/socket/SocketAddress.zig +++ b/src/bun.js/api/bun/socket/SocketAddress.zig @@ -5,7 +5,11 @@ //! TODO: add a inspect method (under `Symbol.for("nodejs.util.inspect.custom")`). //! Requires updating bindgen. const SocketAddress = @This(); -pub usingnamespace JSC.Codegen.JSSocketAddress; +pub const js = JSC.Codegen.JSSocketAddress; +pub const toJS = js.toJS; +pub const fromJS = js.fromJS; +pub const fromJSDirect = js.fromJSDirect; + pub const new = bun.TrivialNew(SocketAddress); // NOTE: not std.net.Address b/c .un is huge and we don't use it. @@ -612,7 +616,7 @@ comptime { } const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const ares = bun.c_ares; const net = std.net; const Environment = bun.Environment; diff --git a/src/bun.js/api/bun/spawn.zig b/src/bun.js/api/bun/spawn.zig index ffdcce65fd..4b4bacdb8b 100644 --- a/src/bun.js/api/bun/spawn.zig +++ b/src/bun.js/api/bun/spawn.zig @@ -1,5 +1,5 @@ const JSC = bun.JSC; -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const std = @import("std"); const Output = bun.Output; @@ -77,14 +77,14 @@ pub const BunSpawn = struct { .path = (try bun.default_allocator.dupeZ(u8, bun.span(path))).ptr, .flags = @intCast(flags), .mode = @intCast(mode), - .fds = .{ fd, bun.toFD(0) }, + .fds = .{ fd, .fromUV(0) }, }); } pub fn close(self: *Actions, fd: bun.FileDescriptor) !void { try self.actions.append(bun.default_allocator, .{ .kind = .close, - .fds = .{ fd, bun.toFD(0) }, + .fds = .{ fd, .fromUV(0) }, }); } diff --git a/src/bun.js/api/bun/spawn/stdio.zig b/src/bun.js/api/bun/spawn/stdio.zig index 61697c94f7..3467915f26 100644 --- a/src/bun.js/api/bun/spawn/stdio.zig +++ b/src/bun.js/api/bun/spawn/stdio.zig @@ -2,7 +2,7 @@ const Allocator = std.mem.Allocator; const uws = bun.uws; const std = @import("std"); const default_allocator = bun.default_allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const Environment = bun.Environment; const Async = bun.Async; const JSC = bun.JSC; @@ -14,9 +14,9 @@ const os = std.os; const uv = bun.windows.libuv; pub const Stdio = union(enum) { - inherit: void, + inherit, capture: struct { fd: bun.FileDescriptor, buf: *bun.ByteList }, - ignore: void, + ignore, fd: bun.FileDescriptor, dup2: struct { out: bun.JSC.Subprocess.StdioKind, @@ -26,8 +26,8 @@ pub const Stdio = union(enum) { blob: JSC.WebCore.AnyBlob, array_buffer: JSC.ArrayBuffer.Strong, memfd: bun.FileDescriptor, - pipe: void, - ipc: void, + pipe, + ipc, const log = bun.sys.syslog; @@ -81,7 +81,7 @@ pub const Stdio = union(enum) { blob.detach(); }, .memfd => |fd| { - _ = bun.sys.close(fd); + fd.close(); }, else => {}, } @@ -129,13 +129,13 @@ pub const Stdio = union(enum) { } Output.debugWarn("Failed to write to memfd: {s}", .{@tagName(err.getErrno())}); - _ = bun.sys.close(fd); + fd.close(); return; }, .result => |result| { if (result == 0) { Output.debugWarn("Failed to write to memfd: EOF", .{}); - _ = bun.sys.close(fd); + fd.close(); return; } written += @intCast(result); @@ -155,12 +155,12 @@ pub const Stdio = union(enum) { fn toPosix( stdio: *@This(), - i: u32, + i: i32, ) Result { return .{ .result = switch (stdio.*) { .blob => |blob| brk: { - const fd = bun.stdio(i); + const fd = bun.FD.Stdio.fromInt(i).?.fd(); if (blob.needsToReadFile()) { if (blob.store()) |store| { if (store.data.file.pathlike == .fd) { @@ -168,19 +168,18 @@ pub const Stdio = union(enum) { break :brk .{ .inherit = {} }; } - switch (bun.FDTag.get(store.data.file.pathlike.fd)) { - .stdin => { + if (store.data.file.pathlike.fd.stdioTag()) |tag| switch (tag) { + .std_in => { if (i == 1 or i == 2) { return .{ .err = .stdin_used_as_out }; } }, - .stdout, .stderr => { + .std_out, .std_err => { if (i == 0) { return .{ .err = .out_used_as_stdin }; } }, - else => {}, - } + }; break :brk .{ .pipe = store.data.file.pathlike.fd }; } @@ -209,12 +208,12 @@ pub const Stdio = union(enum) { fn toWindows( stdio: *@This(), - i: u32, + i: i32, ) Result { return .{ .result = switch (stdio.*) { .blob => |blob| brk: { - const fd = bun.stdio(i); + const fd = bun.FD.Stdio.fromInt(i).?.fd(); if (blob.needsToReadFile()) { if (blob.store()) |store| { if (store.data.file.pathlike == .fd) { @@ -222,19 +221,18 @@ pub const Stdio = union(enum) { break :brk .{ .inherit = {} }; } - switch (bun.FDTag.get(store.data.file.pathlike.fd)) { - .stdin => { + if (store.data.file.pathlike.fd.stdioTag()) |tag| switch (tag) { + .std_in => { if (i == 1 or i == 2) { return .{ .err = .stdin_used_as_out }; } }, - .stdout, .stderr => { + .std_out, .std_err => { if (i == 0) { return .{ .err = .out_used_as_stdin }; } }, - else => {}, - } + }; break :brk .{ .pipe = store.data.file.pathlike.fd }; } @@ -272,7 +270,7 @@ pub const Stdio = union(enum) { /// On windows this function allocate memory ensure that .deinit() is called or ownership is passed for all *uv.Pipe pub fn asSpawnOption( stdio: *@This(), - i: u32, + i: i32, ) Stdio.Result { if (comptime Environment.isWindows) { return stdio.toWindows(i); @@ -289,7 +287,7 @@ pub const Stdio = union(enum) { }; } - pub fn extract(out_stdio: *Stdio, globalThis: *JSC.JSGlobalObject, i: u32, value: JSValue) bun.JSError!void { + pub fn extract(out_stdio: *Stdio, globalThis: *JSC.JSGlobalObject, i: i32, value: JSValue) bun.JSError!void { switch (value) { // undefined: default .undefined, .zero => return, @@ -317,7 +315,7 @@ pub const Stdio = union(enum) { return; } else if (value.isNumber()) { const fd = value.asFileDescriptor(); - const file_fd = bun.uvfdcast(fd); + const file_fd = fd.uv(); if (file_fd < 0) { return globalThis.throwInvalidArguments("file descriptor must be a positive integer", .{}); } @@ -328,8 +326,8 @@ pub const Stdio = union(enum) { return globalThis.throwInvalidArguments("file descriptor must be a valid integer, received: {}", .{value.toFmt(&formatter)}); } - switch (bun.FDTag.get(fd)) { - .stdin => { + if (fd.stdioTag()) |tag| switch (tag) { + .std_in => { if (i == 1 or i == 2) { return globalThis.throwInvalidArguments("stdin cannot be used for stdout or stderr", .{}); } @@ -337,20 +335,19 @@ pub const Stdio = union(enum) { out_stdio.* = Stdio{ .inherit = {} }; return; }, - .stdout, .stderr => |tag| { + .std_out, .std_err => { if (i == 0) { return globalThis.throwInvalidArguments("stdout and stderr cannot be used for stdin", .{}); } - if (i == 1 and tag == .stdout) { + if (i == 1 and tag == .std_out) { out_stdio.* = .{ .inherit = {} }; return; - } else if (i == 2 and tag == .stderr) { + } else if (i == 2 and tag == .std_err) { out_stdio.* = .{ .inherit = {} }; return; } }, - else => {}, - } + }; out_stdio.* = Stdio{ .fd = fd }; return; @@ -403,31 +400,29 @@ pub const Stdio = union(enum) { return globalThis.throwInvalidArguments("stdio must be an array of 'inherit', 'ignore', or null", .{}); } - pub fn extractBlob(stdio: *Stdio, globalThis: *JSC.JSGlobalObject, blob: JSC.WebCore.AnyBlob, i: u32) bun.JSError!void { - const fd = bun.stdio(i); + pub fn extractBlob(stdio: *Stdio, globalThis: *JSC.JSGlobalObject, blob: JSC.WebCore.AnyBlob, i: i32) bun.JSError!void { + const fd = bun.FD.Stdio.fromInt(i).?.fd(); if (blob.needsToReadFile()) { if (blob.store()) |store| { if (store.data.file.pathlike == .fd) { if (store.data.file.pathlike.fd == fd) { - stdio.* = Stdio{ .inherit = {} }; + stdio.* = .inherit; } else { - switch (bun.FDTag.get(i)) { - .stdin => { - if (i == 1 or i == 2) { - return globalThis.throwInvalidArguments("stdin cannot be used for stdout or stderr", .{}); - } + // TODO: is this supposed to be `store.data.file.pathlike.fd`? + if (bun.FD.Stdio.fromInt(i)) |tag| switch (tag) { + .std_in, + => if (i == 1 or i == 2) { + return globalThis.throwInvalidArguments("stdin cannot be used for stdout or stderr", .{}); }, - - .stdout, .stderr => { - if (i == 0) { - return globalThis.throwInvalidArguments("stdout and stderr cannot be used for stdin", .{}); - } + .std_out, + .std_err, + => if (i == 0) { + return globalThis.throwInvalidArguments("stdout and stderr cannot be used for stdin", .{}); }, - else => {}, - } + }; - stdio.* = Stdio{ .fd = store.data.file.pathlike.fd }; + stdio.* = .{ .fd = store.data.file.pathlike.fd }; } return; diff --git a/src/bun.js/api/bun/ssl_wrapper.zig b/src/bun.js/api/bun/ssl_wrapper.zig index 266cbcebc7..6c62116674 100644 --- a/src/bun.js/api/bun/ssl_wrapper.zig +++ b/src/bun.js/api/bun/ssl_wrapper.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const BoringSSL = bun.BoringSSL.c; const X509 = @import("./x509.zig"); diff --git a/src/bun.js/api/bun/subprocess.zig b/src/bun.js/api/bun/subprocess.zig index c6a1b16e6f..c4b093734b 100644 --- a/src/bun.js/api/bun/subprocess.zig +++ b/src/bun.js/api/bun/subprocess.zig @@ -1,7 +1,11 @@ //! The Subprocess object is returned by `Bun.spawn`. This file also holds the //! code for `Bun.spawnSync` -pub usingnamespace JSC.Codegen.JSSubprocess; +pub const js = JSC.Codegen.JSSubprocess; +pub const toJS = js.toJS; +pub const fromJS = js.fromJS; +pub const fromJSDirect = js.fromJSDirect; + const RefCount = bun.ptr.RefCount(@This(), "ref_count", deinit, .{}); pub const ref = RefCount.ref; pub const deref = RefCount.deref; @@ -78,7 +82,11 @@ pub inline fn assertStdioResult(result: StdioResult) void { } pub const ResourceUsage = struct { - pub usingnamespace JSC.Codegen.JSResourceUsage; + pub const js = JSC.Codegen.JSResourceUsage; + pub const toJS = ResourceUsage.js.toJS; + pub const fromJS = ResourceUsage.js.fromJS; + pub const fromJSDirect = ResourceUsage.js.fromJSDirect; + rusage: Rusage, pub fn getCPUTime( @@ -191,9 +199,9 @@ pub const StdioKind = enum { pub fn toFd(this: @This()) bun.FileDescriptor { return switch (this) { - .stdin => bun.STDIN_FD, - .stdout => bun.STDOUT_FD, - .stderr => bun.STDERR_FD, + .stdin => .stdin(), + .stdout => .stdout(), + .stderr => .stderr(), }; } @@ -453,7 +461,7 @@ const Readable = union(enum) { switch (this.*) { .memfd => |fd| { this.* = .{ .closed = {} }; - _ = bun.sys.close(fd); + fd.close(); }, .fd => |_| { this.* = .{ .closed = {} }; @@ -469,7 +477,7 @@ const Readable = union(enum) { switch (this.*) { .memfd => |fd| { this.* = .{ .closed = {} }; - _ = bun.sys.close(fd); + fd.close(); }, .fd => { this.* = .{ .closed = {} }; @@ -1290,7 +1298,7 @@ const Writable = union(enum) { const process: *Subprocess = @fieldParentPtr("stdin", this); if (process.this_jsvalue != .zero) { - if (Subprocess.stdinGetCached(process.this_jsvalue)) |existing_value| { + if (js.stdinGetCached(process.this_jsvalue)) |existing_value| { JSC.WebCore.FileSink.JSSink.setDestroyCallback(existing_value, 0); } } @@ -1498,7 +1506,7 @@ const Writable = union(enum) { this.buffer.deref(); }, .memfd => |fd| { - _ = bun.sys.close(fd); + fd.close(); this.* = .{ .ignore = {} }; }, .ignore => {}, @@ -1512,7 +1520,7 @@ const Writable = union(enum) { _ = pipe.end(null); }, .memfd => |fd| { - _ = bun.sys.close(fd); + fd.close(); this.* = .{ .ignore = {} }; }, .fd => { @@ -1718,7 +1726,7 @@ pub fn finalizeStreams(this: *Subprocess) void { item.buffer.close(onPipeClose); } } else { - _ = bun.sys.close(item); + item.close(); } } this.stdio_pipes.clearAndFree(bun.default_allocator); @@ -2078,7 +2086,7 @@ pub fn spawnMaybeSync( if (!stdio_val.isEmptyOrUndefinedOrNull()) { if (stdio_val.jsType().isArray()) { var stdio_iter = stdio_val.arrayIterator(globalThis); - var i: u32 = 0; + var i: u31 = 0; while (stdio_iter.next()) |value| : (i += 1) { try stdio[i].extract(globalThis, i, value); if (i == 2) @@ -2185,7 +2193,7 @@ pub fn spawnMaybeSync( if (should_close_memfd) { inline for (0..stdio.len) |fd_index| { if (stdio[fd_index] == .memfd) { - _ = bun.sys.close(stdio[fd_index].memfd); + stdio[fd_index].memfd.close(); stdio[fd_index] = .ignore; } } @@ -2205,12 +2213,12 @@ pub fn spawnMaybeSync( // // When Bun.spawn() is given an `.ipc` callback, it enables IPC as follows: env_array.ensureUnusedCapacity(allocator, 3) catch |err| return globalThis.throwError(err, "in Bun.spawn") catch return .zero; - const ipc_fd: u32 = brk: { + const ipc_fd: i32 = brk: { if (ipc_channel == -1) { // If the user didn't specify an IPC channel, we need to add one ipc_channel = @intCast(extra_fds.items.len); var ipc_extra_fd_default = Stdio{ .ipc = {} }; - const fd: u32 = @intCast(ipc_channel + 3); + const fd: i32 = ipc_channel + 3; switch (ipc_extra_fd_default.asSpawnOption(fd)) { .result => |opt| { try extra_fds.append(opt); @@ -2674,7 +2682,7 @@ pub fn getGlobalThis(this: *Subprocess) ?*JSC.JSGlobalObject { pub const IPCHandler = IPC.NewIPCHandler(Subprocess); const default_allocator = bun.default_allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const Environment = bun.Environment; const Global = bun.Global; diff --git a/src/bun.js/api/bun/udp_socket.zig b/src/bun.js/api/bun/udp_socket.zig index 144d5a30ef..9adc502f95 100644 --- a/src/bun.js/api/bun/udp_socket.zig +++ b/src/bun.js/api/bun/udp_socket.zig @@ -1,6 +1,6 @@ const std = @import("std"); const uws = @import("../../../deps/uws.zig"); -const bun = @import("root").bun; +const bun = @import("bun"); const strings = bun.strings; const default_allocator = bun.default_allocator; @@ -290,7 +290,10 @@ pub const UDPSocket = struct { port: u16, }; - pub usingnamespace JSC.Codegen.JSUDPSocket; + pub const js = JSC.Codegen.JSUDPSocket; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; pub fn hasPendingActivity(this: *This) callconv(.C) bool { return this.js_refcount.load(.monotonic) > 0; @@ -944,8 +947,8 @@ pub const UDPSocket = struct { .port = port, }; - UDPSocket.addressSetCached(callFrame.this(), globalThis, .zero); - UDPSocket.remoteAddressSetCached(callFrame.this(), globalThis, .zero); + js.addressSetCached(callFrame.this(), globalThis, .zero); + js.remoteAddressSetCached(callFrame.this(), globalThis, .zero); return .undefined; } diff --git a/src/bun.js/api/bun/x509.zig b/src/bun.js/api/bun/x509.zig index 09f0801dab..99adc1fda9 100644 --- a/src/bun.js/api/bun/x509.zig +++ b/src/bun.js/api/bun/x509.zig @@ -1,5 +1,5 @@ const BoringSSL = bun.BoringSSL.c; -const bun = @import("root").bun; +const bun = @import("bun"); const ZigString = JSC.ZigString; const std = @import("std"); const JSC = bun.JSC; diff --git a/src/bun.js/api/crypto.zig b/src/bun.js/api/crypto.zig index 549fcc18ef..9323541de8 100644 --- a/src/bun.js/api/crypto.zig +++ b/src/bun.js/api/crypto.zig @@ -22,7 +22,7 @@ comptime { } const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const strings = bun.strings; const MutableString = bun.MutableString; diff --git a/src/bun.js/api/crypto/CryptoHasher.zig b/src/bun.js/api/crypto/CryptoHasher.zig index 3190217847..eec9906f6e 100644 --- a/src/bun.js/api/crypto/CryptoHasher.zig +++ b/src/bun.js/api/crypto/CryptoHasher.zig @@ -7,7 +7,11 @@ pub const CryptoHasher = union(enum) { const Digest = EVP.Digest; - pub usingnamespace JSC.Codegen.JSCryptoHasher; + pub const js = JSC.Codegen.JSCryptoHasher; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; + pub const new = bun.TrivialNew(@This()); // For using only CryptoHasherZig in c++ @@ -307,7 +311,7 @@ pub const CryptoHasher = union(enum) { globalObject: *JSC.JSGlobalObject, _: *JSC.JSObject, ) JSC.JSValue { - return CryptoHasher.getConstructor(globalObject); + return CryptoHasher.js.getConstructor(globalObject); } pub fn update(this: *CryptoHasher, globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) bun.JSError!JSC.JSValue { @@ -873,7 +877,7 @@ const Crypto = JSC.API.Bun.Crypto; const Hashers = @import("../../../sha.zig"); const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const strings = bun.strings; const MutableString = bun.MutableString; diff --git a/src/bun.js/api/crypto/EVP.zig b/src/bun.js/api/crypto/EVP.zig index 1e8e4a1cee..7efe18d09d 100644 --- a/src/bun.js/api/crypto/EVP.zig +++ b/src/bun.js/api/crypto/EVP.zig @@ -204,7 +204,7 @@ pub const PBKDF2 = @import("./PBKDF2.zig"); pub const pbkdf2 = PBKDF2.pbkdf2; const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const strings = bun.strings; const MutableString = bun.MutableString; diff --git a/src/bun.js/api/crypto/HMAC.zig b/src/bun.js/api/crypto/HMAC.zig index e0aae477e0..71eef7b24c 100644 --- a/src/bun.js/api/crypto/HMAC.zig +++ b/src/bun.js/api/crypto/HMAC.zig @@ -49,7 +49,7 @@ pub fn deinit(this: *HMAC) void { bun.destroy(this); } -const bun = @import("root").bun; +const bun = @import("bun"); const BoringSSL = bun.BoringSSL.c; const JSC = bun.JSC; const EVP = JSC.API.Bun.Crypto.EVP; diff --git a/src/bun.js/api/crypto/PBKDF2.zig b/src/bun.js/api/crypto/PBKDF2.zig index 8c335d9dcb..bbcf83f52f 100644 --- a/src/bun.js/api/crypto/PBKDF2.zig +++ b/src/bun.js/api/crypto/PBKDF2.zig @@ -244,7 +244,7 @@ pub fn pbkdf2( } const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const strings = bun.strings; const MutableString = bun.MutableString; diff --git a/src/bun.js/api/crypto/PasswordObject.zig b/src/bun.js/api/crypto/PasswordObject.zig index 0d91767bce..574fe6bc6b 100644 --- a/src/bun.js/api/crypto/PasswordObject.zig +++ b/src/bun.js/api/crypto/PasswordObject.zig @@ -755,7 +755,7 @@ pub const JSPasswordObject = struct { }; const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const strings = bun.strings; const MutableString = bun.MutableString; diff --git a/src/bun.js/api/ffi.zig b/src/bun.js/api/ffi.zig index 4a08c77d5f..b1290ef750 100644 --- a/src/bun.js/api/ffi.zig +++ b/src/bun.js/api/ffi.zig @@ -1,6 +1,5 @@ const Bun = @This(); -const root = @import("root"); -const bun = @import("root").bun; +const bun = @import("bun"); const Environment = bun.Environment; const Global = bun.Global; @@ -14,7 +13,6 @@ const Fs = @import("../../fs.zig"); const options = @import("../../options.zig"); const ZigString = bun.JSC.ZigString; -const js = bun.JSC.C; const JSC = bun.JSC; const JSError = @import("../base.zig").JSError; @@ -60,14 +58,17 @@ const Offsets = extern struct { }; pub const FFI = struct { + pub const js = JSC.Codegen.JSFFI; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; + dylib: ?std.DynLib = null, relocated_bytes_to_free: ?[]u8 = null, functions: bun.StringArrayHashMapUnmanaged(Function) = .{}, closed: bool = false, shared_state: ?*TCC.State = null, - pub usingnamespace JSC.Codegen.JSFFI; - pub fn finalize(_: *FFI) callconv(.C) void {} const CompileC = struct { @@ -280,27 +281,27 @@ pub const FFI = struct { // On Alpine and RHEL-based distros, the paths are not suffixed if (Environment.isX64) { - if (bun.sys.directoryExistsAt(std.fs.cwd(), "/usr/include/x86_64-linux-gnu").isTrue()) { + if (bun.FD.cwd().directoryExistsAt("/usr/include/x86_64-linux-gnu").isTrue()) { cached_default_system_include_dir = "/usr/include/x86_64-linux-gnu"; - } else if (bun.sys.directoryExistsAt(std.fs.cwd(), "/usr/include").isTrue()) { + } else if (bun.FD.cwd().directoryExistsAt("/usr/include").isTrue()) { cached_default_system_include_dir = "/usr/include"; } - if (bun.sys.directoryExistsAt(std.fs.cwd(), "/usr/lib/x86_64-linux-gnu").isTrue()) { + if (bun.FD.cwd().directoryExistsAt("/usr/lib/x86_64-linux-gnu").isTrue()) { cached_default_system_library_dir = "/usr/lib/x86_64-linux-gnu"; - } else if (bun.sys.directoryExistsAt(std.fs.cwd(), "/usr/lib64").isTrue()) { + } else if (bun.FD.cwd().directoryExistsAt("/usr/lib64").isTrue()) { cached_default_system_library_dir = "/usr/lib64"; } } else if (Environment.isAarch64) { - if (bun.sys.directoryExistsAt(std.fs.cwd(), "/usr/include/aarch64-linux-gnu").isTrue()) { + if (bun.FD.cwd().directoryExistsAt("/usr/include/aarch64-linux-gnu").isTrue()) { cached_default_system_include_dir = "/usr/include/aarch64-linux-gnu"; - } else if (bun.sys.directoryExistsAt(std.fs.cwd(), "/usr/include").isTrue()) { + } else if (bun.FD.cwd().directoryExistsAt("/usr/include").isTrue()) { cached_default_system_include_dir = "/usr/include"; } - if (bun.sys.directoryExistsAt(std.fs.cwd(), "/usr/lib/aarch64-linux-gnu").isTrue()) { + if (bun.FD.cwd().directoryExistsAt("/usr/lib/aarch64-linux-gnu").isTrue()) { cached_default_system_library_dir = "/usr/lib/aarch64-linux-gnu"; - } else if (bun.sys.directoryExistsAt(std.fs.cwd(), "/usr/lib64").isTrue()) { + } else if (bun.FD.cwd().directoryExistsAt("/usr/lib64").isTrue()) { cached_default_system_library_dir = "/usr/lib64"; } } @@ -368,13 +369,13 @@ pub const FFI = struct { } if (Environment.isAarch64) { - if (bun.sys.directoryExistsAt(std.fs.cwd(), "/opt/homebrew/include").isTrue()) { + if (bun.FD.cwd().directoryExistsAt("/opt/homebrew/include").isTrue()) { state.addSysIncludePath("/opt/homebrew/include") catch { debug("TinyCC failed to add library path", .{}); }; } - if (bun.sys.directoryExistsAt(std.fs.cwd(), "/opt/homebrew/lib").isTrue()) { + if (bun.FD.cwd().directoryExistsAt("/opt/homebrew/lib").isTrue()) { state.addLibraryPath("/opt/homebrew/lib") catch { debug("TinyCC failed to add library path", .{}); }; @@ -395,13 +396,13 @@ pub const FFI = struct { } if (Environment.isPosix) { - if (bun.sys.directoryExistsAt(std.fs.cwd(), "/usr/local/include").isTrue()) { + if (bun.FD.cwd().directoryExistsAt("/usr/local/include").isTrue()) { state.addSysIncludePath("/usr/local/include") catch { debug("TinyCC failed to add sysinclude path", .{}); }; } - if (bun.sys.directoryExistsAt(std.fs.cwd(), "/usr/local/lib").isTrue()) { + if (bun.FD.cwd().directoryExistsAt("/usr/local/lib").isTrue()) { state.addLibraryPath("/usr/local/lib") catch { debug("TinyCC failed to add library path", .{}); }; @@ -2333,7 +2334,7 @@ const CompilerRT = struct { }) catch {}; } var path_buf: [bun.MAX_PATH_BYTES]u8 = undefined; - compiler_rt_dir = bun.default_allocator.dupeZ(u8, bun.getFdPath(bunCC, &path_buf) catch return) catch bun.outOfMemory(); + compiler_rt_dir = bun.default_allocator.dupeZ(u8, bun.getFdPath(.fromStdDir(bunCC), &path_buf) catch return) catch bun.outOfMemory(); } var create_compiler_rt_dir_once = std.once(createCompilerRTDir); diff --git a/src/bun.js/api/filesystem_router.zig b/src/bun.js/api/filesystem_router.zig index 35bb81aece..64759f9abd 100644 --- a/src/bun.js/api/filesystem_router.zig +++ b/src/bun.js/api/filesystem_router.zig @@ -2,10 +2,9 @@ const std = @import("std"); const Api = @import("../../api/schema.zig").Api; const QueryStringMap = @import("../../url.zig").QueryStringMap; const CombinedScanner = @import("../../url.zig").CombinedScanner; -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const JSC = bun.JSC; -const js = JSC.C; const WebCore = JSC.WebCore; const Transpiler = bun.transpiler; const ScriptSrcStream = std.io.FixedBufferStream([]u8); @@ -44,7 +43,10 @@ pub const FileSystemRouter = struct { allocator: std.mem.Allocator = undefined, asset_prefix: ?*JSC.RefString = null, - pub usingnamespace JSC.Codegen.JSFileSystemRouter; + pub const js = JSC.Codegen.JSFileSystemRouter; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; pub fn constructor(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) bun.JSError!*FileSystemRouter { const argument_ = callframe.arguments_old(1); @@ -278,7 +280,7 @@ pub const FileSystemRouter = struct { globalThis.allocator().destroy(this.arena); this.arena = arena; - @This().routesSetCached(this_value, globalThis, JSC.JSValue.zero); + js.routesSetCached(this_value, globalThis, JSC.JSValue.zero); this.allocator = allocator; this.router = router; return this_value; @@ -418,7 +420,10 @@ pub const MatchedRoute = struct { needs_deinit: bool = true, base_dir: ?*JSC.RefString = null, - pub usingnamespace JSC.Codegen.JSMatchedRoute; + pub const js = JSC.Codegen.JSMatchedRoute; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; pub fn getName(this: *MatchedRoute, globalThis: *JSC.JSGlobalObject) JSValue { return ZigString.init(this.route.name).withEncoding().toJS(globalThis); @@ -537,7 +542,7 @@ pub const MatchedRoute = struct { threadlocal var query_string_values_buf: [256]string = undefined; threadlocal var query_string_value_refs_buf: [256]ZigString = undefined; - pub fn createQueryObject(ctx: js.JSContextRef, map: *QueryStringMap) JSValue { + pub fn createQueryObject(ctx: *JSC.JSGlobalObject, map: *QueryStringMap) JSValue { const QueryObjectCreator = struct { query: *QueryStringMap, pub fn create(this: *@This(), obj: *JSObject, global: *JSGlobalObject) void { diff --git a/src/bun.js/api/glob.zig b/src/bun.js/api/glob.zig index f4911965e4..7e9b69fefe 100644 --- a/src/bun.js/api/glob.zig +++ b/src/bun.js/api/glob.zig @@ -7,7 +7,7 @@ const Syscall = @import("../../sys.zig"); const std = @import("std"); const Allocator = std.mem.Allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const BunString = bun.String; const string = bun.string; const JSC = bun.JSC; @@ -23,7 +23,10 @@ const CodepointIterator = @import("../../string_immutable.zig").UnsignedCodepoin const Arena = std.heap.ArenaAllocator; -pub usingnamespace JSC.Codegen.JSGlob; +pub const js = JSC.Codegen.JSGlob; +pub const toJS = js.toJS; +pub const fromJS = js.fromJS; +pub const fromJSDirect = js.fromJSDirect; pattern: []const u8, pattern_codepoints: ?std.ArrayList(u32) = null, diff --git a/src/bun.js/api/html_rewriter.zig b/src/bun.js/api/html_rewriter.zig index 289d1d1ff5..597cf05e82 100644 --- a/src/bun.js/api/html_rewriter.zig +++ b/src/bun.js/api/html_rewriter.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const JSC = bun.JSC; const WebCore = @import("../webcore/response.zig"); @@ -48,7 +48,10 @@ pub const HTMLRewriter = struct { builder: *LOLHTML.HTMLRewriter.Builder, context: *LOLHTMLContext, - pub usingnamespace JSC.Codegen.JSHTMLRewriter; + pub const js = JSC.Codegen.JSHTMLRewriter; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; pub fn constructor(_: *JSGlobalObject, _: *JSC.CallFrame) bun.JSError!*HTMLRewriter { const rewriter = bun.default_allocator.create(HTMLRewriter) catch bun.outOfMemory(); @@ -215,7 +218,7 @@ pub const HTMLRewriter = struct { var blob = out_response.body.value.useAsAnyBlobAllowNonUTF8String(); defer { - _ = Response.dangerouslySetPtr(out_response_value, null); + _ = Response.js.dangerouslySetPtr(out_response_value, null); // Manually invoke the finalizer to ensure it does what we want out_response.finalize(); } @@ -1077,7 +1080,10 @@ pub const TextChunk = struct { ref_count: RefCount, text_chunk: ?*LOLHTML.TextChunk = null, - pub usingnamespace JSC.Codegen.JSTextChunk; + pub const js = JSC.Codegen.JSTextChunk; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; pub fn init(text_chunk: *LOLHTML.TextChunk) *TextChunk { return bun.new(TextChunk, .{ @@ -1197,7 +1203,10 @@ pub const DocType = struct { }); } - pub usingnamespace JSC.Codegen.JSDocType; + pub const js = JSC.Codegen.JSDocType; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; /// The doctype name. pub fn name( @@ -1267,7 +1276,10 @@ pub const DocEnd = struct { ref_count: RefCount, doc_end: ?*LOLHTML.DocEnd, - pub usingnamespace JSC.Codegen.JSDocEnd; + pub const js = JSC.Codegen.JSDocEnd; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; pub fn init(doc_end: *LOLHTML.DocEnd) *DocEnd { return bun.new(DocEnd, .{ @@ -1322,7 +1334,10 @@ pub const Comment = struct { ref_count: RefCount, comment: ?*LOLHTML.Comment = null, - pub usingnamespace JSC.Codegen.JSComment; + pub const js = JSC.Codegen.JSComment; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; pub fn init(comment: *LOLHTML.Comment) *Comment { return bun.new(Comment, .{ @@ -1475,7 +1490,10 @@ pub const EndTag = struct { pub const onEndTagHandler = LOLHTML.DirectiveHandler(LOLHTML.EndTag, Handler, onEndTag); }; - pub usingnamespace JSC.Codegen.JSEndTag; + pub const js = JSC.Codegen.JSEndTag; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; fn contentHandler(this: *EndTag, comptime Callback: (fn (*LOLHTML.EndTag, []const u8, bool) LOLHTML.Error!void), thisObject: JSValue, globalObject: *JSGlobalObject, content: ZigString, contentOptions: ?ContentOptions) JSValue { if (this.end_tag == null) @@ -1599,7 +1617,10 @@ pub const AttributeIterator = struct { bun.destroy(this); } - pub usingnamespace JSC.Codegen.JSAttributeIterator; + pub const js = JSC.Codegen.JSAttributeIterator; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; pub fn next(this: *AttributeIterator, globalObject: *JSGlobalObject, _: *JSC.CallFrame) bun.JSError!JSValue { const done_label = JSC.ZigString.static("done"); @@ -1639,7 +1660,10 @@ pub const Element = struct { ref_count: RefCount, element: ?*LOLHTML.Element = null, - pub usingnamespace JSC.Codegen.JSElement; + pub const js = JSC.Codegen.JSElement; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; pub fn init(element: *LOLHTML.Element) *Element { return bun.new(Element, .{ diff --git a/src/bun.js/api/server.zig b/src/bun.js/api/server.zig index 04651d4573..59df543db9 100644 --- a/src/bun.js/api/server.zig +++ b/src/bun.js/api/server.zig @@ -1,6 +1,6 @@ const Bun = @This(); const default_allocator = bun.default_allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const Environment = bun.Environment; const AnyBlob = bun.JSC.WebCore.AnyBlob; const Global = bun.Global; @@ -42,14 +42,12 @@ const Headers = WebCore.Headers; const Fetch = WebCore.Fetch; const HTTP = bun.http; const FetchEvent = WebCore.FetchEvent; -const js = bun.JSC.C; const JSC = bun.JSC; const MarkedArrayBuffer = @import("../base.zig").MarkedArrayBuffer; const getAllocator = @import("../base.zig").getAllocator; const JSValue = bun.JSC.JSValue; const JSGlobalObject = bun.JSC.JSGlobalObject; -const ExceptionValueRef = bun.JSC.ExceptionValueRef; const JSPrivateDataPtr = bun.JSC.JSPrivateDataPtr; const ConsoleObject = bun.JSC.ConsoleObject; const Node = bun.JSC.Node; @@ -2905,7 +2903,7 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp // use node syscall so that we don't segfault on BADF if (sendfile.auto_close) - _ = bun.sys.close(sendfile.fd); + sendfile.fd.close(); } const separator: string = "\r\n"; const separator_iovec = [1]std.posix.iovec_const{.{ @@ -3056,7 +3054,7 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp .err => |err| { this.runErrorHandler(err.withPathLike(file.pathlike).toJSC(globalThis)); if (auto_close) { - _ = bun.sys.close(fd); + fd.close(); } return; }, @@ -3065,7 +3063,7 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp if (Environment.isMac) { if (!bun.isRegularFile(stat.mode)) { if (auto_close) { - _ = bun.sys.close(fd); + fd.close(); } var err = bun.sys.Error{ @@ -3084,7 +3082,7 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp if (Environment.isLinux) { if (!(bun.isRegularFile(stat.mode) or std.posix.S.ISFIFO(stat.mode) or std.posix.S.ISSOCK(stat.mode))) { if (auto_close) { - _ = bun.sys.close(fd); + fd.close(); } var err = bun.sys.Error{ @@ -5821,7 +5819,7 @@ pub fn NewServer(comptime NamespaceType: type, comptime ssl_enabled_: bool, comp false, ); } else { - const fetch_error = JSC.WebCore.Fetch.fetch_type_error_strings.get(js.JSValueGetType(ctx, first_arg.asRef())); + const fetch_error = JSC.WebCore.Fetch.fetch_type_error_strings.get(bun.JSC.C.JSValueGetType(ctx, first_arg.asRef())); const err = JSC.toTypeError(.ERR_INVALID_ARG_TYPE, "{s}", .{fetch_error}, ctx); return JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(ctx, err); diff --git a/src/bun.js/api/server/HTMLBundle.zig b/src/bun.js/api/server/HTMLBundle.zig index d3bc6d45b6..0e82d73e91 100644 --- a/src/bun.js/api/server/HTMLBundle.zig +++ b/src/bun.js/api/server/HTMLBundle.zig @@ -2,7 +2,11 @@ //! HTML file, and can be passed to the `static` option in `Bun.serve`. The build //! is done lazily (state held in HTMLBundle.Route or DevServer.RouteBundle.HTML). pub const HTMLBundle = @This(); -pub usingnamespace JSC.Codegen.JSHTMLBundle; +pub const js = JSC.Codegen.JSHTMLBundle; +pub const toJS = js.toJS; +pub const fromJS = js.fromJS; +pub const fromJSDirect = js.fromJSDirect; + /// HTMLBundle can be owned by JavaScript as well as any number of Server instances. const RefCount = bun.ptr.RefCount(@This(), "ref_count", deinit, .{}); pub const ref = RefCount.ref; @@ -496,7 +500,7 @@ pub const Route = struct { }; }; -const bun = @import("root").bun; +const bun = @import("bun"); const std = @import("std"); const JSC = bun.JSC; const JSValue = JSC.JSValue; diff --git a/src/bun.js/api/server/NodeHTTPResponse.zig b/src/bun.js/api/server/NodeHTTPResponse.zig index 5a0b0b9b34..7062691884 100644 --- a/src/bun.js/api/server/NodeHTTPResponse.zig +++ b/src/bun.js/api/server/NodeHTTPResponse.zig @@ -1,7 +1,11 @@ const NodeHTTPResponse = @This(); const log = bun.Output.scoped(.NodeHTTPResponse, false); -pub usingnamespace JSC.Codegen.JSNodeHTTPResponse; +pub const js = JSC.Codegen.JSNodeHTTPResponse; +pub const toJS = js.toJS; +pub const fromJS = js.fromJS; +pub const fromJSDirect = js.fromJSDirect; + const RefCount = bun.ptr.RefCount(@This(), "ref_count", deinit, .{}); pub const ref = RefCount.ref; pub const deref = RefCount.deref; @@ -138,7 +142,7 @@ pub fn upgrade(this: *NodeHTTPResponse, data_value: JSValue, sec_websocket_proto defer if (new_socket) |socket| { this.flags.upgraded = true; Bun__setNodeHTTPServerSocketUsSocketValue(socketValue, socket); - ServerWebSocket.socketSetCached(ws.getThisValue(), ws_handler.globalObject, socketValue); + ServerWebSocket.js.socketSetCached(ws.getThisValue(), ws_handler.globalObject, socketValue); defer this.js_ref.unref(JSC.VirtualMachine.get()); switch (this.raw_response) { .SSL => this.raw_response = uws.AnyResponse.init(uws.NewApp(true).Response.castRes(@alignCast(@ptrCast(socket)))), @@ -219,7 +223,10 @@ pub fn upgrade(this: *NodeHTTPResponse, data_value: JSValue, sec_websocket_proto pub fn maybeStopReadingBody(this: *NodeHTTPResponse, vm: *JSC.VirtualMachine, thisValue: JSC.JSValue) void { this.upgrade_context.deinit(); // we can discard the upgrade context now - if ((this.flags.socket_closed or this.flags.ended) and (this.body_read_ref.has or this.body_read_state == .pending) and (!this.flags.hasCustomOnData or NodeHTTPResponse.onDataGetCached(thisValue) == null)) { + if ((this.flags.socket_closed or this.flags.ended) and + (this.body_read_ref.has or this.body_read_state == .pending) and + (!this.flags.hasCustomOnData or js.onDataGetCached(thisValue) == null)) + { const had_ref = this.body_read_ref.has; this.raw_response.clearOnData(); this.body_read_ref.unref(vm); @@ -531,11 +538,11 @@ fn handleAbortOrTimeout(this: *NodeHTTPResponse, comptime event: AbortEvent, js_ defer if (event == .abort) this.markRequestAsDoneIfNecessary(); const js_this: JSValue = if (js_value == .zero) this.getThisValue() else js_value; - if (NodeHTTPResponse.onAbortedGetCached(js_this)) |on_aborted| { + if (js.onAbortedGetCached(js_this)) |on_aborted| { const globalThis = JSC.VirtualMachine.get().global; defer { if (event == .abort) { - NodeHTTPResponse.onAbortedSetCached(js_this, globalThis, .zero); + js.onAbortedSetCached(js_this, globalThis, .zero); } } @@ -567,7 +574,7 @@ pub fn doPause(this: *NodeHTTPResponse, _: *JSC.JSGlobalObject, _: *JSC.CallFram if (this.flags.request_has_completed or this.flags.socket_closed or this.flags.ended) { return .false; } - if (this.body_read_ref.has and NodeHTTPResponse.onDataGetCached(thisValue) == null) { + if (this.body_read_ref.has and js.onDataGetCached(thisValue) == null) { this.flags.is_data_buffered_during_pause = true; this.raw_response.onData(*NodeHTTPResponse, onBufferRequestBodyWhilePaused, this); } @@ -634,7 +641,7 @@ pub export fn Bun__NodeHTTPRequest__onResolve(globalObject: *JSC.JSGlobalObject, if (!this.flags.request_has_completed and !this.flags.socket_closed) { const this_value = this.getThisValue(); if (this_value != .zero) { - NodeHTTPResponse.onAbortedSetCached(this_value, globalObject, .zero); + js.onAbortedSetCached(this_value, globalObject, .zero); } this.raw_response.clearOnData(); this.raw_response.clearOnWritable(); @@ -660,7 +667,7 @@ pub export fn Bun__NodeHTTPRequest__onReject(globalObject: *JSC.JSGlobalObject, if (!this.flags.request_has_completed and !this.flags.socket_closed) { const this_value = this.getThisValue(); if (this_value != .zero) { - NodeHTTPResponse.onAbortedSetCached(this_value, globalObject, .zero); + js.onAbortedSetCached(this_value, globalObject, .zero); } this.raw_response.clearOnData(); this.raw_response.clearOnWritable(); @@ -724,7 +731,7 @@ fn onDataOrAborted(this: *NodeHTTPResponse, chunk: []const u8, last: bool, event } } - if (NodeHTTPResponse.onDataGetCached(thisValue)) |callback| { + if (js.onDataGetCached(thisValue)) |callback| { if (callback == .undefined) { return; } @@ -778,9 +785,9 @@ fn onDrain(this: *NodeHTTPResponse, offset: u64, response: uws.AnyResponse) bool return false; } const thisValue = this.getThisValue(); - const on_writable = NodeHTTPResponse.onWritableGetCached(thisValue) orelse return false; + const on_writable = js.onWritableGetCached(thisValue) orelse return false; const globalThis = JSC.VirtualMachine.get().global; - NodeHTTPResponse.onWritableSetCached(thisValue, globalThis, .undefined); // TODO(@heimskr): is this necessary? + js.onWritableSetCached(thisValue, globalThis, .undefined); // TODO(@heimskr): is this necessary? const vm = globalThis.bunVM(); response.corked(JSC.EventLoop.runCallback, .{ vm.eventLoop(), on_writable, globalThis, .undefined, &.{JSC.JSValue.jsNumberFromUint64(offset)} }); @@ -861,13 +868,13 @@ fn writeOrEnd( if (is_end) { // Discard the body read ref if it's pending and no onData callback is set at this point. // This is the equivalent of req._dump(). - if (this.body_read_ref.has and this.body_read_state == .pending and (!this.flags.hasCustomOnData or NodeHTTPResponse.onDataGetCached(this_value) == null)) { + if (this.body_read_ref.has and this.body_read_state == .pending and (!this.flags.hasCustomOnData or js.onDataGetCached(this_value) == null)) { this.body_read_ref.unref(JSC.VirtualMachine.get()); this.body_read_state = .none; } if (this_value != .zero) { - NodeHTTPResponse.onAbortedSetCached(this_value, globalObject, .zero); + js.onAbortedSetCached(this_value, globalObject, .zero); } this.raw_response.clearAborted(); @@ -887,12 +894,12 @@ fn writeOrEnd( switch (this.raw_response.write(bytes)) { .want_more => |written| { this.raw_response.clearOnWritable(); - NodeHTTPResponse.onWritableSetCached(js_this, globalObject, .undefined); + js.onWritableSetCached(js_this, globalObject, .undefined); return JSC.JSValue.jsNumberFromUint64(written); }, .backpressure => |written| { if (callback_value != .undefined) { - NodeHTTPResponse.onWritableSetCached(js_this, globalObject, callback_value.withAsyncContextIfNeeded(globalObject)); + js.onWritableSetCached(js_this, globalObject, callback_value.withAsyncContextIfNeeded(globalObject)); this.raw_response.onWritable(*NodeHTTPResponse, onDrain, this); } @@ -904,23 +911,23 @@ fn writeOrEnd( pub fn setOnWritable(this: *NodeHTTPResponse, thisValue: JSC.JSValue, globalObject: *JSC.JSGlobalObject, value: JSValue) bool { if (this.isDone() or value == .undefined) { - NodeHTTPResponse.onWritableSetCached(thisValue, globalObject, .undefined); + js.onWritableSetCached(thisValue, globalObject, .undefined); } else { - NodeHTTPResponse.onWritableSetCached(thisValue, globalObject, value.withAsyncContextIfNeeded(globalObject)); + js.onWritableSetCached(thisValue, globalObject, value.withAsyncContextIfNeeded(globalObject)); } return true; } pub fn getOnWritable(_: *NodeHTTPResponse, thisValue: JSC.JSValue, _: *JSC.JSGlobalObject) JSC.JSValue { - return NodeHTTPResponse.onWritableGetCached(thisValue) orelse .undefined; + return js.onWritableGetCached(thisValue) orelse .undefined; } pub fn getOnAbort(this: *NodeHTTPResponse, thisValue: JSC.JSValue, _: *JSC.JSGlobalObject) JSC.JSValue { if (this.flags.socket_closed) { return .undefined; } - return NodeHTTPResponse.onAbortedGetCached(thisValue) orelse .undefined; + return js.onAbortedGetCached(thisValue) orelse .undefined; } pub fn setOnAbort(this: *NodeHTTPResponse, thisValue: JSC.JSValue, globalObject: *JSC.JSGlobalObject, value: JSValue) bool { @@ -929,16 +936,16 @@ pub fn setOnAbort(this: *NodeHTTPResponse, thisValue: JSC.JSValue, globalObject: } if (this.isDone() or value == .undefined) { - NodeHTTPResponse.onAbortedSetCached(thisValue, globalObject, .zero); + js.onAbortedSetCached(thisValue, globalObject, .zero); } else { - NodeHTTPResponse.onAbortedSetCached(thisValue, globalObject, value.withAsyncContextIfNeeded(globalObject)); + js.onAbortedSetCached(thisValue, globalObject, value.withAsyncContextIfNeeded(globalObject)); } return true; } pub fn getOnData(_: *NodeHTTPResponse, thisValue: JSC.JSValue, _: *JSC.JSGlobalObject) JSC.JSValue { - return NodeHTTPResponse.onDataGetCached(thisValue) orelse .undefined; + return js.onDataGetCached(thisValue) orelse .undefined; } pub fn getHasCustomOnData(this: *NodeHTTPResponse, _: *JSC.JSGlobalObject) JSC.JSValue { @@ -957,7 +964,7 @@ pub fn setHasCustomOnData(this: *NodeHTTPResponse, _: *JSC.JSGlobalObject, value fn clearOnDataCallback(this: *NodeHTTPResponse, thisValue: JSC.JSValue, globalObject: *JSC.JSGlobalObject) void { if (this.body_read_state != .none) { if (thisValue != .zero) { - NodeHTTPResponse.onDataSetCached(thisValue, globalObject, .undefined); + js.onDataSetCached(thisValue, globalObject, .undefined); } if (!this.flags.socket_closed) this.raw_response.clearOnData(); @@ -969,7 +976,7 @@ fn clearOnDataCallback(this: *NodeHTTPResponse, thisValue: JSC.JSValue, globalOb pub fn setOnData(this: *NodeHTTPResponse, thisValue: JSC.JSValue, globalObject: *JSC.JSGlobalObject, value: JSValue) bool { if (value == .undefined or this.flags.ended or this.flags.socket_closed or this.body_read_state == .none or this.flags.is_data_buffered_during_pause_last) { - NodeHTTPResponse.onDataSetCached(thisValue, globalObject, .undefined); + js.onDataSetCached(thisValue, globalObject, .undefined); defer { if (this.body_read_ref.has) { this.body_read_ref.unref(globalObject.bunVM()); @@ -987,7 +994,7 @@ pub fn setOnData(this: *NodeHTTPResponse, thisValue: JSC.JSValue, globalObject: return true; } - NodeHTTPResponse.onDataSetCached(thisValue, globalObject, value.withAsyncContextIfNeeded(globalObject)); + js.onDataSetCached(thisValue, globalObject, value.withAsyncContextIfNeeded(globalObject)); this.flags.hasCustomOnData = true; this.raw_response.onData(*NodeHTTPResponse, onData, this); this.flags.is_data_buffered_during_pause = false; @@ -1113,7 +1120,7 @@ const JSGlobalObject = JSC.JSGlobalObject; const JSObject = JSC.JSObject; const JSValue = JSC.JSValue; const JSC = bun.JSC; -const bun = @import("root").bun; +const bun = @import("bun"); const string = []const u8; const Bun = JSC.API.Bun; const max_addressable_memory = bun.max_addressable_memory; diff --git a/src/bun.js/api/server/ServerWebSocket.zig b/src/bun.js/api/server/ServerWebSocket.zig index 04c9c7664d..185787c7bc 100644 --- a/src/bun.js/api/server/ServerWebSocket.zig +++ b/src/bun.js/api/server/ServerWebSocket.zig @@ -27,7 +27,11 @@ inline fn websocket(this: *const ServerWebSocket) uws.AnyWebSocket { return this.flags.websocket(); } -pub usingnamespace JSC.Codegen.JSServerWebSocket; +pub const js = JSC.Codegen.JSServerWebSocket; +pub const toJS = js.toJS; +pub const fromJS = js.fromJS; +pub const fromJSDirect = js.fromJSDirect; + pub const new = bun.TrivialNew(ServerWebSocket); pub fn memoryCost(this: *const ServerWebSocket) usize { @@ -64,7 +68,7 @@ pub fn onOpen(this: *ServerWebSocket, ws: uws.AnyWebSocket) void { this.flags.opened = false; if (value_to_cache != .zero) { const current_this = this.getThisValue(); - ServerWebSocket.dataSetCached(current_this, globalObject, value_to_cache); + js.dataSetCached(current_this, globalObject, value_to_cache); } if (onOpenHandler.isEmptyOrUndefinedOrNull()) return; @@ -289,7 +293,7 @@ pub fn onClose(this: *ServerWebSocket, _: uws.AnyWebSocket, code: i32, message: const signal = this.signal; this.signal = null; - if (ServerWebSocket.socketGetCached(this.getThisValue())) |socket| { + if (js.socketGetCached(this.getThisValue())) |socket| { Bun__callNodeHTTPServerSocketOnClose(socket); } @@ -1032,7 +1036,7 @@ pub fn setData( value: JSC.JSValue, ) callconv(.C) bool { log("setData()", .{}); - ServerWebSocket.dataSetCached(this.this_value, globalObject, value); + js.dataSetCached(this.this_value, globalObject, value); return true; } @@ -1284,7 +1288,7 @@ const JSGlobalObject = JSC.JSGlobalObject; const JSObject = JSC.JSObject; const JSValue = JSC.JSValue; const JSC = bun.JSC; -const bun = @import("root").bun; +const bun = @import("bun"); const string = []const u8; const Bun = JSC.API.Bun; const max_addressable_memory = bun.max_addressable_memory; diff --git a/src/bun.js/api/server/StaticRoute.zig b/src/bun.js/api/server/StaticRoute.zig index 3aae794479..8b6eca8073 100644 --- a/src/bun.js/api/server/StaticRoute.zig +++ b/src/bun.js/api/server/StaticRoute.zig @@ -343,7 +343,7 @@ pub fn onWithMethod(this: *StaticRoute, method: bun.http.Method, resp: AnyRespon } const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Api = @import("../../../api/schema.zig").Api; const JSC = bun.JSC; diff --git a/src/bun.js/base.zig b/src/bun.js/base.zig index a0c4cb8401..0ba3eef83f 100644 --- a/src/bun.js/base.zig +++ b/src/bun.js/base.zig @@ -1,6 +1,5 @@ -pub const js = bun.JSC.C; const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; @@ -18,8 +17,7 @@ const TaggedPointerTypes = @import("../ptr.zig"); const TaggedPointerUnion = TaggedPointerTypes.TaggedPointerUnion; const JSError = bun.JSError; -pub const ExceptionValueRef = [*c]js.JSValueRef; -pub const JSValueRef = js.JSValueRef; +pub const JSValueRef = bun.JSC.C.JSValueRef; pub const Lifetime = enum { allocated, @@ -151,15 +149,6 @@ pub const Properties = struct { pub const navigate = "navigate"; pub const follow = "follow"; }; - - pub const Refs = struct { - pub var empty_string_ptr = [_]u8{0}; - pub var empty_string: js.JSStringRef = undefined; - }; - - pub fn init() void { - Refs.empty_string = js.JSStringCreateWithUTF8CString(&Refs.empty_string_ptr); - } }; pub const PathString = bun.PathString; @@ -194,7 +183,7 @@ fn toTypeErrorWithCode( code: []const u8, comptime fmt: string, args: anytype, - ctx: js.JSContextRef, + ctx: *JSC.JSGlobalObject, ) JSC.JSValue { @branchHint(.cold); var zig_str: JSC.ZigString = undefined; @@ -215,31 +204,21 @@ pub fn toTypeError( code: JSC.Error, comptime fmt: [:0]const u8, args: anytype, - ctx: js.JSContextRef, + ctx: *JSC.JSGlobalObject, ) JSC.JSValue { return code.fmt(ctx, fmt, args); } -pub fn throwInvalidArguments( - comptime fmt: [:0]const u8, - args: anytype, - ctx: js.JSContextRef, - exception: ExceptionValueRef, -) void { - @branchHint(.cold); - exception.* = JSC.Error.ERR_INVALID_ARG_TYPE.fmt(ctx, fmt, args).asObjectRef(); -} - pub fn toInvalidArguments( comptime fmt: [:0]const u8, args: anytype, - ctx: js.JSContextRef, + ctx: *JSC.JSGlobalObject, ) JSC.JSValue { @branchHint(.cold); return JSC.Error.ERR_INVALID_ARG_TYPE.fmt(ctx, fmt, args); } -pub fn getAllocator(_: js.JSContextRef) std.mem.Allocator { +pub fn getAllocator(_: *JSC.JSGlobalObject) std.mem.Allocator { return default_allocator; } @@ -251,7 +230,7 @@ pub fn dump(value: JSC.WebCore.JSValue, globalObject: *JSC.JSGlobalObject) !void Output.flush(); } -pub const JSStringList = std.ArrayList(js.JSStringRef); +pub const JSStringList = std.ArrayList(JSC.C.JSStringRef); pub const ArrayBuffer = extern struct { ptr: [*]u8 = undefined, @@ -326,7 +305,7 @@ pub const ArrayBuffer = extern struct { pub fn toJSBufferFromMemfd(fd: bun.FileDescriptor, globalObject: *JSC.JSGlobalObject) bun.JSError!JSC.JSValue { const stat = switch (bun.sys.fstat(fd)) { .err => |err| { - _ = bun.sys.close(fd); + fd.close(); return globalObject.throwValue(err.toJSC(globalObject)); }, .result => |fstat| fstat, @@ -335,7 +314,7 @@ pub const ArrayBuffer = extern struct { const size = stat.size; if (size == 0) { - _ = bun.sys.close(fd); + fd.close(); return createBuffer(globalObject, ""); } @@ -345,7 +324,7 @@ pub const ArrayBuffer = extern struct { // So we clone it when it's small. if (size < mmap_threshold) { const result = toJSBufferFromFd(fd, @intCast(size), globalObject); - _ = bun.sys.close(fd); + fd.close(); return result; } @@ -357,7 +336,7 @@ pub const ArrayBuffer = extern struct { fd, 0, ); - _ = bun.sys.close(fd); + fd.close(); switch (result) { .result => |buf| { @@ -445,7 +424,7 @@ pub const ArrayBuffer = extern struct { extern "c" fn Bun__createUint8ArrayForCopy(*JSC.JSGlobalObject, ptr: ?*const anyopaque, len: usize, buffer: bool) JSC.JSValue; extern "c" fn Bun__createArrayBufferForCopy(*JSC.JSGlobalObject, ptr: ?*const anyopaque, len: usize) JSC.JSValue; - pub fn fromTypedArray(ctx: JSC.C.JSContextRef, value: JSC.JSValue) ArrayBuffer { + pub fn fromTypedArray(ctx: *JSC.JSGlobalObject, value: JSC.JSValue) ArrayBuffer { var out = std.mem.zeroes(ArrayBuffer); const was = value.asArrayBuffer_(ctx, &out); bun.assert(was); @@ -470,7 +449,7 @@ pub const ArrayBuffer = extern struct { return ArrayBuffer{ .offset = 0, .len = @as(u32, @intCast(bytes.len)), .byte_len = @as(u32, @intCast(bytes.len)), .typed_array_type = typed_array_type, .ptr = bytes.ptr }; } - pub fn toJSUnchecked(this: ArrayBuffer, ctx: JSC.C.JSContextRef, exception: JSC.C.ExceptionRef) JSC.JSValue { + pub fn toJSUnchecked(this: ArrayBuffer, ctx: *JSC.JSGlobalObject, exception: JSC.C.ExceptionRef) JSC.JSValue { // The reason for this is // JSC C API returns a detached arraybuffer @@ -513,7 +492,7 @@ pub const ArrayBuffer = extern struct { const log = Output.scoped(.ArrayBuffer, false); - pub fn toJS(this: ArrayBuffer, ctx: JSC.C.JSContextRef, exception: JSC.C.ExceptionRef) JSC.JSValue { + pub fn toJS(this: ArrayBuffer, ctx: *JSC.JSGlobalObject, exception: JSC.C.ExceptionRef) JSC.JSValue { if (this.value != .zero) { return this.value; } @@ -549,7 +528,7 @@ pub const ArrayBuffer = extern struct { pub fn toJSWithContext( this: ArrayBuffer, - ctx: JSC.C.JSContextRef, + ctx: *JSC.JSGlobalObject, deallocator: ?*anyopaque, callback: JSC.C.JSTypedArrayBytesDeallocator, exception: JSC.C.ExceptionRef, @@ -621,14 +600,14 @@ pub const MarkedArrayBuffer = struct { return this.buffer.stream(); } - pub fn fromTypedArray(ctx: JSC.C.JSContextRef, value: JSC.JSValue) MarkedArrayBuffer { + pub fn fromTypedArray(ctx: *JSC.JSGlobalObject, value: JSC.JSValue) MarkedArrayBuffer { return MarkedArrayBuffer{ .allocator = null, .buffer = ArrayBuffer.fromTypedArray(ctx, value), }; } - pub fn fromArrayBuffer(ctx: JSC.C.JSContextRef, value: JSC.JSValue) MarkedArrayBuffer { + pub fn fromArrayBuffer(ctx: *JSC.JSGlobalObject, value: JSC.JSValue) MarkedArrayBuffer { return MarkedArrayBuffer{ .allocator = null, .buffer = ArrayBuffer.fromArrayBuffer(ctx, value), @@ -677,16 +656,16 @@ pub const MarkedArrayBuffer = struct { return container; } - pub fn toNodeBuffer(this: *const MarkedArrayBuffer, ctx: js.JSContextRef) JSC.JSValue { + pub fn toNodeBuffer(this: *const MarkedArrayBuffer, ctx: *JSC.JSGlobalObject) JSC.JSValue { return JSC.JSValue.createBufferWithCtx(ctx, this.buffer.byteSlice(), this.buffer.ptr, MarkedArrayBuffer_deallocator); } - pub fn toJSObjectRef(this: *const MarkedArrayBuffer, ctx: js.JSContextRef, exception: js.ExceptionRef) js.JSObjectRef { + pub fn toJSObjectRef(this: *const MarkedArrayBuffer, ctx: *JSC.JSGlobalObject, exception: JSC.C.ExceptionRef) bun.JSC.C.JSObjectRef { if (!this.buffer.value.isEmptyOrUndefinedOrNull()) { return this.buffer.value.asObjectRef(); } if (this.buffer.byte_len == 0) { - return js.JSObjectMakeTypedArray( + return JSC.C.JSObjectMakeTypedArray( ctx, this.buffer.typed_array_type.toC(), 0, @@ -694,7 +673,7 @@ pub const MarkedArrayBuffer = struct { ); } - return js.JSObjectMakeTypedArrayWithBytesNoCopy( + return JSC.C.JSObjectMakeTypedArrayWithBytesNoCopy( ctx, this.buffer.typed_array_type.toC(), this.buffer.ptr, @@ -829,16 +808,16 @@ const MD5_SHA1 = JSC.API.Bun.Crypto.MD5_SHA1; const FFI = JSC.FFI; pub const JSPropertyNameIterator = struct { - array: js.JSPropertyNameArrayRef, + array: JSC.C.JSPropertyNameArrayRef, count: u32, i: u32 = 0, - pub fn next(this: *JSPropertyNameIterator) ?js.JSStringRef { + pub fn next(this: *JSPropertyNameIterator) ?JSC.C.JSStringRef { if (this.i >= this.count) return null; const i = this.i; this.i += 1; - return js.JSPropertyNameArrayGetNameAtIndex(this.array, i); + return JSC.C.JSPropertyNameArrayGetNameAtIndex(this.array, i); } }; diff --git a/src/bun.js/bindgen_test.zig b/src/bun.js/bindgen_test.zig index 1d0d0d5e31..3f3f636d8a 100644 --- a/src/bun.js/bindgen_test.zig +++ b/src/bun.js/bindgen_test.zig @@ -32,5 +32,5 @@ pub fn requiredAndOptionalArg(a: bool, b: ?usize, c: i32, d: ?u8) i32 { } const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; diff --git a/src/bun.js/bindings/AbortSignal.zig b/src/bun.js/bindings/AbortSignal.zig index 960f6ce1e8..693cff1fb4 100644 --- a/src/bun.js/bindings/AbortSignal.zig +++ b/src/bun.js/bindings/AbortSignal.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const JSValue = JSC.JSValue; const JSGlobalObject = JSC.JSGlobalObject; diff --git a/src/bun.js/bindings/AnyPromise.zig b/src/bun.js/bindings/AnyPromise.zig index 8012aeded8..192ef00c22 100644 --- a/src/bun.js/bindings/AnyPromise.zig +++ b/src/bun.js/bindings/AnyPromise.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const JSValue = JSC.JSValue; const JSGlobalObject = JSC.JSGlobalObject; diff --git a/src/bun.js/bindings/CPUFeatures.zig b/src/bun.js/bindings/CPUFeatures.zig index 668d9144b5..7efefbc5c8 100644 --- a/src/bun.js/bindings/CPUFeatures.zig +++ b/src/bun.js/bindings/CPUFeatures.zig @@ -68,4 +68,4 @@ pub fn get() CPUFeatures { } const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); diff --git a/src/bun.js/bindings/CachedBytecode.zig b/src/bun.js/bindings/CachedBytecode.zig index 08758d8584..a365c12944 100644 --- a/src/bun.js/bindings/CachedBytecode.zig +++ b/src/bun.js/bindings/CachedBytecode.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); pub const CachedBytecode = opaque { extern fn generateCachedModuleByteCodeFromSourceCode(sourceProviderURL: *bun.String, input_code: [*]const u8, inputSourceCodeSize: usize, outputByteCode: *?[*]u8, outputByteCodeSize: *usize, cached_bytecode: *?*CachedBytecode) bool; diff --git a/src/bun.js/bindings/CallFrame.zig b/src/bun.js/bindings/CallFrame.zig index 9f310961ab..8d105dde18 100644 --- a/src/bun.js/bindings/CallFrame.zig +++ b/src/bun.js/bindings/CallFrame.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const JSGlobalObject = JSC.JSGlobalObject; const JSValue = JSC.JSValue; diff --git a/src/bun.js/bindings/CommonAbortReason.zig b/src/bun.js/bindings/CommonAbortReason.zig index 8d93622e11..c0d630d7ca 100644 --- a/src/bun.js/bindings/CommonAbortReason.zig +++ b/src/bun.js/bindings/CommonAbortReason.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const JSValue = JSC.JSValue; const JSGlobalObject = JSC.JSGlobalObject; diff --git a/src/bun.js/bindings/CommonStrings.zig b/src/bun.js/bindings/CommonStrings.zig index a7d0a5559d..ee0c4de574 100644 --- a/src/bun.js/bindings/CommonStrings.zig +++ b/src/bun.js/bindings/CommonStrings.zig @@ -29,7 +29,7 @@ pub const CommonStrings = struct { }; const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const JSValue = JSC.JSValue; const VM = JSC.VM; diff --git a/src/bun.js/bindings/CustomGetterSetter.zig b/src/bun.js/bindings/CustomGetterSetter.zig index b0484f7641..37eeedefaf 100644 --- a/src/bun.js/bindings/CustomGetterSetter.zig +++ b/src/bun.js/bindings/CustomGetterSetter.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; pub const CustomGetterSetter = opaque { diff --git a/src/bun.js/bindings/DOMFormData.zig b/src/bun.js/bindings/DOMFormData.zig index 0a658b8c60..2633859d02 100644 --- a/src/bun.js/bindings/DOMFormData.zig +++ b/src/bun.js/bindings/DOMFormData.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const JSValue = JSC.JSValue; const JSGlobalObject = JSC.JSGlobalObject; diff --git a/src/bun.js/bindings/DOMURL.zig b/src/bun.js/bindings/DOMURL.zig index 3d1050bf1d..36444bdb6f 100644 --- a/src/bun.js/bindings/DOMURL.zig +++ b/src/bun.js/bindings/DOMURL.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const JSValue = JSC.JSValue; const JSGlobalObject = JSC.JSGlobalObject; diff --git a/src/bun.js/bindings/Debugger.zig b/src/bun.js/bindings/Debugger.zig index 3d9fc450c1..47ea34bb16 100644 --- a/src/bun.js/bindings/Debugger.zig +++ b/src/bun.js/bindings/Debugger.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; pub const Debugger = struct { diff --git a/src/bun.js/bindings/DeferredError.zig b/src/bun.js/bindings/DeferredError.zig index 48298ac690..94c30f1d95 100644 --- a/src/bun.js/bindings/DeferredError.zig +++ b/src/bun.js/bindings/DeferredError.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const JSGlobalObject = JSC.JSGlobalObject; const JSValue = JSC.JSValue; diff --git a/src/bun.js/bindings/EncodedJSValue.zig b/src/bun.js/bindings/EncodedJSValue.zig index 604e5c2d01..9d331d60af 100644 --- a/src/bun.js/bindings/EncodedJSValue.zig +++ b/src/bun.js/bindings/EncodedJSValue.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const JSCell = @import("./JSCell.zig").JSCell; diff --git a/src/bun.js/bindings/Errorable.zig b/src/bun.js/bindings/Errorable.zig index a1aac13d03..779bc26322 100644 --- a/src/bun.js/bindings/Errorable.zig +++ b/src/bun.js/bindings/Errorable.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const std = @import("std"); const ZigErrorType = @import("ZigErrorType.zig").ZigErrorType; const ErrorCode = @import("ErrorCode.zig").ErrorCode; diff --git a/src/bun.js/bindings/EventType.zig b/src/bun.js/bindings/EventType.zig index 01c0c72cec..4edf9ca600 100644 --- a/src/bun.js/bindings/EventType.zig +++ b/src/bun.js/bindings/EventType.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; pub const EventType = enum(u8) { diff --git a/src/bun.js/bindings/Exception.zig b/src/bun.js/bindings/Exception.zig index 754a845a62..97a6e862c2 100644 --- a/src/bun.js/bindings/Exception.zig +++ b/src/bun.js/bindings/Exception.zig @@ -1,5 +1,5 @@ const JSC = bun.JSC; -const bun = @import("root").bun; +const bun = @import("bun"); const JSGlobalObject = JSC.JSGlobalObject; const ZigStackTrace = @import("ZigStackTrace.zig").ZigStackTrace; const JSValue = JSC.JSValue; diff --git a/src/bun.js/bindings/FetchHeaders.zig b/src/bun.js/bindings/FetchHeaders.zig index 8e431c48d2..b9026fac55 100644 --- a/src/bun.js/bindings/FetchHeaders.zig +++ b/src/bun.js/bindings/FetchHeaders.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const JSValue = JSC.JSValue; const JSGlobalObject = JSC.JSGlobalObject; diff --git a/src/bun.js/bindings/GetterSetter.zig b/src/bun.js/bindings/GetterSetter.zig index 71b4ffb52d..57c4b5a2f0 100644 --- a/src/bun.js/bindings/GetterSetter.zig +++ b/src/bun.js/bindings/GetterSetter.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; pub const GetterSetter = opaque { diff --git a/src/bun.js/bindings/JSArray.zig b/src/bun.js/bindings/JSArray.zig index 6cd53231f4..cdf8cd5f66 100644 --- a/src/bun.js/bindings/JSArray.zig +++ b/src/bun.js/bindings/JSArray.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const JSGlobalObject = JSC.JSGlobalObject; const JSValue = JSC.JSValue; diff --git a/src/bun.js/bindings/JSArrayIterator.zig b/src/bun.js/bindings/JSArrayIterator.zig index 185141322c..1ed65ddc2b 100644 --- a/src/bun.js/bindings/JSArrayIterator.zig +++ b/src/bun.js/bindings/JSArrayIterator.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const JSC = bun.JSC; const JSValue = JSC.JSValue; diff --git a/src/bun.js/bindings/JSCell.zig b/src/bun.js/bindings/JSCell.zig index 17d5f9837e..7bc75757fa 100644 --- a/src/bun.js/bindings/JSCell.zig +++ b/src/bun.js/bindings/JSCell.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const GetterSetter = @import("GetterSetter.zig").GetterSetter; const CustomGetterSetter = @import("CustomGetterSetter.zig").CustomGetterSetter; const FFI = @import("FFI.zig"); diff --git a/src/bun.js/bindings/JSFunction.zig b/src/bun.js/bindings/JSFunction.zig index ae1363d08a..151baa7677 100644 --- a/src/bun.js/bindings/JSFunction.zig +++ b/src/bun.js/bindings/JSFunction.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const JSC = bun.JSC; diff --git a/src/bun.js/bindings/JSGlobalObject.zig b/src/bun.js/bindings/JSGlobalObject.zig index 109f3c44a0..4fef77dfce 100644 --- a/src/bun.js/bindings/JSGlobalObject.zig +++ b/src/bun.js/bindings/JSGlobalObject.zig @@ -426,8 +426,9 @@ pub const JSGlobalObject = opaque { return error.JSError; } - pub fn ref(this: *JSGlobalObject) C_API.JSContextRef { - return @as(C_API.JSContextRef, @ptrCast(this)); + // TODO: delete these two fns + pub fn ref(this: *JSGlobalObject) *JSGlobalObject { + return this; } pub const ctx = ref; @@ -460,6 +461,18 @@ pub const JSGlobalObject = opaque { return JSGlobalObject__clearException(this); } + /// Clear the currently active exception off the VM unless it is a + /// termination exception. + /// + /// Returns `true` if the exception was cleared, `false` if it was a + /// termination exception. Use `clearException` to unconditionally clear + /// exceptions. + /// + /// It is safe to call this function when no exception is present. + pub fn clearExceptionExceptTermination(this: *JSGlobalObject) bool { + return JSGlobalObject__clearExceptionExceptTermination(this); + } + /// Clears the current exception and returns that value. Requires compile-time /// proof of an exception via `error.JSError` pub fn takeException(this: *JSGlobalObject, proof: bun.JSError) JSValue { @@ -727,6 +740,7 @@ pub const JSGlobalObject = opaque { extern fn JSC__JSGlobalObject__vm(*JSGlobalObject) *VM; extern fn JSC__JSGlobalObject__deleteModuleRegistryEntry(*JSGlobalObject, *const ZigString) void; extern fn JSGlobalObject__clearException(*JSGlobalObject) void; + extern fn JSGlobalObject__clearExceptionExceptTermination(*JSGlobalObject) bool; extern fn JSGlobalObject__clearTerminationException(this: *JSGlobalObject) void; extern fn JSGlobalObject__hasException(*JSGlobalObject) bool; extern fn JSGlobalObject__setTimeZone(this: *JSGlobalObject, timeZone: *const ZigString) bool; @@ -794,7 +808,7 @@ pub const JSGlobalObject = opaque { const CommonStrings = JSC.CommonStrings; const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const C_API = bun.JSC.C; diff --git a/src/bun.js/bindings/JSInternalPromise.zig b/src/bun.js/bindings/JSInternalPromise.zig index c6889f18b3..7b5497c0c2 100644 --- a/src/bun.js/bindings/JSInternalPromise.zig +++ b/src/bun.js/bindings/JSInternalPromise.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const JSValue = JSC.JSValue; const JSGlobalObject = JSC.JSGlobalObject; diff --git a/src/bun.js/bindings/JSMap.zig b/src/bun.js/bindings/JSMap.zig index 50ad06b3ac..36d4b13ae1 100644 --- a/src/bun.js/bindings/JSMap.zig +++ b/src/bun.js/bindings/JSMap.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const JSValue = JSC.JSValue; const JSGlobalObject = JSC.JSGlobalObject; diff --git a/src/bun.js/bindings/JSModuleLoader.zig b/src/bun.js/bindings/JSModuleLoader.zig index eb419b8990..80000c0ff2 100644 --- a/src/bun.js/bindings/JSModuleLoader.zig +++ b/src/bun.js/bindings/JSModuleLoader.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const JSC = bun.JSC; const JSValue = JSC.JSValue; diff --git a/src/bun.js/bindings/JSObject.zig b/src/bun.js/bindings/JSObject.zig index 6735049e02..deb9fc69f7 100644 --- a/src/bun.js/bindings/JSObject.zig +++ b/src/bun.js/bindings/JSObject.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const JSValue = JSC.JSValue; const JSGlobalObject = JSC.JSGlobalObject; diff --git a/src/bun.js/bindings/JSPromise.zig b/src/bun.js/bindings/JSPromise.zig index 25e551286f..c6b24216ec 100644 --- a/src/bun.js/bindings/JSPromise.zig +++ b/src/bun.js/bindings/JSPromise.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const JSValue = JSC.JSValue; const JSGlobalObject = JSC.JSGlobalObject; diff --git a/src/bun.js/bindings/JSPromiseRejectionOperation.zig b/src/bun.js/bindings/JSPromiseRejectionOperation.zig index b96e1313ca..4486f0dd72 100644 --- a/src/bun.js/bindings/JSPromiseRejectionOperation.zig +++ b/src/bun.js/bindings/JSPromiseRejectionOperation.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; pub const JSPromiseRejectionOperation = enum(u32) { diff --git a/src/bun.js/bindings/JSPropertyIterator.zig b/src/bun.js/bindings/JSPropertyIterator.zig index 3cdb5592f9..226585e337 100644 --- a/src/bun.js/bindings/JSPropertyIterator.zig +++ b/src/bun.js/bindings/JSPropertyIterator.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; pub const JSPropertyIteratorOptions = struct { diff --git a/src/bun.js/bindings/JSRef.zig b/src/bun.js/bindings/JSRef.zig index d6f452cebe..0e49d74fdd 100644 --- a/src/bun.js/bindings/JSRef.zig +++ b/src/bun.js/bindings/JSRef.zig @@ -79,4 +79,4 @@ pub const JSRef = union(enum) { const JSC = bun.JSC; const JSValue = JSC.JSValue; -const bun = @import("root").bun; +const bun = @import("bun"); diff --git a/src/bun.js/bindings/JSString.zig b/src/bun.js/bindings/JSString.zig index 729aa2620f..c574866200 100644 --- a/src/bun.js/bindings/JSString.zig +++ b/src/bun.js/bindings/JSString.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const JSValue = JSC.JSValue; const JSGlobalObject = JSC.JSGlobalObject; diff --git a/src/bun.js/bindings/JSUint8Array.zig b/src/bun.js/bindings/JSUint8Array.zig index 0e3bdab67d..a9830dac1f 100644 --- a/src/bun.js/bindings/JSUint8Array.zig +++ b/src/bun.js/bindings/JSUint8Array.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const Sizes = @import("./sizes.zig"); const JSGlobalObject = JSC.JSGlobalObject; diff --git a/src/bun.js/bindings/JSValue.zig b/src/bun.js/bindings/JSValue.zig index e2c890883c..c362367983 100644 --- a/src/bun.js/bindings/JSValue.zig +++ b/src/bun.js/bindings/JSValue.zig @@ -2426,7 +2426,7 @@ pub const JSValue = enum(i64) { pub fn asFileDescriptor(this: JSValue) bun.FileDescriptor { bun.assert(this.isNumber()); - return bun.FDImpl.fromUV(this.toInt32()).encode(); + return .fromUV(this.toInt32()); } pub inline fn toU16(this: JSValue) u16 { @@ -2652,7 +2652,7 @@ pub const JSValue = enum(i64) { pub const JSValueReprInt = JSC.JSValueReprInt; const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const C_API = bun.JSC.C; diff --git a/src/bun.js/bindings/NodeModuleModule.zig b/src/bun.js/bindings/NodeModuleModule.zig index 1da4932984..aae75cdb0d 100644 --- a/src/bun.js/bindings/NodeModuleModule.zig +++ b/src/bun.js/bindings/NodeModuleModule.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const std = @import("std"); const JSGlobalObject = JSC.JSGlobalObject; diff --git a/src/bun.js/bindings/Process.zig b/src/bun.js/bindings/Process.zig index 0e93ff0e64..df7c837621 100644 --- a/src/bun.js/bindings/Process.zig +++ b/src/bun.js/bindings/Process.zig @@ -39,7 +39,7 @@ pub const Process = opaque { } }; -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const JSGlobalObject = JSC.JSGlobalObject; const JSValue = JSC.JSValue; diff --git a/src/bun.js/bindings/RegularExpression.zig b/src/bun.js/bindings/RegularExpression.zig index d878135d47..7845bbf93c 100644 --- a/src/bun.js/bindings/RegularExpression.zig +++ b/src/bun.js/bindings/RegularExpression.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); pub const RegularExpression = opaque { pub const Flags = enum(u16) { diff --git a/src/bun.js/bindings/ResolvedSource.zig b/src/bun.js/bindings/ResolvedSource.zig index f8f43999e0..d3cdf92d1b 100644 --- a/src/bun.js/bindings/ResolvedSource.zig +++ b/src/bun.js/bindings/ResolvedSource.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const JSValue = JSC.JSValue; diff --git a/src/bun.js/bindings/ScriptExecutionStatus.zig b/src/bun.js/bindings/ScriptExecutionStatus.zig index 5d3a8f79b9..741b9fa250 100644 --- a/src/bun.js/bindings/ScriptExecutionStatus.zig +++ b/src/bun.js/bindings/ScriptExecutionStatus.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); pub const ScriptExecutionStatus = enum(i32) { running = 0, diff --git a/src/bun.js/bindings/SourceType.zig b/src/bun.js/bindings/SourceType.zig index f35a399dd8..82c2ba22d4 100644 --- a/src/bun.js/bindings/SourceType.zig +++ b/src/bun.js/bindings/SourceType.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; // From SourceProvider.h diff --git a/src/bun.js/bindings/SystemError.zig b/src/bun.js/bindings/SystemError.zig index 34b9fa57c9..e8cdfd4560 100644 --- a/src/bun.js/bindings/SystemError.zig +++ b/src/bun.js/bindings/SystemError.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const String = bun.String; const ZigString = @import("ZigString.zig"); @@ -9,13 +9,14 @@ const JSGlobalObject = JSC.JSGlobalObject; pub const SystemError = extern struct { errno: c_int = 0, /// label for errno - code: String = String.empty, - message: String = String.empty, - path: String = String.empty, - syscall: String = String.empty, - hostname: String = String.empty, - fd: bun.FileDescriptor = bun.toFD(-1), - dest: String = String.empty, + code: String = .empty, + message: String = .empty, + path: String = .empty, + syscall: String = .empty, + hostname: String = .empty, + /// MinInt = no file descriptor + fd: c_int = std.math.minInt(c_int), + dest: String = .empty, pub fn Maybe(comptime Result: type) type { return union(enum) { diff --git a/src/bun.js/bindings/URL.zig b/src/bun.js/bindings/URL.zig index a0dc39e119..a7290b8000 100644 --- a/src/bun.js/bindings/URL.zig +++ b/src/bun.js/bindings/URL.zig @@ -111,7 +111,7 @@ pub const URL = opaque { }; const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const JSGlobalObject = JSC.JSGlobalObject; const JSValue = JSC.JSValue; diff --git a/src/bun.js/bindings/URLSearchParams.zig b/src/bun.js/bindings/URLSearchParams.zig index a3db44f486..e66dec1638 100644 --- a/src/bun.js/bindings/URLSearchParams.zig +++ b/src/bun.js/bindings/URLSearchParams.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const JSGlobalObject = JSC.JSGlobalObject; const JSValue = JSC.JSValue; diff --git a/src/bun.js/bindings/VM.zig b/src/bun.js/bindings/VM.zig index 91507bf1d8..3e4e191bef 100644 --- a/src/bun.js/bindings/VM.zig +++ b/src/bun.js/bindings/VM.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const JSGlobalObject = JSC.JSGlobalObject; const JSValue = JSC.JSValue; diff --git a/src/bun.js/bindings/WTF.zig b/src/bun.js/bindings/WTF.zig index d3b7a12b9e..8dd8537f08 100644 --- a/src/bun.js/bindings/WTF.zig +++ b/src/bun.js/bindings/WTF.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; pub const WTF = struct { diff --git a/src/bun.js/bindings/ZigException.zig b/src/bun.js/bindings/ZigException.zig index e9f08290b9..bdd38fb2db 100644 --- a/src/bun.js/bindings/ZigException.zig +++ b/src/bun.js/bindings/ZigException.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const std = @import("std"); const JSC = bun.JSC; const JSValue = JSC.JSValue; diff --git a/src/bun.js/bindings/ZigStackFrame.zig b/src/bun.js/bindings/ZigStackFrame.zig index ae0042e3d5..d3b94b1cc3 100644 --- a/src/bun.js/bindings/ZigStackFrame.zig +++ b/src/bun.js/bindings/ZigStackFrame.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const std = @import("std"); const JSC = bun.JSC; const String = bun.String; diff --git a/src/bun.js/bindings/ZigStackFramePosition.zig b/src/bun.js/bindings/ZigStackFramePosition.zig index 62e9cb1ce9..85515902f2 100644 --- a/src/bun.js/bindings/ZigStackFramePosition.zig +++ b/src/bun.js/bindings/ZigStackFramePosition.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const std = @import("std"); /// Represents a position in source code with line and column information diff --git a/src/bun.js/bindings/ZigStackTrace.zig b/src/bun.js/bindings/ZigStackTrace.zig index fab8e52418..b2e709457d 100644 --- a/src/bun.js/bindings/ZigStackTrace.zig +++ b/src/bun.js/bindings/ZigStackTrace.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const std = @import("std"); const ZigStackFrame = JSC.ZigStackFrame; const ZigURL = @import("../../url.zig").URL; diff --git a/src/bun.js/bindings/ZigString.zig b/src/bun.js/bindings/ZigString.zig index 74cc6b4308..7cdc6ea9ea 100644 --- a/src/bun.js/bindings/ZigString.zig +++ b/src/bun.js/bindings/ZigString.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const strings = bun.strings; @@ -843,7 +843,7 @@ pub const ZigString = extern struct { } pub fn toJSStringRef(this: *const ZigString) C_API.JSStringRef { - if (comptime @hasDecl(@import("root").bun, "bindgen")) { + if (comptime @hasDecl(@import("bun"), "bindgen")) { return undefined; } diff --git a/src/bun.js/bindings/bindings.cpp b/src/bun.js/bindings/bindings.cpp index 435b614421..4ab3ed9cea 100644 --- a/src/bun.js/bindings/bindings.cpp +++ b/src/bun.js/bindings/bindings.cpp @@ -2077,7 +2077,7 @@ JSC__JSValue SystemError__toErrorInstance(const SystemError* arg0, result->putDirect(vm, clientData->builtinNames().destPublicName(), dest, JSC::PropertyAttribute::DontDelete | 0); } - if (err.fd != -1) { + if (err.fd >= 0) { JSC::JSValue fd = JSC::JSValue(jsNumber(err.fd)); result->putDirect(vm, names.fdPublicName(), fd, JSC::PropertyAttribute::DontDelete | 0); @@ -6272,6 +6272,11 @@ extern "C" void JSGlobalObject__clearException(JSC::JSGlobalObject* globalObject DECLARE_CATCH_SCOPE(globalObject->vm()).clearException(); } +extern "C" bool JSGlobalObject__clearExceptionExceptTermination(JSC::JSGlobalObject* globalObject) +{ + return DECLARE_CATCH_SCOPE(globalObject->vm()).clearExceptionExceptTermination(); +} + extern "C" JSC::EncodedJSValue JSGlobalObject__tryTakeException(JSC::JSGlobalObject* globalObject) { auto scope = DECLARE_CATCH_SCOPE(globalObject->vm()); diff --git a/src/bun.js/bindings/bindings.zig b/src/bun.js/bindings/bindings.zig index 89fefe4495..2c46997e73 100644 --- a/src/bun.js/bindings/bindings.zig +++ b/src/bun.js/bindings/bindings.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const C_API = bun.JSC.C; diff --git a/src/bun.js/bindings/bun-simdutf.zig b/src/bun.js/bindings/bun-simdutf.zig index 246624c3f3..006bfb4a46 100644 --- a/src/bun.js/bindings/bun-simdutf.zig +++ b/src/bun.js/bindings/bun-simdutf.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; pub const SIMDUTFResult = extern struct { diff --git a/src/bun.js/bindings/codegen.zig b/src/bun.js/bindings/codegen.zig index bf67bb491c..d2e02aa1bd 100644 --- a/src/bun.js/bindings/codegen.zig +++ b/src/bun.js/bindings/codegen.zig @@ -1,6 +1,6 @@ const JSC = bun.JSC; const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); pub const CallbackGetterFn = fn (JSC.JSValue) callconv(.C) JSC.JSValue; pub const CallbackSetterFn = fn (JSC.JSValue, JSC.JSValue) callconv(.C) void; diff --git a/src/bun.js/bindings/exports.zig b/src/bun.js/bindings/exports.zig index f239c35f99..549e81cead 100644 --- a/src/bun.js/bindings/exports.zig +++ b/src/bun.js/bindings/exports.zig @@ -1,6 +1,6 @@ const JSC = bun.JSC; -const bun = @import("root").bun; +const bun = @import("bun"); const std = @import("std"); const strings = bun.strings; const default_allocator = bun.default_allocator; diff --git a/src/bun.js/bindings/generated_classes_list.zig b/src/bun.js/bindings/generated_classes_list.zig index 34fcfc718d..1d0cc94c9c 100644 --- a/src/bun.js/bindings/generated_classes_list.zig +++ b/src/bun.js/bindings/generated_classes_list.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; pub const Classes = struct { diff --git a/src/bun.js/bindings/headers-handwritten.h b/src/bun.js/bindings/headers-handwritten.h index b0513402e3..1fe5690be7 100644 --- a/src/bun.js/bindings/headers-handwritten.h +++ b/src/bun.js/bindings/headers-handwritten.h @@ -132,6 +132,7 @@ typedef struct SystemError { BunString path; BunString syscall; BunString hostname; + /// MinInt if not specified int fd; BunString dest; } SystemError; diff --git a/src/bun.js/config.zig b/src/bun.js/config.zig index c8fbeddbd4..19436f69f8 100644 --- a/src/bun.js/config.zig +++ b/src/bun.js/config.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/src/bun.js/event_loop.zig b/src/bun.js/event_loop.zig index b7332b3434..204c9a652b 100644 --- a/src/bun.js/event_loop.zig +++ b/src/bun.js/event_loop.zig @@ -3,7 +3,7 @@ const JSC = bun.JSC; const VirtualMachine = bun.JSC.VirtualMachine; const Allocator = std.mem.Allocator; const Lock = bun.Mutex; -const bun = @import("root").bun; +const bun = @import("bun"); const Environment = bun.Environment; const Fetch = JSC.WebCore.Fetch; const Bun = JSC.API.Bun; @@ -2120,7 +2120,7 @@ pub const MiniEventLoop = struct { pub fn stderr(this: *MiniEventLoop) *JSC.WebCore.Blob.Store { return this.stderr_store orelse brk: { var mode: bun.Mode = 0; - const fd = if (Environment.isWindows) bun.FDImpl.fromUV(2).encode() else bun.STDERR_FD; + const fd = bun.FD.fromUV(2); switch (bun.sys.fstat(fd)) { .result => |stat| { @@ -2151,7 +2151,7 @@ pub const MiniEventLoop = struct { pub fn stdout(this: *MiniEventLoop) *JSC.WebCore.Blob.Store { return this.stdout_store orelse brk: { var mode: bun.Mode = 0; - const fd = if (Environment.isWindows) bun.FDImpl.fromUV(1).encode() else bun.STDOUT_FD; + const fd = bun.FD.stdout(); switch (bun.sys.fstat(fd)) { .result => |stat| { diff --git a/src/bun.js/ipc.zig b/src/bun.js/ipc.zig index 292a4e1fba..4e941ab733 100644 --- a/src/bun.js/ipc.zig +++ b/src/bun.js/ipc.zig @@ -1,5 +1,5 @@ const uws = bun.uws; -const bun = @import("root").bun; +const bun = @import("bun"); const Environment = bun.Environment; const Global = bun.Global; const strings = bun.strings; diff --git a/src/bun.js/javascript.zig b/src/bun.js/javascript.zig index 900a96669a..d75af7ccba 100644 --- a/src/bun.js/javascript.zig +++ b/src/bun.js/javascript.zig @@ -1,6 +1,6 @@ const std = @import("std"); const StaticExport = @import("./bindings/static_export.zig"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; @@ -50,7 +50,6 @@ const JSValue = bun.JSC.JSValue; const NewClass = @import("./base.zig").NewClass; const JSGlobalObject = bun.JSC.JSGlobalObject; -const ExceptionValueRef = bun.JSC.ExceptionValueRef; const JSPrivateDataPtr = bun.JSC.JSPrivateDataPtr; const ConsoleObject = bun.JSC.ConsoleObject; const Node = bun.JSC.Node; @@ -1189,8 +1188,8 @@ pub const VirtualMachine = struct { .json; IPC.log("IPC environment variables: NODE_CHANNEL_FD={s}, NODE_CHANNEL_SERIALIZATION_MODE={s}", .{ fd_s, @tagName(mode) }); - if (std.fmt.parseInt(i32, fd_s, 10)) |fd| { - this.initIPCInstance(bun.toFD(fd), mode); + if (std.fmt.parseInt(u31, fd_s, 10)) |fd| { + this.initIPCInstance(.fromUV(fd), mode); } else |_| { Output.warn("Failed to parse IPC channel number '{s}'", .{fd_s}); } @@ -4082,12 +4081,15 @@ pub const VirtualMachine = struct { const prev_disable_inspect_custom = formatter.disable_inspect_custom; const prev_quote_strings = formatter.quote_strings; const prev_max_depth = formatter.max_depth; + const prev_format_buffer_as_text = formatter.format_buffer_as_text; formatter.depth += 1; + formatter.format_buffer_as_text = true; defer { formatter.depth -= 1; formatter.max_depth = prev_max_depth; formatter.quote_strings = prev_quote_strings; formatter.disable_inspect_custom = prev_disable_inspect_custom; + formatter.format_buffer_as_text = prev_format_buffer_as_text; } formatter.max_depth = 1; formatter.quote_strings = true; @@ -4420,7 +4422,8 @@ pub const VirtualMachine = struct { /// IPC is put in this "enabled but not started" state when IPC is detected /// but the client JavaScript has not yet done `.on("message")` waiting: struct { - info: IPCInfoType, + // TODO: rename to `fd` + info: bun.FD, mode: IPC.Mode, }, initialized: *IPCInstance, @@ -4495,8 +4498,7 @@ pub const VirtualMachine = struct { pub const Handlers = IPC.NewIPCHandler(IPCInstance); }; - const IPCInfoType = bun.FileDescriptor; - pub fn initIPCInstance(this: *VirtualMachine, info: IPCInfoType, mode: IPC.Mode) void { + pub fn initIPCInstance(this: *VirtualMachine, info: bun.FD, mode: IPC.Mode) void { IPC.log("initIPCInstance {}", .{info}); this.ipc = .{ .waiting = .{ .info = info, .mode = mode } }; } @@ -4929,13 +4931,13 @@ pub fn NewHotReloader(comptime Ctx: type, comptime EventLoopType: type, comptime const abs_path: string = brk: { if (dir_ent.entries.get(@as([]const u8, @ptrCast(changed_name)))) |file_ent| { // reset the file descriptor - file_ent.entry.cache.fd = .zero; + file_ent.entry.cache.fd = .invalid; file_ent.entry.need_stat = true; path_string = file_ent.entry.abs_path; file_hash = Watcher.getHash(path_string.slice()); for (hashes, 0..) |hash, entry_id| { if (hash == file_hash) { - if (file_descriptors[entry_id] != .zero) { + if (file_descriptors[entry_id].isValid()) { if (prev_entry_id != entry_id) { current_task.append(hashes[entry_id]); ctx.removeAtIndex( diff --git a/src/bun.js/javascript_core_c_api.zig b/src/bun.js/javascript_core_c_api.zig index b2345047db..8d1c9ab3c1 100644 --- a/src/bun.js/javascript_core_c_api.zig +++ b/src/bun.js/javascript_core_c_api.zig @@ -4,9 +4,10 @@ /// To generate a new class exposed to JavaScript, look at *.classes.ts /// Otherwise, use `JSC.JSValue`. /// ************************************ -const bun = @import("root").bun; +const bun = @import("bun"); const std = @import("std"); const cpp = @import("./bindings/bindings.zig"); +const JSC = bun.JSC; const generic = opaque { pub fn value(this: *const generic) cpp.JSValue { return @as(cpp.JSValue, @enumFromInt(@as(cpp.JSValueReprInt, @bitCast(@intFromPtr(this))))); @@ -16,7 +17,6 @@ pub const Private = anyopaque; pub const struct_OpaqueJSContextGroup = generic; pub const JSContextGroupRef = ?*const struct_OpaqueJSContextGroup; pub const struct_OpaqueJSContext = generic; -pub const JSContextRef = *cpp.JSGlobalObject; pub const JSGlobalContextRef = ?*cpp.JSGlobalObject; pub const struct_OpaqueJSPropertyNameAccumulator = generic; @@ -25,7 +25,7 @@ pub const JSTypedArrayBytesDeallocator = ?*const fn (*anyopaque, *anyopaque) cal pub const OpaqueJSValue = generic; pub const JSValueRef = ?*OpaqueJSValue; pub const JSObjectRef = ?*OpaqueJSValue; -pub extern fn JSGarbageCollect(ctx: JSContextRef) void; +pub extern fn JSGarbageCollect(ctx: *JSC.JSGlobalObject) void; pub const JSType = enum(c_uint) { kJSTypeUndefined, kJSTypeNull, @@ -70,15 +70,15 @@ pub const kJSTypedArrayTypeFloat32Array = @intFromEnum(JSTypedArrayType.kJSTyped pub const kJSTypedArrayTypeFloat64Array = @intFromEnum(JSTypedArrayType.kJSTypedArrayTypeFloat64Array); pub const kJSTypedArrayTypeArrayBuffer = @intFromEnum(JSTypedArrayType.kJSTypedArrayTypeArrayBuffer); pub const kJSTypedArrayTypeNone = @intFromEnum(JSTypedArrayType.kJSTypedArrayTypeNone); -pub extern fn JSValueGetType(ctx: JSContextRef, value: JSValueRef) JSType; -pub extern fn JSValueMakeNull(ctx: JSContextRef) JSValueRef; -pub extern fn JSValueToNumber(ctx: JSContextRef, value: JSValueRef, exception: ExceptionRef) f64; -pub extern fn JSValueToObject(ctx: JSContextRef, value: JSValueRef, exception: ExceptionRef) JSObjectRef; +pub extern fn JSValueGetType(ctx: *JSC.JSGlobalObject, value: JSValueRef) JSType; +pub extern fn JSValueMakeNull(ctx: *JSC.JSGlobalObject) JSValueRef; +pub extern fn JSValueToNumber(ctx: *JSC.JSGlobalObject, value: JSValueRef, exception: ExceptionRef) f64; +pub extern fn JSValueToObject(ctx: *JSC.JSGlobalObject, value: JSValueRef, exception: ExceptionRef) JSObjectRef; const log_protection = bun.Environment.allow_assert and false; -pub inline fn JSValueUnprotect(ctx: JSContextRef, value: JSValueRef) void { +pub inline fn JSValueUnprotect(ctx: *JSC.JSGlobalObject, value: JSValueRef) void { const Wrapped = struct { - pub extern fn JSValueUnprotect(ctx: JSContextRef, value: JSValueRef) void; + pub extern fn JSValueUnprotect(ctx: *JSC.JSGlobalObject, value: JSValueRef) void; }; if (comptime log_protection) { const Output = bun.Output; @@ -88,9 +88,9 @@ pub inline fn JSValueUnprotect(ctx: JSContextRef, value: JSValueRef) void { Wrapped.JSValueUnprotect(ctx, value); } -pub inline fn JSValueProtect(ctx: JSContextRef, value: JSValueRef) void { +pub inline fn JSValueProtect(ctx: *JSC.JSGlobalObject, value: JSValueRef) void { const Wrapped = struct { - pub extern fn JSValueProtect(ctx: JSContextRef, value: JSValueRef) void; + pub extern fn JSValueProtect(ctx: *JSC.JSGlobalObject, value: JSValueRef) void; }; if (comptime log_protection) { const Output = bun.Output; @@ -119,42 +119,42 @@ pub const JSClassAttributes = enum(c_uint) { pub const kJSClassAttributeNone = @intFromEnum(JSClassAttributes.kJSClassAttributeNone); pub const kJSClassAttributeNoAutomaticPrototype = @intFromEnum(JSClassAttributes.kJSClassAttributeNoAutomaticPrototype); -pub const JSObjectInitializeCallback = *const fn (JSContextRef, JSObjectRef) callconv(.C) void; +pub const JSObjectInitializeCallback = *const fn (*JSC.JSGlobalObject, JSObjectRef) callconv(.C) void; pub const JSObjectFinalizeCallback = *const fn (JSObjectRef) callconv(.C) void; -pub const JSObjectGetPropertyNamesCallback = *const fn (JSContextRef, JSObjectRef, JSPropertyNameAccumulatorRef) callconv(.C) void; +pub const JSObjectGetPropertyNamesCallback = *const fn (*JSC.JSGlobalObject, JSObjectRef, JSPropertyNameAccumulatorRef) callconv(.C) void; pub const ExceptionRef = [*c]JSValueRef; pub const JSObjectCallAsFunctionCallback = *const fn ( - ctx: JSContextRef, + ctx: *JSC.JSGlobalObject, function: JSObjectRef, thisObject: JSObjectRef, argumentCount: usize, arguments: [*c]const JSValueRef, exception: ExceptionRef, ) callconv(.C) JSValueRef; -pub const JSObjectCallAsConstructorCallback = *const fn (JSContextRef, JSObjectRef, usize, [*c]const JSValueRef, ExceptionRef) callconv(.C) JSObjectRef; -pub const JSObjectHasInstanceCallback = *const fn (JSContextRef, JSObjectRef, JSValueRef, ExceptionRef) callconv(.C) bool; -pub const JSObjectConvertToTypeCallback = *const fn (JSContextRef, JSObjectRef, JSType, ExceptionRef) callconv(.C) JSValueRef; +pub const JSObjectCallAsConstructorCallback = *const fn (*JSC.JSGlobalObject, JSObjectRef, usize, [*c]const JSValueRef, ExceptionRef) callconv(.C) JSObjectRef; +pub const JSObjectHasInstanceCallback = *const fn (*JSC.JSGlobalObject, JSObjectRef, JSValueRef, ExceptionRef) callconv(.C) bool; +pub const JSObjectConvertToTypeCallback = *const fn (*JSC.JSGlobalObject, JSObjectRef, JSType, ExceptionRef) callconv(.C) JSValueRef; -pub extern "c" fn JSObjectGetPrototype(ctx: JSContextRef, object: JSObjectRef) JSValueRef; -pub extern "c" fn JSObjectGetPropertyAtIndex(ctx: JSContextRef, object: JSObjectRef, propertyIndex: c_uint, exception: ExceptionRef) JSValueRef; -pub extern "c" fn JSObjectSetPropertyAtIndex(ctx: JSContextRef, object: JSObjectRef, propertyIndex: c_uint, value: JSValueRef, exception: ExceptionRef) void; -pub extern "c" fn JSObjectCallAsFunction(ctx: JSContextRef, object: JSObjectRef, thisObject: JSObjectRef, argumentCount: usize, arguments: [*c]const JSValueRef, exception: ExceptionRef) JSValueRef; -pub extern "c" fn JSObjectIsConstructor(ctx: JSContextRef, object: JSObjectRef) bool; -pub extern "c" fn JSObjectCallAsConstructor(ctx: JSContextRef, object: JSObjectRef, argumentCount: usize, arguments: [*c]const JSValueRef, exception: ExceptionRef) JSObjectRef; -pub extern "c" fn JSObjectMakeDate(ctx: JSContextRef, argumentCount: usize, arguments: [*c]const JSValueRef, exception: ExceptionRef) JSObjectRef; +pub extern "c" fn JSObjectGetPrototype(ctx: *JSC.JSGlobalObject, object: JSObjectRef) JSValueRef; +pub extern "c" fn JSObjectGetPropertyAtIndex(ctx: *JSC.JSGlobalObject, object: JSObjectRef, propertyIndex: c_uint, exception: ExceptionRef) JSValueRef; +pub extern "c" fn JSObjectSetPropertyAtIndex(ctx: *JSC.JSGlobalObject, object: JSObjectRef, propertyIndex: c_uint, value: JSValueRef, exception: ExceptionRef) void; +pub extern "c" fn JSObjectCallAsFunction(ctx: *JSC.JSGlobalObject, object: JSObjectRef, thisObject: JSObjectRef, argumentCount: usize, arguments: [*c]const JSValueRef, exception: ExceptionRef) JSValueRef; +pub extern "c" fn JSObjectIsConstructor(ctx: *JSC.JSGlobalObject, object: JSObjectRef) bool; +pub extern "c" fn JSObjectCallAsConstructor(ctx: *JSC.JSGlobalObject, object: JSObjectRef, argumentCount: usize, arguments: [*c]const JSValueRef, exception: ExceptionRef) JSObjectRef; +pub extern "c" fn JSObjectMakeDate(ctx: *JSC.JSGlobalObject, argumentCount: usize, arguments: [*c]const JSValueRef, exception: ExceptionRef) JSObjectRef; pub const JSChar = u16; -pub extern fn JSObjectMakeTypedArray(ctx: JSContextRef, arrayType: JSTypedArrayType, length: usize, exception: ExceptionRef) JSObjectRef; -pub extern fn JSObjectMakeTypedArrayWithBytesNoCopy(ctx: JSContextRef, arrayType: JSTypedArrayType, bytes: ?*anyopaque, byteLength: usize, bytesDeallocator: JSTypedArrayBytesDeallocator, deallocatorContext: ?*anyopaque, exception: ExceptionRef) JSObjectRef; -pub extern fn JSObjectMakeTypedArrayWithArrayBuffer(ctx: JSContextRef, arrayType: JSTypedArrayType, buffer: JSObjectRef, exception: ExceptionRef) JSObjectRef; -pub extern fn JSObjectMakeTypedArrayWithArrayBufferAndOffset(ctx: JSContextRef, arrayType: JSTypedArrayType, buffer: JSObjectRef, byteOffset: usize, length: usize, exception: ExceptionRef) JSObjectRef; -pub extern fn JSObjectGetTypedArrayBytesPtr(ctx: JSContextRef, object: JSObjectRef, exception: ExceptionRef) ?*anyopaque; -pub extern fn JSObjectGetTypedArrayLength(ctx: JSContextRef, object: JSObjectRef, exception: ExceptionRef) usize; -pub extern fn JSObjectGetTypedArrayByteLength(ctx: JSContextRef, object: JSObjectRef, exception: ExceptionRef) usize; -pub extern fn JSObjectGetTypedArrayByteOffset(ctx: JSContextRef, object: JSObjectRef, exception: ExceptionRef) usize; -pub extern fn JSObjectGetTypedArrayBuffer(ctx: JSContextRef, object: JSObjectRef, exception: ExceptionRef) JSObjectRef; -pub extern fn JSObjectMakeArrayBufferWithBytesNoCopy(ctx: JSContextRef, bytes: ?*anyopaque, byteLength: usize, bytesDeallocator: JSTypedArrayBytesDeallocator, deallocatorContext: ?*anyopaque, exception: ExceptionRef) JSObjectRef; -pub extern fn JSObjectGetArrayBufferBytesPtr(ctx: JSContextRef, object: JSObjectRef, exception: ExceptionRef) ?*anyopaque; -pub extern fn JSObjectGetArrayBufferByteLength(ctx: JSContextRef, object: JSObjectRef, exception: ExceptionRef) usize; +pub extern fn JSObjectMakeTypedArray(ctx: *JSC.JSGlobalObject, arrayType: JSTypedArrayType, length: usize, exception: ExceptionRef) JSObjectRef; +pub extern fn JSObjectMakeTypedArrayWithBytesNoCopy(ctx: *JSC.JSGlobalObject, arrayType: JSTypedArrayType, bytes: ?*anyopaque, byteLength: usize, bytesDeallocator: JSTypedArrayBytesDeallocator, deallocatorContext: ?*anyopaque, exception: ExceptionRef) JSObjectRef; +pub extern fn JSObjectMakeTypedArrayWithArrayBuffer(ctx: *JSC.JSGlobalObject, arrayType: JSTypedArrayType, buffer: JSObjectRef, exception: ExceptionRef) JSObjectRef; +pub extern fn JSObjectMakeTypedArrayWithArrayBufferAndOffset(ctx: *JSC.JSGlobalObject, arrayType: JSTypedArrayType, buffer: JSObjectRef, byteOffset: usize, length: usize, exception: ExceptionRef) JSObjectRef; +pub extern fn JSObjectGetTypedArrayBytesPtr(ctx: *JSC.JSGlobalObject, object: JSObjectRef, exception: ExceptionRef) ?*anyopaque; +pub extern fn JSObjectGetTypedArrayLength(ctx: *JSC.JSGlobalObject, object: JSObjectRef, exception: ExceptionRef) usize; +pub extern fn JSObjectGetTypedArrayByteLength(ctx: *JSC.JSGlobalObject, object: JSObjectRef, exception: ExceptionRef) usize; +pub extern fn JSObjectGetTypedArrayByteOffset(ctx: *JSC.JSGlobalObject, object: JSObjectRef, exception: ExceptionRef) usize; +pub extern fn JSObjectGetTypedArrayBuffer(ctx: *JSC.JSGlobalObject, object: JSObjectRef, exception: ExceptionRef) JSObjectRef; +pub extern fn JSObjectMakeArrayBufferWithBytesNoCopy(ctx: *JSC.JSGlobalObject, bytes: ?*anyopaque, byteLength: usize, bytesDeallocator: JSTypedArrayBytesDeallocator, deallocatorContext: ?*anyopaque, exception: ExceptionRef) JSObjectRef; +pub extern fn JSObjectGetArrayBufferBytesPtr(ctx: *JSC.JSGlobalObject, object: JSObjectRef, exception: ExceptionRef) ?*anyopaque; +pub extern fn JSObjectGetArrayBufferByteLength(ctx: *JSC.JSGlobalObject, object: JSObjectRef, exception: ExceptionRef) usize; pub const OpaqueJSContextGroup = struct_OpaqueJSContextGroup; pub const OpaqueJSContext = struct_OpaqueJSContext; pub const OpaqueJSPropertyNameAccumulator = struct_OpaqueJSPropertyNameAccumulator; @@ -162,7 +162,7 @@ pub const OpaqueJSPropertyNameAccumulator = struct_OpaqueJSPropertyNameAccumulat // This is a workaround for not receiving a JSException* object // This function lets us use the C API but returns a plain old JSValue // allowing us to have exceptions that include stack traces -pub extern "c" fn JSObjectCallAsFunctionReturnValueHoldingAPILock(ctx: JSContextRef, object: JSObjectRef, thisObject: JSObjectRef, argumentCount: usize, arguments: [*c]const JSValueRef) cpp.JSValue; +pub extern "c" fn JSObjectCallAsFunctionReturnValueHoldingAPILock(ctx: *JSC.JSGlobalObject, object: JSObjectRef, thisObject: JSObjectRef, argumentCount: usize, arguments: [*c]const JSValueRef) cpp.JSValue; pub extern fn JSRemoteInspectorDisableAutoStart() void; pub extern fn JSRemoteInspectorStart() void; diff --git a/src/bun.js/module_loader.zig b/src/bun.js/module_loader.zig index 024ad6cdcb..ed7952b02c 100644 --- a/src/bun.js/module_loader.zig +++ b/src/bun.js/module_loader.zig @@ -1,6 +1,6 @@ const std = @import("std"); const StaticExport = @import("./bindings/static_export.zig"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; @@ -37,7 +37,6 @@ const ImportRecord = ast.ImportRecord; const DotEnv = @import("../env_loader.zig"); const PackageJSON = @import("../resolver/package_json.zig").PackageJSON; const MacroRemap = @import("../resolver/package_json.zig").MacroMap; -const js = bun.JSC.C; const JSC = bun.JSC; const MarkedArrayBuffer = @import("./base.zig").MarkedArrayBuffer; const getAllocator = @import("./base.zig").getAllocator; @@ -45,7 +44,6 @@ const JSValue = bun.JSC.JSValue; const node_module_module = @import("./bindings/NodeModuleModule.zig"); const JSGlobalObject = bun.JSC.JSGlobalObject; -const ExceptionValueRef = bun.JSC.ExceptionValueRef; const ConsoleObject = bun.JSC.ConsoleObject; const ZigException = bun.JSC.ZigException; const ZigStackTrace = bun.JSC.ZigStackTrace; @@ -424,8 +422,8 @@ pub const RuntimeTranspilerStore = struct { switch (vm.bun_watcher) { .hot, .watch => { if (vm.bun_watcher.indexOf(hash)) |index| { - const _fd = vm.bun_watcher.watchlist().items(.fd)[index]; - fd = if (!_fd.isStdio()) _fd else null; + const watcher_fd = vm.bun_watcher.watchlist().items(.fd)[index]; + fd = if (watcher_fd.stdioTag() == null) watcher_fd else null; package_json = vm.bun_watcher.watchlist().items(.package_json)[index]; } }, @@ -449,7 +447,7 @@ pub const RuntimeTranspilerStore = struct { // var should_close_input_file_fd = fd == null; - var input_file_fd: StoredFileDescriptorType = .zero; + var input_file_fd: StoredFileDescriptorType = .invalid; const is_main = vm.main.len == path.text.len and vm.main_hash == hash and @@ -465,7 +463,7 @@ pub const RuntimeTranspilerStore = struct { .allocator = allocator, .path = path, .loader = loader, - .dirname_fd = .zero, + .dirname_fd = .invalid, .file_descriptor = fd, .file_fd_ptr = &input_file_fd, .file_hash = hash, @@ -487,9 +485,9 @@ pub const RuntimeTranspilerStore = struct { }; defer { - if (should_close_input_file_fd and input_file_fd != .zero) { - _ = bun.sys.close(input_file_fd); - input_file_fd = .zero; + if (should_close_input_file_fd and input_file_fd.isValid()) { + input_file_fd.close(); + input_file_fd = .invalid; } } @@ -508,7 +506,7 @@ pub const RuntimeTranspilerStore = struct { false, ) orelse { if (vm.isWatcherEnabled()) { - if (input_file_fd != .zero) { + if (input_file_fd.isValid()) { if (!is_node_override and std.fs.path.isAbsolute(path.text) and !strings.contains(path.text, "node_modules")) { should_close_input_file_fd = false; _ = vm.bun_watcher.addFile( @@ -516,7 +514,7 @@ pub const RuntimeTranspilerStore = struct { path.text, hash, loader, - .zero, + .invalid, package_json, true, ); @@ -529,7 +527,7 @@ pub const RuntimeTranspilerStore = struct { }; if (vm.isWatcherEnabled()) { - if (input_file_fd != .zero) { + if (input_file_fd.isValid()) { if (!is_node_override and std.fs.path.isAbsolute(path.text) and !strings.contains(path.text, "node_modules")) { @@ -539,7 +537,7 @@ pub const RuntimeTranspilerStore = struct { path.text, hash, loader, - .zero, + .invalid, package_json, true, ); @@ -719,13 +717,11 @@ pub const ModuleLoader = struct { var tmpname_buf: bun.PathBuffer = undefined; const tmpfilename = bun.sliceTo(bun.fs.FileSystem.instance.tmpname(extname, &tmpname_buf, bun.hash(file.name)) catch return null, 0); - const tmpdir = bun.fs.FileSystem.instance.tmpdir() catch return null; + const tmpdir: bun.FD = .fromStdDir(bun.fs.FileSystem.instance.tmpdir() catch return null); // First we open the tmpfile, to avoid any other work in the event of failure. - const tmpfile = bun.Tmpfile.create(bun.toFD(tmpdir.fd), tmpfilename).unwrap() catch return null; - defer { - _ = bun.sys.close(tmpfile.fd); - } + const tmpfile = bun.Tmpfile.create(tmpdir, tmpfilename).unwrap() catch return null; + defer tmpfile.fd.close(); switch (JSC.Node.NodeFS.writeFileWithPathBuffer( &tmpname_buf, // not used @@ -734,10 +730,8 @@ pub const ModuleLoader = struct { .data = .{ .encoded_slice = ZigString.Slice.fromUTF8NeverFree(file.contents), }, - .dirfd = bun.toFD(tmpdir.fd), - .file = .{ - .fd = tmpfile.fd, - }, + .dirfd = tmpdir, + .file = .{ .fd = tmpfile.fd }, .encoding = .buffer, }, )) { @@ -1426,7 +1420,7 @@ pub const ModuleLoader = struct { path.text, this.hash, options.Loader.fromAPI(this.loader), - .zero, + .invalid, this.package_json, true, ); @@ -1563,8 +1557,7 @@ pub const ModuleLoader = struct { var package_json: ?*PackageJSON = null; if (jsc_vm.bun_watcher.indexOf(hash)) |index| { - const maybe_fd = jsc_vm.bun_watcher.watchlist().items(.fd)[index]; - fd = if (maybe_fd != .zero) maybe_fd else null; + fd = jsc_vm.bun_watcher.watchlist().items(.fd)[index].unwrapValid(); package_json = jsc_vm.bun_watcher.watchlist().items(.package_json)[index]; } @@ -1641,7 +1634,7 @@ pub const ModuleLoader = struct { }; defer { if (should_close_input_file_fd and input_file_fd != bun.invalid_fd) { - _ = bun.sys.close(input_file_fd); + input_file_fd.close(); input_file_fd = bun.invalid_fd; } } @@ -1664,7 +1657,7 @@ pub const ModuleLoader = struct { ) orelse { if (comptime !disable_transpilying) { if (jsc_vm.isWatcherEnabled()) { - if (input_file_fd != .zero) { + if (input_file_fd.isValid()) { if (!is_node_override and std.fs.path.isAbsolute(path.text) and !strings.contains(path.text, "node_modules")) { should_close_input_file_fd = false; _ = jsc_vm.bun_watcher.addFile( @@ -1672,7 +1665,7 @@ pub const ModuleLoader = struct { path.text, hash, loader, - .zero, + .invalid, package_json, true, ); @@ -1707,7 +1700,7 @@ pub const ModuleLoader = struct { if (comptime !disable_transpilying) { if (jsc_vm.isWatcherEnabled()) { - if (input_file_fd != .zero) { + if (input_file_fd.isValid()) { if (!is_node_override and std.fs.path.isAbsolute(path.text) and !strings.contains(path.text, "node_modules")) { should_close_input_file_fd = false; _ = jsc_vm.bun_watcher.addFile( @@ -1715,7 +1708,7 @@ pub const ModuleLoader = struct { path.text, hash, loader, - .zero, + .invalid, package_json, true, ); @@ -2134,11 +2127,11 @@ pub const ModuleLoader = struct { 0, )) { .err => break :auto_watch, - .result => |fd| break :brk @enumFromInt(fd.cast()), + .result => |fd| break :brk fd, } } else { // Otherwise, don't even bother opening it. - break :brk .zero; + break :brk .invalid; } }; const hash = bun.Watcher.getHash(path.text); @@ -2147,7 +2140,7 @@ pub const ModuleLoader = struct { path.text, hash, loader, - .zero, + .invalid, null, true, )) { @@ -2157,8 +2150,8 @@ pub const ModuleLoader = struct { // opened the file descriptor to // receive event notifications on // it, we should close it. - if (input_fd != .zero) { - _ = bun.sys.close(bun.toFD(input_fd)); + if (input_fd.isValid()) { + input_fd.close(); } } diff --git a/src/bun.js/node/Stat.zig b/src/bun.js/node/Stat.zig index a08f8c454e..a873f604a5 100644 --- a/src/bun.js/node/Stat.zig +++ b/src/bun.js/node/Stat.zig @@ -203,7 +203,7 @@ pub const Stats = union(enum) { } }; -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const Environment = bun.Environment; const std = @import("std"); diff --git a/src/bun.js/node/StatFS.zig b/src/bun.js/node/StatFS.zig index 7783634459..ea24c2ce1b 100644 --- a/src/bun.js/node/StatFS.zig +++ b/src/bun.js/node/StatFS.zig @@ -136,7 +136,7 @@ pub const StatFS = union(enum) { } }; -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const Environment = bun.Environment; const std = @import("std"); diff --git a/src/bun.js/node/assert/myers_diff.zig b/src/bun.js/node/assert/myers_diff.zig index 01a0a3ca0b..cd76a3e235 100644 --- a/src/bun.js/node/assert/myers_diff.zig +++ b/src/bun.js/node/assert/myers_diff.zig @@ -1,8 +1,8 @@ //! ## IMPORTANT NOTE //! -//! Do _NOT_ import from "root" in this file! Do _NOT_ use the Bun object in this file! +//! Do _NOT_ import from "bun" in this file! Do _NOT_ use the Bun object in this file! //! -//! This file has tests defined in it which _cannot_ be run if `@import("root")` is used! +//! This file has tests defined in it which _cannot_ be run if `@import("bun")` is used! //! //! Run tests with `:zig test %` const std = @import("std"); diff --git a/src/bun.js/node/buffer.zig b/src/bun.js/node/buffer.zig index 5ee8ecb092..4366569a9c 100644 --- a/src/bun.js/node/buffer.zig +++ b/src/bun.js/node/buffer.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const Encoder = JSC.WebCore.Encoder; const Environment = bun.Environment; diff --git a/src/bun.js/node/dir_iterator.zig b/src/bun.js/node/dir_iterator.zig index 7b6b89286e..9be5cc5020 100644 --- a/src/bun.js/node/dir_iterator.zig +++ b/src/bun.js/node/dir_iterator.zig @@ -12,7 +12,7 @@ const posix = std.posix; const Dir = std.fs.Dir; const JSC = bun.JSC; const PathString = JSC.PathString; -const bun = @import("root").bun; +const bun = @import("bun"); const IteratorError = error{ AccessDenied, SystemResources } || posix.UnexpectedError; const mem = std.mem; @@ -260,14 +260,14 @@ pub fn NewIterator(comptime use_windows_ospath: bool) type { self.first = false; if (io.Information == 0) { - bun.sys.syslog("NtQueryDirectoryFile({}) = 0", .{bun.toFD(self.dir.fd)}); + bun.sys.syslog("NtQueryDirectoryFile({}) = 0", .{bun.FD.fromStdDir(self.dir)}); return .{ .result = null }; } self.index = 0; self.end_index = io.Information; // If the handle is not a directory, we'll get STATUS_INVALID_PARAMETER. if (rc == .INVALID_PARAMETER) { - bun.sys.syslog("NtQueryDirectoryFile({}) = {s}", .{ bun.toFD(self.dir.fd), @tagName(rc) }); + bun.sys.syslog("NtQueryDirectoryFile({}) = {s}", .{ bun.FD.fromStdDir(self.dir), @tagName(rc) }); return .{ .err = .{ .errno = @intFromEnum(bun.C.SystemErrno.ENOTDIR), @@ -277,13 +277,13 @@ pub fn NewIterator(comptime use_windows_ospath: bool) type { } if (rc == .NO_MORE_FILES) { - bun.sys.syslog("NtQueryDirectoryFile({}) = {s}", .{ bun.toFD(self.dir.fd), @tagName(rc) }); + bun.sys.syslog("NtQueryDirectoryFile({}) = {s}", .{ bun.FD.fromStdDir(self.dir), @tagName(rc) }); self.end_index = self.index; return .{ .result = null }; } if (rc != .SUCCESS) { - bun.sys.syslog("NtQueryDirectoryFile({}) = {s}", .{ bun.toFD(self.dir.fd), @tagName(rc) }); + bun.sys.syslog("NtQueryDirectoryFile({}) = {s}", .{ bun.FD.fromStdDir(self.dir), @tagName(rc) }); if ((bun.windows.Win32Error.fromNTStatus(rc).toSystemErrno())) |errno| { return .{ @@ -302,7 +302,7 @@ pub fn NewIterator(comptime use_windows_ospath: bool) type { }; } - bun.sys.syslog("NtQueryDirectoryFile({}) = {d}", .{ bun.toFD(self.dir.fd), self.end_index }); + bun.sys.syslog("NtQueryDirectoryFile({}) = {d}", .{ bun.FD.fromStdDir(self.dir), self.end_index }); } const dir_info: FILE_DIRECTORY_INFORMATION_PTR = @ptrCast(@alignCast(&self.buf[self.index])); diff --git a/src/bun.js/node/fs_events.zig b/src/bun.js/node/fs_events.zig index f746f63a34..04da57b35e 100644 --- a/src/bun.js/node/fs_events.zig +++ b/src/bun.js/node/fs_events.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Environment = bun.Environment; const Mutex = bun.Mutex; const sync = @import("../../sync.zig"); diff --git a/src/bun.js/node/node_assert.zig b/src/bun.js/node/node_assert.zig index b0016b55c1..c9f3337997 100644 --- a/src/bun.js/node/node_assert.zig +++ b/src/bun.js/node/node_assert.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const MyersDiff = @import("./assert/myers_diff.zig"); const Allocator = std.mem.Allocator; diff --git a/src/bun.js/node/node_assert_binding.zig b/src/bun.js/node/node_assert_binding.zig index ea1572e512..d7cab41e17 100644 --- a/src/bun.js/node/node_assert_binding.zig +++ b/src/bun.js/node/node_assert_binding.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const assert = @import("./node_assert.zig"); const DiffList = @import("./assert/myers_diff.zig").DiffList; const Allocator = std.mem.Allocator; diff --git a/src/bun.js/node/node_cluster_binding.zig b/src/bun.js/node/node_cluster_binding.zig index 508fb1025c..4885278894 100644 --- a/src/bun.js/node/node_cluster_binding.zig +++ b/src/bun.js/node/node_cluster_binding.zig @@ -4,7 +4,7 @@ // at all. It should happen in the protocol before it reaches JS. // - We should not be creating JSFunction's in process.nextTick. const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Environment = bun.Environment; const JSC = bun.JSC; const string = bun.string; diff --git a/src/bun.js/node/node_crypto_binding.zig b/src/bun.js/node/node_crypto_binding.zig index 7b6a5ae1c4..f95b46c364 100644 --- a/src/bun.js/node/node_crypto_binding.zig +++ b/src/bun.js/node/node_crypto_binding.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Environment = bun.Environment; const JSC = bun.JSC; const string = bun.string; diff --git a/src/bun.js/node/node_error_binding.zig b/src/bun.js/node/node_error_binding.zig index 818725a0dd..6166c0c24f 100644 --- a/src/bun.js/node/node_error_binding.zig +++ b/src/bun.js/node/node_error_binding.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Environment = bun.Environment; const JSC = bun.JSC; const string = bun.string; diff --git a/src/bun.js/node/node_fs.zig b/src/bun.js/node/node_fs.zig index ffcb30f44e..7aa10b2b2b 100644 --- a/src/bun.js/node/node_fs.zig +++ b/src/bun.js/node/node_fs.zig @@ -2,7 +2,7 @@ // for interacting with the filesystem from JavaScript. // The top-level functions assume the arguments are already validated const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const strings = bun.strings; const windows = bun.windows; const string = bun.string; @@ -16,7 +16,8 @@ const Encoding = JSC.Node.Encoding; const PosixToWinNormalizer = bun.path.PosixToWinNormalizer; const FileDescriptor = bun.FileDescriptor; -const FDImpl = bun.FDImpl; +const FD = bun.FD; + const AbortSignal = JSC.AbortSignal; const Syscall = if (Environment.isWindows) bun.sys.sys_uv else bun.sys; @@ -214,7 +215,7 @@ pub const Async = struct { }, .close => { const args: Arguments.Close = task.args; - const fd = args.fd.impl().uv(); + const fd = args.fd.uv(); if (fd == 1 or fd == 2) { log("uv close({}) SKIPPED", .{fd}); @@ -230,7 +231,7 @@ pub const Async = struct { .read => { const args: Arguments.Read = task.args; const B = uv.uv_buf_t.init; - const fd = args.fd.impl().uv(); + const fd = args.fd.uv(); var buf = args.buffer.slice(); buf = buf[@min(buf.len, args.offset)..]; @@ -243,7 +244,7 @@ pub const Async = struct { .write => { const args: Arguments.Write = task.args; const B = uv.uv_buf_t.init; - const fd = args.fd.impl().uv(); + const fd = args.fd.uv(); var buf = args.buffer.slice(); buf = buf[@min(buf.len, args.offset)..]; @@ -255,7 +256,7 @@ pub const Async = struct { }, .readv => { const args: Arguments.Readv = task.args; - const fd = args.fd.impl().uv(); + const fd = args.fd.uv(); const bufs = args.buffers.buffers.items; const pos: i64 = args.position orelse -1; @@ -268,7 +269,7 @@ pub const Async = struct { }, .writev => { const args_: Arguments.Writev = task.args; - const fd = args_.fd.impl().uv(); + const fd = args_.fd.uv(); const bufs = args_.buffers.buffers.items; if (bufs.len == 0) { @@ -878,7 +879,7 @@ pub fn NewAsyncCpTask(comptime is_shell: bool) type { }, .result => |fd_| fd_, }; - defer _ = Syscall.close(fd); + defer fd.close(); var buf: bun.OSPathBuffer = undefined; @@ -904,7 +905,7 @@ pub fn NewAsyncCpTask(comptime is_shell: bool) type { }, } - const dir = fd.asDir(); + const dir = fd.stdDir(); var iterator = DirIterator.iterate(dir, if (Environment.isWindows) .u16 else .u8); var entry = iterator.next(); while (switch (entry) { @@ -1199,7 +1200,7 @@ pub const AsyncReaddirRecursiveTask = struct { const root_fd = this.root_fd; if (root_fd != bun.invalid_fd) { this.root_fd = bun.invalid_fd; - _ = Syscall.close(root_fd); + root_fd.close(); bun.default_allocator.free(this.root_path.slice()); this.root_path = PathString.empty; } @@ -1334,7 +1335,7 @@ pub const Arguments = struct { this.new_path.toThreadSafe(); } - pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice) bun.JSError!Rename { + pub fn fromJS(ctx: *JSC.JSGlobalObject, arguments: *ArgumentsSlice) bun.JSError!Rename { const old_path = try PathLike.fromJS(ctx, arguments) orelse { return ctx.throwInvalidArgumentTypeValue("oldPath", "string or an instance of Buffer or URL", arguments.next() orelse .undefined); }; @@ -1365,7 +1366,7 @@ pub const Arguments = struct { this.path.toThreadSafe(); } - pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice) bun.JSError!Truncate { + pub fn fromJS(ctx: *JSC.JSGlobalObject, arguments: *ArgumentsSlice) bun.JSError!Truncate { const path = try PathOrFileDescriptor.fromJS(ctx, arguments, bun.default_allocator) orelse { return ctx.throwInvalidArguments("path must be a string or TypedArray", .{}); }; @@ -1399,9 +1400,9 @@ pub const Arguments = struct { this.buffers.buffers.allocator = bun.default_allocator; } - pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice) bun.JSError!Writev { + pub fn fromJS(ctx: *JSC.JSGlobalObject, arguments: *ArgumentsSlice) bun.JSError!Writev { const fd_value = arguments.nextEat() orelse JSC.JSValue.undefined; - const fd = try JSC.Node.fileDescriptorFromJS(ctx, fd_value) orelse { + const fd = try bun.FD.fromJSValidated(fd_value, ctx) orelse { return throwInvalidFdError(ctx, fd_value); }; @@ -1453,9 +1454,9 @@ pub const Arguments = struct { this.buffers.buffers.allocator = bun.default_allocator; } - pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice) bun.JSError!Readv { + pub fn fromJS(ctx: *JSC.JSGlobalObject, arguments: *ArgumentsSlice) bun.JSError!Readv { const fd_value = arguments.nextEat() orelse JSC.JSValue.undefined; - const fd = try JSC.Node.fileDescriptorFromJS(ctx, fd_value) orelse { + const fd = try bun.FD.fromJSValidated(fd_value, ctx) orelse { return throwInvalidFdError(ctx, fd_value); }; @@ -1499,9 +1500,9 @@ pub const Arguments = struct { _ = this; } - pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice) bun.JSError!FTruncate { + pub fn fromJS(ctx: *JSC.JSGlobalObject, arguments: *ArgumentsSlice) bun.JSError!FTruncate { const fd_value = arguments.nextEat() orelse JSC.JSValue.undefined; - const fd = try JSC.Node.fileDescriptorFromJS(ctx, fd_value) orelse { + const fd = try bun.FD.fromJSValidated(fd_value, ctx) orelse { return throwInvalidFdError(ctx, fd_value); }; @@ -1534,7 +1535,7 @@ pub const Arguments = struct { this.path.toThreadSafe(); } - pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice) bun.JSError!Chown { + pub fn fromJS(ctx: *JSC.JSGlobalObject, arguments: *ArgumentsSlice) bun.JSError!Chown { const path = try PathLike.fromJS(ctx, arguments) orelse { return ctx.throwInvalidArguments("path must be a string or TypedArray", .{}); }; @@ -1570,9 +1571,9 @@ pub const Arguments = struct { pub fn toThreadSafe(_: *const @This()) void {} - pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice) bun.JSError!Fchown { + pub fn fromJS(ctx: *JSC.JSGlobalObject, arguments: *ArgumentsSlice) bun.JSError!Fchown { const fd_value = arguments.nextEat() orelse JSC.JSValue.undefined; - const fd = try JSC.Node.fileDescriptorFromJS(ctx, fd_value) orelse { + const fd = try bun.FD.fromJSValidated(fd_value, ctx) orelse { return throwInvalidFdError(ctx, fd_value); }; @@ -1621,7 +1622,7 @@ pub const Arguments = struct { this.path.toThreadSafe(); } - pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice) bun.JSError!Lutimes { + pub fn fromJS(ctx: *JSC.JSGlobalObject, arguments: *ArgumentsSlice) bun.JSError!Lutimes { const path = try PathLike.fromJS(ctx, arguments) orelse { return ctx.throwInvalidArguments("path must be a string or TypedArray", .{}); }; @@ -1663,7 +1664,7 @@ pub const Arguments = struct { this.path.deinitAndUnprotect(); } - pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice) bun.JSError!Chmod { + pub fn fromJS(ctx: *JSC.JSGlobalObject, arguments: *ArgumentsSlice) bun.JSError!Chmod { const path = try PathLike.fromJS(ctx, arguments) orelse { return ctx.throwInvalidArguments("path must be a string or TypedArray", .{}); }; @@ -1688,9 +1689,9 @@ pub const Arguments = struct { pub fn toThreadSafe(_: *const @This()) void {} - pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice) bun.JSError!FChmod { + pub fn fromJS(ctx: *JSC.JSGlobalObject, arguments: *ArgumentsSlice) bun.JSError!FChmod { const fd_value = arguments.nextEat() orelse JSC.JSValue.undefined; - const fd = try JSC.Node.fileDescriptorFromJS(ctx, fd_value) orelse { + const fd = try bun.FD.fromJSValidated(fd_value, ctx) orelse { return throwInvalidFdError(ctx, fd_value); }; @@ -1723,7 +1724,7 @@ pub const Arguments = struct { this.path.toThreadSafe(); } - pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice) bun.JSError!Arguments.StatFS { + pub fn fromJS(ctx: *JSC.JSGlobalObject, arguments: *ArgumentsSlice) bun.JSError!Arguments.StatFS { const path = try PathLike.fromJS(ctx, arguments) orelse { return ctx.throwInvalidArguments("path must be a string or TypedArray", .{}); }; @@ -1764,7 +1765,7 @@ pub const Arguments = struct { this.path.toThreadSafe(); } - pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice) bun.JSError!Stat { + pub fn fromJS(ctx: *JSC.JSGlobalObject, arguments: *ArgumentsSlice) bun.JSError!Stat { const path = try PathLike.fromJS(ctx, arguments) orelse { return ctx.throwInvalidArguments("path must be a string or TypedArray", .{}); }; @@ -1802,9 +1803,9 @@ pub const Arguments = struct { pub fn toThreadSafe(_: *@This()) void {} - pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice) bun.JSError!Fstat { + pub fn fromJS(ctx: *JSC.JSGlobalObject, arguments: *ArgumentsSlice) bun.JSError!Fstat { const fd_value = arguments.nextEat() orelse JSC.JSValue.undefined; - const fd = try JSC.Node.fileDescriptorFromJS(ctx, fd_value) orelse { + const fd = try bun.FD.fromJSValidated(fd_value, ctx) orelse { return throwInvalidFdError(ctx, fd_value); }; @@ -1847,7 +1848,7 @@ pub const Arguments = struct { this.new_path.toThreadSafe(); } - pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice) bun.JSError!Link { + pub fn fromJS(ctx: *JSC.JSGlobalObject, arguments: *ArgumentsSlice) bun.JSError!Link { const old_path = try PathLike.fromJS(ctx, arguments) orelse { return ctx.throwInvalidArguments("oldPath must be a string or TypedArray", .{}); }; @@ -1890,7 +1891,7 @@ pub const Arguments = struct { this.new_path.toThreadSafe(); } - pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice) bun.JSError!Symlink { + pub fn fromJS(ctx: *JSC.JSGlobalObject, arguments: *ArgumentsSlice) bun.JSError!Symlink { const old_path = try PathLike.fromJS(ctx, arguments) orelse { return ctx.throwInvalidArguments("target must be a string or TypedArray", .{}); }; @@ -1951,7 +1952,7 @@ pub const Arguments = struct { this.path.toThreadSafe(); } - pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice) bun.JSError!Readlink { + pub fn fromJS(ctx: *JSC.JSGlobalObject, arguments: *ArgumentsSlice) bun.JSError!Readlink { const path = try PathLike.fromJS(ctx, arguments) orelse { return ctx.throwInvalidArguments("path must be a string or TypedArray", .{}); }; @@ -1993,7 +1994,7 @@ pub const Arguments = struct { this.path.toThreadSafe(); } - pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice) bun.JSError!Realpath { + pub fn fromJS(ctx: *JSC.JSGlobalObject, arguments: *ArgumentsSlice) bun.JSError!Realpath { const path = try PathLike.fromJS(ctx, arguments) orelse { return ctx.throwInvalidArguments("path must be a string or TypedArray", .{}); }; @@ -2045,7 +2046,7 @@ pub const Arguments = struct { this.path.toThreadSafe(); } - pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice) bun.JSError!Unlink { + pub fn fromJS(ctx: *JSC.JSGlobalObject, arguments: *ArgumentsSlice) bun.JSError!Unlink { const path = try PathLike.fromJS(ctx, arguments) orelse { return ctx.throwInvalidArguments("path must be a string or TypedArray", .{}); }; @@ -2080,7 +2081,7 @@ pub const Arguments = struct { this.path.deinit(); } - pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice) bun.JSError!RmDir { + pub fn fromJS(ctx: *JSC.JSGlobalObject, arguments: *ArgumentsSlice) bun.JSError!RmDir { const path = try PathLike.fromJS(ctx, arguments) orelse { return ctx.throwInvalidArguments("path must be a string or TypedArray", .{}); }; @@ -2208,7 +2209,7 @@ pub const Arguments = struct { this.prefix.toThreadSafe(); } - pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice) bun.JSError!MkdirTemp { + pub fn fromJS(ctx: *JSC.JSGlobalObject, arguments: *ArgumentsSlice) bun.JSError!MkdirTemp { const prefix = try PathLike.fromJS(ctx, arguments) orelse { return ctx.throwInvalidArgumentTypeValue("prefix", "string, Buffer, or URL", arguments.next() orelse .undefined); }; @@ -2266,7 +2267,7 @@ pub const Arguments = struct { }; } - pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice) bun.JSError!Readdir { + pub fn fromJS(ctx: *JSC.JSGlobalObject, arguments: *ArgumentsSlice) bun.JSError!Readdir { const path = try PathLike.fromJS(ctx, arguments) orelse { return ctx.throwInvalidArguments("path must be a string or TypedArray", .{}); }; @@ -2317,9 +2318,9 @@ pub const Arguments = struct { pub fn deinit(_: Close) void {} pub fn toThreadSafe(_: Close) void {} - pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice) bun.JSError!Close { + pub fn fromJS(ctx: *JSC.JSGlobalObject, arguments: *ArgumentsSlice) bun.JSError!Close { const fd_value = arguments.nextEat() orelse JSC.JSValue.undefined; - const fd = try JSC.Node.fileDescriptorFromJS(ctx, fd_value) orelse { + const fd = try bun.FD.fromJSValidated(fd_value, ctx) orelse { return throwInvalidFdError(ctx, fd_value); }; @@ -2344,7 +2345,7 @@ pub const Arguments = struct { this.path.toThreadSafe(); } - pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice) bun.JSError!Open { + pub fn fromJS(ctx: *JSC.JSGlobalObject, arguments: *ArgumentsSlice) bun.JSError!Open { const path = try PathLike.fromJS(ctx, arguments) orelse { return ctx.throwInvalidArguments("path must be a string or TypedArray", .{}); }; @@ -2404,9 +2405,9 @@ pub const Arguments = struct { _ = self; } - pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice) bun.JSError!Futimes { + pub fn fromJS(ctx: *JSC.JSGlobalObject, arguments: *ArgumentsSlice) bun.JSError!Futimes { const fd_value = arguments.nextEat() orelse JSC.JSValue.undefined; - const fd = try JSC.Node.fileDescriptorFromJS(ctx, fd_value) orelse { + const fd = try bun.FD.fromJSValidated(fd_value, ctx) orelse { return throwInvalidFdError(ctx, fd_value); }; @@ -2476,9 +2477,9 @@ pub const Arguments = struct { self.buffer.toThreadSafe(); } - pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice) bun.JSError!Write { + pub fn fromJS(ctx: *JSC.JSGlobalObject, arguments: *ArgumentsSlice) bun.JSError!Write { const fd_value = arguments.nextEat() orelse JSC.JSValue.undefined; - const fd = try JSC.Node.fileDescriptorFromJS(ctx, fd_value) orelse { + const fd = try bun.FD.fromJSValidated(fd_value, ctx) orelse { return throwInvalidFdError(ctx, fd_value); }; @@ -2577,13 +2578,13 @@ pub const Arguments = struct { this.buffer.buffer.value.unprotect(); } - pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice) bun.JSError!Read { + pub fn fromJS(ctx: *JSC.JSGlobalObject, arguments: *ArgumentsSlice) bun.JSError!Read { // About half of the normalization has already been done. The second half is done in the native code. // fs_binding.read(fd, buffer, offset, length, position) // fd = getValidatedFd(fd); const fd_value = arguments.nextEat() orelse JSC.JSValue.undefined; - const fd = try JSC.Node.fileDescriptorFromJS(ctx, fd_value) orelse { + const fd = try bun.FD.fromJSValidated(fd_value, ctx) orelse { return throwInvalidFdError(ctx, fd_value); }; @@ -2718,7 +2719,7 @@ pub const Arguments = struct { self.path.toThreadSafe(); } - pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice) bun.JSError!ReadFile { + pub fn fromJS(ctx: *JSC.JSGlobalObject, arguments: *ArgumentsSlice) bun.JSError!ReadFile { const path = try PathOrFileDescriptor.fromJS(ctx, arguments, bun.default_allocator) orelse { return ctx.throwInvalidArguments("path must be a string or a file descriptor", .{}); }; @@ -2811,7 +2812,7 @@ pub const Arguments = struct { signal.unref(); } } - pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice) bun.JSError!WriteFile { + pub fn fromJS(ctx: *JSC.JSGlobalObject, arguments: *ArgumentsSlice) bun.JSError!WriteFile { const path = try PathOrFileDescriptor.fromJS(ctx, arguments, bun.default_allocator) orelse { return ctx.throwInvalidArguments("path must be a string or a file descriptor", .{}); }; @@ -2912,7 +2913,7 @@ pub const Arguments = struct { self.path.deinit(); } - pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice) bun.JSError!OpenDir { + pub fn fromJS(ctx: *JSC.JSGlobalObject, arguments: *ArgumentsSlice) bun.JSError!OpenDir { const path = try PathLike.fromJS(ctx, arguments) orelse { return ctx.throwInvalidArguments("path must be a string or TypedArray", .{}); }; @@ -2968,7 +2969,7 @@ pub const Arguments = struct { } } - pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice) bun.JSError!Exists { + pub fn fromJS(ctx: *JSC.JSGlobalObject, arguments: *ArgumentsSlice) bun.JSError!Exists { return Exists{ .path = try PathLike.fromJS(ctx, arguments), }; @@ -2991,7 +2992,7 @@ pub const Arguments = struct { this.path.deinitAndUnprotect(); } - pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice) bun.JSError!Access { + pub fn fromJS(ctx: *JSC.JSGlobalObject, arguments: *ArgumentsSlice) bun.JSError!Access { const path = try PathLike.fromJS(ctx, arguments) orelse { return ctx.throwInvalidArguments("path must be a string or TypedArray", .{}); }; @@ -3019,9 +3020,9 @@ pub const Arguments = struct { _ = self; } - pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice) bun.JSError!FdataSync { + pub fn fromJS(ctx: *JSC.JSGlobalObject, arguments: *ArgumentsSlice) bun.JSError!FdataSync { const fd_value = arguments.nextEat() orelse JSC.JSValue.undefined; - const fd = try JSC.Node.fileDescriptorFromJS(ctx, fd_value) orelse { + const fd = try bun.FD.fromJSValidated(fd_value, ctx) orelse { return throwInvalidFdError(ctx, fd_value); }; @@ -3049,7 +3050,7 @@ pub const Arguments = struct { this.dest.deinitAndUnprotect(); } - pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice) bun.JSError!CopyFile { + pub fn fromJS(ctx: *JSC.JSGlobalObject, arguments: *ArgumentsSlice) bun.JSError!CopyFile { const src = try PathLike.fromJS(ctx, arguments) orelse { return ctx.throwInvalidArguments("src must be a string or TypedArray", .{}); }; @@ -3094,7 +3095,7 @@ pub const Arguments = struct { } } - pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice) bun.JSError!Cp { + pub fn fromJS(ctx: *JSC.JSGlobalObject, arguments: *ArgumentsSlice) bun.JSError!Cp { const src = try PathLike.fromJS(ctx, arguments) orelse { return ctx.throwInvalidArguments("src must be a string or TypedArray", .{}); }; @@ -3169,9 +3170,9 @@ pub const Arguments = struct { pub fn deinit(_: Fsync) void {} pub fn toThreadSafe(_: *const @This()) void {} - pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice) bun.JSError!Fsync { + pub fn fromJS(ctx: *JSC.JSGlobalObject, arguments: *ArgumentsSlice) bun.JSError!Fsync { const fd_value = arguments.nextEat() orelse JSC.JSValue.undefined; - const fd = try JSC.Node.fileDescriptorFromJS(ctx, fd_value) orelse { + const fd = try bun.FD.fromJSValidated(fd_value, ctx) orelse { return throwInvalidFdError(ctx, fd_value); }; @@ -3240,14 +3241,14 @@ const Return = struct { pub const Lstat = StatOrNotFound; pub const Mkdir = StringOrUndefined; pub const Mkdtemp = JSC.ZigString; - pub const Open = FDImpl; + pub const Open = FD; pub const WriteFile = void; pub const Readv = Read; pub const StatFS = bun.JSC.Node.StatFS; pub const Read = struct { bytes_read: u52, - pub fn toJS(this: Read, _: JSC.C.JSContextRef) JSC.JSValue { + pub fn toJS(this: Read, _: *JSC.JSGlobalObject) JSC.JSValue { return JSC.JSValue.jsNumberFromUint64(this.bytes_read); } }; @@ -3281,7 +3282,7 @@ const Return = struct { }; // Excited for the issue that's like "cannot read file bigger than 2 GB" - pub fn toJS(this: *const WritePromise, globalObject: JSC.C.JSContextRef) JSC.C.JSValueRef { + pub fn toJS(this: *const WritePromise, globalObject: *JSC.JSGlobalObject) JSC.C.JSValueRef { defer if (!this.buffer_val.isEmptyOrUndefinedOrNull()) this.buffer_val.unprotect(); @@ -3421,7 +3422,7 @@ pub const NodeFS = struct { }; defer { - _ = Syscall.close(fd); + fd.close(); } while (data.len > 0) { @@ -3438,7 +3439,10 @@ pub const NodeFS = struct { } pub fn close(_: *NodeFS, args: Arguments.Close, _: Flavor) Maybe(Return.Close) { - return if (Syscall.close(args.fd)) |err| .{ .err = err } else Maybe(Return.Close).success; + return if (args.fd.closeAllowingBadFileDescriptor(null)) |err| + .{ .err = err } + else + .success; } pub fn uv_close(_: *NodeFS, args: Arguments.Close, rc: i64) Maybe(Return.Close) { @@ -3607,7 +3611,7 @@ pub const NodeFS = struct { .err => |err| return .{ .err = err.withPath(args.src.slice()) }, }; defer { - _ = Syscall.close(src_fd); + src_fd.close(); } var flags: Mode = bun.O.CREAT | bun.O.WRONLY; @@ -3623,7 +3627,7 @@ pub const NodeFS = struct { defer { _ = Syscall.ftruncate(dest_fd, @as(std.c.off_t, @intCast(@as(u63, @truncate(wrote))))); _ = Syscall.fchmod(dest_fd, stat_.mode); - _ = Syscall.close(dest_fd); + dest_fd.close(); } return copyFileUsingReadWriteLoop(src, dest, src_fd, dest_fd, @intCast(@max(stat_.size, 0)), &wrote); @@ -3652,7 +3656,7 @@ pub const NodeFS = struct { .err => |err| return .{ .err = err }, }; defer { - _ = Syscall.close(src_fd); + src_fd.close(); } const stat_: linux.Stat = switch (Syscall.fstat(src_fd)) { @@ -3680,13 +3684,13 @@ pub const NodeFS = struct { // https://manpages.debian.org/testing/manpages-dev/ioctl_ficlone.2.en.html if (args.mode.isForceClone()) { if (ret.errnoSysP(bun.C.linux.ioctl_ficlone(dest_fd, src_fd), .ioctl_ficlone, dest)) |err| { - _ = Syscall.close(dest_fd); + dest_fd.close(); // This is racey, but it's the best we can do _ = bun.sys.unlink(dest); return err; } _ = Syscall.fchmod(dest_fd, stat_.mode); - _ = Syscall.close(dest_fd); + dest_fd.close(); return ret.success; } @@ -3695,7 +3699,7 @@ pub const NodeFS = struct { const rc = bun.C.linux.ioctl_ficlone(dest_fd, src_fd); if (rc == 0) { _ = Syscall.fchmod(dest_fd, stat_.mode); - _ = Syscall.close(dest_fd); + dest_fd.close(); return ret.success; } @@ -3707,7 +3711,7 @@ pub const NodeFS = struct { defer { _ = linux.ftruncate(dest_fd.cast(), @as(i64, @intCast(@as(u63, @truncate(wrote))))); _ = linux.fchmod(dest_fd.cast(), stat_.mode); - _ = Syscall.close(dest_fd); + dest_fd.close(); } var off_in_copy = @as(i64, @bitCast(@as(u64, 0))); @@ -3843,7 +3847,7 @@ pub const NodeFS = struct { if (Environment.isWindows) { return Syscall.fdatasync(args.fd); } - return Maybe(Return.Fdatasync).errnoSysFd(system.fdatasync(args.fd.int()), .fdatasync, args.fd) orelse Maybe(Return.Fdatasync).success; + return Maybe(Return.Fdatasync).errnoSysFd(system.fdatasync(args.fd.native()), .fdatasync, args.fd) orelse Maybe(Return.Fdatasync).success; } pub fn fstat(_: *NodeFS, args: Arguments.Fstat, _: Flavor) Maybe(Return.Fstat) { @@ -3857,7 +3861,7 @@ pub const NodeFS = struct { if (Environment.isWindows) { return Syscall.fsync(args.fd); } - return Maybe(Return.Fsync).errnoSys(system.fsync(args.fd.int()), .fsync) orelse + return Maybe(Return.Fsync).errnoSys(system.fsync(args.fd.native()), .fsync) orelse Maybe(Return.Fsync).success; } @@ -3869,7 +3873,7 @@ pub const NodeFS = struct { if (comptime Environment.isWindows) { var req: uv.fs_t = uv.fs_t.uninitialized; defer req.deinit(); - const rc = uv.uv_fs_futime(uv.Loop.get(), &req, bun.uvfdcast(args.fd), args.atime, args.mtime, null); + const rc = uv.uv_fs_futime(uv.Loop.get(), &req, args.fd.uv(), args.atime, args.mtime, null); return if (rc.errno()) |e| .{ .err = .{ .errno = e, @@ -4204,9 +4208,7 @@ pub const NodeFS = struct { .err => |err| .{ .err = err.withPath(args.path.slice()), }, - .result => |fd| fd: { - break :fd .{ .result = FDImpl.decode(fd) }; - }, + .result => |fd| .{ .result = fd }, }; } @@ -4220,7 +4222,7 @@ pub const NodeFS = struct { .from_libuv = true, } }; } - return Maybe(Return.Open).initResult(FDImpl.decode(bun.toFD(@as(u32, @intCast(rc))))); + return Maybe(Return.Open).initResult(.fromUV(@intCast(rc))); } pub fn uv_statfs(_: *NodeFS, args: Arguments.StatFS, req: *uv.fs_t, rc: i64) Maybe(Return.StatFS) { @@ -4467,7 +4469,7 @@ pub const NodeFS = struct { comptime ExpectedType: type, entries: *std.ArrayList(ExpectedType), ) Maybe(void) { - const dir = fd.asDir(); + const dir = fd.stdDir(); const is_u16 = comptime Environment.isWindows and (ExpectedType == bun.String or ExpectedType == bun.JSC.Node.Dirent); var dirent_path: bun.String = bun.String.dead; @@ -4611,11 +4613,11 @@ pub const NodeFS = struct { defer { if (comptime !is_root) { - _ = Syscall.close(fd); + fd.close(); } } - var iterator = DirIterator.iterate(fd.asDir(), .u8); + var iterator = DirIterator.iterate(fd.stdDir(), .u8); var entry = iterator.next(); var dirent_path_prev: bun.String = bun.String.empty; defer { @@ -4724,7 +4726,7 @@ pub const NodeFS = struct { // all other paths are relative to the root directory // so we can only close it once we're 100% done if (root_fd != bun.invalid_fd) { - _ = Syscall.close(root_fd); + root_fd.close(); } } @@ -4765,11 +4767,11 @@ pub const NodeFS = struct { defer { if (fd != root_fd) { - _ = Syscall.close(fd); + fd.close(); } } - var iterator = DirIterator.iterate(fd.asDir(), .u8); + var iterator = DirIterator.iterate(fd.stdDir(), .u8); var entry = iterator.next(); var dirent_path_prev: bun.String = bun.String.dead; defer { @@ -4925,7 +4927,7 @@ pub const NodeFS = struct { .result => |fd_| fd_, }; - defer _ = Syscall.close(fd); + defer fd.close(); var entries = std.ArrayList(ExpectedType).init(bun.default_allocator); return switch (readdirWithEntries(args, fd, path, ExpectedType, &entries)) { @@ -5016,9 +5018,9 @@ pub const NodeFS = struct { }, .fd => |fd| fd, }; - const fd = bun.toLibUVOwnedFD(fd_maybe_windows) catch { + const fd = fd_maybe_windows.makeLibUVOwned() catch { if (args.path == .path) - _ = Syscall.close(fd_maybe_windows); + fd_maybe_windows.close(); return .{ .err = .{ @@ -5030,7 +5032,7 @@ pub const NodeFS = struct { defer { if (args.path == .path) - _ = Syscall.close(fd); + fd.close(); } if (args.aborted()) return Maybe(Return.ReadFileWithOptions).aborted; @@ -5325,7 +5327,7 @@ pub const NodeFS = struct { defer { if (args.file == .path) - _ = bun.sys.close(fd); + fd.close(); } if (args.aborted()) return Maybe(Return.WriteFile).aborted; @@ -5531,9 +5533,7 @@ pub const NodeFS = struct { .result => |fd_| fd_, }; - defer { - _ = Syscall.close(fd); - } + defer fd.close(); const buf = switch (Syscall.getFdPath(fd, &outbuf)) { .err => |err| return .{ .err = err.withPath(path) }, @@ -5874,7 +5874,7 @@ pub const NodeFS = struct { .syscall = .truncate, } }; } - defer _ = Syscall.close(file.result); + defer file.result.close(); const ret = Syscall.ftruncate(file.result, len); return switch (ret) { .result => ret, @@ -6126,7 +6126,7 @@ pub const NodeFS = struct { } const fd = switch (Syscall.openatOSPath( - bun.toFD((std.fs.cwd().fd)), + .cwd(), src, bun.O.DIRECTORY | bun.O.RDONLY, 0, @@ -6136,7 +6136,7 @@ pub const NodeFS = struct { }, .result => |fd_| fd_, }; - defer _ = Syscall.close(fd); + defer fd.close(); switch (this.mkdirRecursiveOSPath(dest, Arguments.Mkdir.DefaultMode, false)) { .err => |err| return .{ .err = err }, @@ -6144,7 +6144,7 @@ pub const NodeFS = struct { } var iterator = iterator: { - const dir = fd.asDir(); + const dir = fd.stdDir(); break :iterator DirIterator.iterate(dir, if (Environment.isWindows) .u16 else .u8); }; var entry = iterator.next(); @@ -6299,7 +6299,7 @@ pub const NodeFS = struct { }, }; defer { - _ = Syscall.close(src_fd); + src_fd.close(); } var flags: Mode = bun.O.CREAT | bun.O.WRONLY; @@ -6340,7 +6340,7 @@ pub const NodeFS = struct { defer { _ = Syscall.ftruncate(dest_fd, @intCast(@as(u63, @truncate(wrote)))); _ = Syscall.fchmod(dest_fd, stat_.mode); - _ = Syscall.close(dest_fd); + dest_fd.close(); } return copyFileUsingReadWriteLoop(src, dest, src_fd, dest_fd, @intCast(@max(stat_.size, 0)), &wrote); @@ -6382,7 +6382,7 @@ pub const NodeFS = struct { }, }; defer { - _ = Syscall.close(src_fd); + src_fd.close(); } const stat_: linux.Stat = switch (Syscall.fstat(src_fd)) { @@ -6439,7 +6439,7 @@ pub const NodeFS = struct { const rc = bun.C.linux.ioctl_ficlone(dest_fd, src_fd); if (rc == 0) { _ = Syscall.fchmod(dest_fd, stat_.mode); - _ = Syscall.close(dest_fd); + dest_fd.close(); return ret.success; } @@ -6449,7 +6449,7 @@ pub const NodeFS = struct { defer { _ = Syscall.ftruncate(dest_fd, @as(i64, @intCast(@as(u63, @truncate(wrote))))); _ = Syscall.fchmod(dest_fd, stat_.mode); - _ = Syscall.close(dest_fd); + dest_fd.close(); } var off_in_copy = @as(i64, @bitCast(@as(u64, 0))); diff --git a/src/bun.js/node/node_fs_binding.zig b/src/bun.js/node/node_fs_binding.zig index e8e527e5eb..27c0bd5fb6 100644 --- a/src/bun.js/node/node_fs_binding.zig +++ b/src/bun.js/node/node_fs_binding.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const std = @import("std"); const Flavor = JSC.Node.Flavor; @@ -96,7 +96,11 @@ fn callSync(comptime FunctionEnum: NodeFSFunctionEnum) NodeFSFunction { pub const NodeJSFS = struct { node_fs: JSC.Node.NodeFS = .{}, - pub usingnamespace JSC.Codegen.JSNodeJSFS; + pub const js = JSC.Codegen.JSNodeJSFS; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; + pub const new = bun.TrivialNew(@This()); pub fn finalize(this: *JSC.Node.NodeJSFS) void { diff --git a/src/bun.js/node/node_fs_constant.zig b/src/bun.js/node/node_fs_constant.zig index 4dad6c1fae..321b25bbed 100644 --- a/src/bun.js/node/node_fs_constant.zig +++ b/src/bun.js/node/node_fs_constant.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const Environment = bun.Environment; const std = @import("std"); diff --git a/src/bun.js/node/node_fs_stat_watcher.zig b/src/bun.js/node/node_fs_stat_watcher.zig index 3e979b1207..2c03d64fc4 100644 --- a/src/bun.js/node/node_fs_stat_watcher.zig +++ b/src/bun.js/node/node_fs_stat_watcher.zig @@ -1,6 +1,6 @@ const std = @import("std"); const JSC = bun.JSC; -const bun = @import("root").bun; +const bun = @import("bun"); const Fs = @import("../../fs.zig"); const Path = @import("../../resolver/resolve_path.zig"); const Encoder = JSC.WebCore.Encoder; @@ -197,7 +197,10 @@ pub const StatWatcher = struct { last_stat: bun.Stat, last_jsvalue: JSC.Strong, - pub usingnamespace JSC.Codegen.JSStatWatcher; + pub const js = JSC.Codegen.JSStatWatcher; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; pub fn eventLoop(this: StatWatcher) *EventLoop { return this.ctx.eventLoop(); @@ -230,7 +233,7 @@ pub const StatWatcher = struct { bigint: bool, interval: i32, - global_this: JSC.C.JSContextRef, + global_this: *JSC.JSGlobalObject, pub fn fromJS(global: *JSC.JSGlobalObject, arguments: *ArgumentsSlice) bun.JSError!Arguments { const path = try PathLike.fromJSWithAllocator(global, arguments, bun.default_allocator) orelse { @@ -390,7 +393,7 @@ pub const StatWatcher = struct { const vm = this.globalThis.bunVM(); - _ = StatWatcher.listenerGetCached(this.js_this).?.call( + _ = js.listenerGetCached(this.js_this).?.call( this.globalThis, .undefined, &[2]JSC.JSValue{ @@ -427,7 +430,7 @@ pub const StatWatcher = struct { const current_jsvalue = statToJSStats(this.globalThis, &this.last_stat, this.bigint); this.last_jsvalue.set(this.globalThis, current_jsvalue); - _ = StatWatcher.listenerGetCached(this.js_this).?.call( + _ = js.listenerGetCached(this.js_this).?.call( this.globalThis, .undefined, &[2]JSC.JSValue{ @@ -489,7 +492,7 @@ pub const StatWatcher = struct { const js_this = StatWatcher.toJS(this, this.globalThis); this.js_this = js_this; - StatWatcher.listenerSetCached(js_this, this.globalThis, args.listener); + js.listenerSetCached(js_this, this.globalThis, args.listener); InitialStatTask.createAndSchedule(this); return this; diff --git a/src/bun.js/node/node_fs_watcher.zig b/src/bun.js/node/node_fs_watcher.zig index 9bfc451873..fc5798a104 100644 --- a/src/bun.js/node/node_fs_watcher.zig +++ b/src/bun.js/node/node_fs_watcher.zig @@ -1,6 +1,6 @@ const std = @import("std"); const JSC = bun.JSC; -const bun = @import("root").bun; +const bun = @import("bun"); const Fs = @import("../../fs.zig"); const Path = @import("../../resolver/resolve_path.zig"); const Encoder = JSC.WebCore.Encoder; @@ -19,7 +19,10 @@ const log = Output.scoped(.@"fs.watch", true); const PathWatcher = if (Environment.isWindows) @import("./win_watcher.zig") else @import("./path_watcher.zig"); pub const FSWatcher = struct { - pub usingnamespace JSC.Codegen.JSFSWatcher; + pub const js = JSC.Codegen.JSFSWatcher; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; ctx: *VirtualMachine, verbose: bool = false, @@ -333,14 +336,14 @@ pub const FSWatcher = struct { pub const Arguments = struct { path: PathLike, listener: JSC.JSValue, - global_this: JSC.C.JSContextRef, + global_this: *JSC.JSGlobalObject, signal: ?*JSC.AbortSignal, persistent: bool, recursive: bool, encoding: JSC.Node.Encoding, verbose: bool, - pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice) bun.JSError!Arguments { + pub fn fromJS(ctx: *JSC.JSGlobalObject, arguments: *ArgumentsSlice) bun.JSError!Arguments { const path = try PathLike.fromJS(ctx, arguments) orelse { return ctx.throwInvalidArguments("filename must be a string or TypedArray", .{}); }; @@ -434,10 +437,10 @@ pub const FSWatcher = struct { _ = this.pending_activity_count.fetchAdd(1, .monotonic); } - const js_this = FSWatcher.toJS(this, this.globalThis); + const js_this = this.toJS(this.globalThis); js_this.ensureStillAlive(); this.js_this = js_this; - FSWatcher.listenerSetCached(js_this, this.globalThis, listener); + js.listenerSetCached(js_this, this.globalThis, listener); if (this.signal) |s| { // already aborted? @@ -473,7 +476,7 @@ pub const FSWatcher = struct { if (this.js_this != .zero) { const js_this = this.js_this; js_this.ensureStillAlive(); - if (FSWatcher.listenerGetCached(js_this)) |listener| { + if (js.listenerGetCached(js_this)) |listener| { listener.ensureStillAlive(); var args = [_]JSC.JSValue{ EventType.@"error".toJS(this.globalThis), @@ -493,7 +496,7 @@ pub const FSWatcher = struct { if (this.js_this != .zero) { const js_this = this.js_this; js_this.ensureStillAlive(); - if (FSWatcher.listenerGetCached(js_this)) |listener| { + if (js.listenerGetCached(js_this)) |listener| { listener.ensureStillAlive(); const globalObject = this.globalThis; var args = [_]JSC.JSValue{ @@ -511,7 +514,7 @@ pub const FSWatcher = struct { pub fn emitWithFilename(this: *FSWatcher, file_name: JSC.JSValue, comptime eventType: EventType) void { const js_this = this.js_this; if (js_this == .zero) return; - const listener = FSWatcher.listenerGetCached(js_this) orelse return; + const listener = js.listenerGetCached(js_this) orelse return; emitJS(listener, this.globalThis, file_name, eventType); } @@ -519,7 +522,7 @@ pub const FSWatcher = struct { bun.assert(event_type != .@"error"); const js_this = this.js_this; if (js_this == .zero) return; - const listener = FSWatcher.listenerGetCached(js_this) orelse return; + const listener = js.listenerGetCached(js_this) orelse return; const globalObject = this.globalThis; var filename: JSC.JSValue = .undefined; if (file_name.len > 0) { @@ -598,7 +601,7 @@ pub const FSWatcher = struct { this.detach(); if (js_this != .zero) { - if (FSWatcher.listenerGetCached(js_this)) |listener| { + if (FSWatcher.js.listenerGetCached(js_this)) |listener| { _ = this.refTask(); log("emit('close')", .{}); emitJS(listener, this.globalThis, .undefined, .close); diff --git a/src/bun.js/node/node_http_binding.zig b/src/bun.js/node/node_http_binding.zig index ab4a9ae4a9..668447613e 100644 --- a/src/bun.js/node/node_http_binding.zig +++ b/src/bun.js/node/node_http_binding.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Environment = bun.Environment; const JSC = bun.JSC; const string = bun.string; diff --git a/src/bun.js/node/node_net_binding.zig b/src/bun.js/node/node_net_binding.zig index eb038a8511..0582c15535 100644 --- a/src/bun.js/node/node_net_binding.zig +++ b/src/bun.js/node/node_net_binding.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const C = bun.c; const Environment = bun.Environment; const JSC = bun.JSC; @@ -81,7 +81,7 @@ pub fn createBinding(global: *JSC.JSGlobalObject) JSC.JSValue { const SocketAddress = bun.JSC.GeneratedClassesList.SocketAddress; const net = JSC.JSValue.createEmptyObjectWithNullPrototype(global); - net.put(global, "SocketAddress", SocketAddress.getConstructor(global)); + net.put(global, "SocketAddress", SocketAddress.js.getConstructor(global)); return net; } diff --git a/src/bun.js/node/node_os.zig b/src/bun.js/node/node_os.zig index ee4eaf3aa9..8a95333725 100644 --- a/src/bun.js/node/node_os.zig +++ b/src/bun.js/node/node_os.zig @@ -1,6 +1,6 @@ const std = @import("std"); const builtin = @import("builtin"); -const bun = @import("root").bun; +const bun = @import("bun"); const C = bun.C; const string = bun.string; const strings = bun.strings; diff --git a/src/bun.js/node/node_util_binding.zig b/src/bun.js/node/node_util_binding.zig index 71b0ccf5fc..2d709d60d4 100644 --- a/src/bun.js/node/node_util_binding.zig +++ b/src/bun.js/node/node_util_binding.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Allocator = std.mem.Allocator; const Environment = bun.Environment; const JSC = bun.JSC; diff --git a/src/bun.js/node/node_zlib_binding.zig b/src/bun.js/node/node_zlib_binding.zig index 8e4ae02afe..6fe612d7d8 100644 --- a/src/bun.js/node/node_zlib_binding.zig +++ b/src/bun.js/node/node_zlib_binding.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Environment = bun.Environment; const JSC = bun.JSC; const string = bun.string; @@ -156,7 +156,7 @@ pub fn CompressionStream(comptime T: type) type { this.stream.updateWriteResult(&this.write_result.?[1], &this.write_result.?[0]); this_value.ensureStillAlive(); - const write_callback: JSC.JSValue = T.writeCallbackGetCached(this_value).?; + const write_callback: JSC.JSValue = T.js.writeCallbackGetCached(this_value).?; vm.eventLoop().runCallback(write_callback, global, this_value, &.{}); @@ -248,13 +248,13 @@ pub fn CompressionStream(comptime T: type) type { pub fn setOnError(_: *T, this_value: JSC.JSValue, globalObject: *JSC.JSGlobalObject, value: JSC.JSValue) bool { if (value.isFunction()) { - T.errorCallbackSetCached(this_value, globalObject, value); + T.js.errorCallbackSetCached(this_value, globalObject, value); } return true; } pub fn getOnError(_: *T, this_value: JSC.JSValue, _: *JSC.JSGlobalObject) JSC.JSValue { - return T.errorCallbackGetCached(this_value) orelse .undefined; + return T.js.errorCallbackGetCached(this_value) orelse .undefined; } /// returns true if no error was detected/emitted @@ -272,7 +272,8 @@ pub fn CompressionStream(comptime T: type) type { var code_str = bun.String.createFormat("{s}", .{std.mem.sliceTo(err_.code, 0) orelse ""}) catch bun.outOfMemory(); const code_value = code_str.transferToJS(globalThis); - const callback: JSC.JSValue = T.errorCallbackGetCached(this_value) orelse Output.panic("Assertion failure: cachedErrorCallback is null in node:zlib binding", .{}); + const callback: JSC.JSValue = T.js.errorCallbackGetCached(this_value) orelse + Output.panic("Assertion failure: cachedErrorCallback is null in node:zlib binding", .{}); _ = try callback.call(globalThis, this_value, &.{ msg_value, err_value, code_value }); this.write_in_progress = false; @@ -315,7 +316,11 @@ pub const SNativeZlib = struct { pub const ref = RefCount.ref; pub const deref = RefCount.deref; - pub usingnamespace JSC.Codegen.JSNativeZlib; + pub const js = JSC.Codegen.JSNativeZlib; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; + pub usingnamespace CompressionStream(@This()); ref_count: RefCount, @@ -379,11 +384,11 @@ pub const SNativeZlib = struct { const dictionary = if (arguments[6].isUndefined()) null else arguments[6].asArrayBuffer(globalThis).?.byteSlice(); this.write_result = writeResult; - SNativeZlib.writeCallbackSetCached(this_value, globalThis, writeCallback); + js.writeCallbackSetCached(this_value, globalThis, writeCallback); // Keep the dictionary alive by keeping a reference to it in the JS object. if (dictionary != null) { - SNativeZlib.dictionarySetCached(this_value, globalThis, arguments[6]); + js.dictionarySetCached(this_value, globalThis, arguments[6]); } this.stream.init(level, windowBits, memLevel, strategy, dictionary); @@ -685,7 +690,11 @@ pub const SNativeBrotli = struct { pub const ref = RefCount.ref; pub const deref = RefCount.deref; - pub usingnamespace JSC.Codegen.JSNativeBrotli; + pub const js = JSC.Codegen.JSNativeBrotli; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; + pub usingnamespace CompressionStream(@This()); ref_count: RefCount, @@ -751,7 +760,7 @@ pub const SNativeBrotli = struct { this.write_result = writeResult; - SNativeBrotli.writeCallbackSetCached(this_value, globalThis, writeCallback); + js.writeCallbackSetCached(this_value, globalThis, writeCallback); var err = this.stream.init(); if (err.isError()) { diff --git a/src/bun.js/node/os/constants.zig b/src/bun.js/node/os/constants.zig index cb3d8c56d0..6b5e67b352 100644 --- a/src/bun.js/node/os/constants.zig +++ b/src/bun.js/node/os/constants.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Environment = bun.Environment; const JSC = bun.JSC; diff --git a/src/bun.js/node/path.zig b/src/bun.js/node/path.zig index a6d0231d92..31541a44aa 100644 --- a/src/bun.js/node/path.zig +++ b/src/bun.js/node/path.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const std = @import("std"); const windows = bun.windows; diff --git a/src/bun.js/node/path_watcher.zig b/src/bun.js/node/path_watcher.zig index c98fed2202..db35bd7026 100644 --- a/src/bun.js/node/path_watcher.zig +++ b/src/bun.js/node/path_watcher.zig @@ -6,10 +6,11 @@ const Fs = @import("../../fs.zig"); const Mutex = bun.Mutex; const FSEvents = @import("./fs_events.zig"); -const bun = @import("root").bun; +const bun = @import("bun"); const Output = bun.Output; const Environment = bun.Environment; -const StoredFileDescriptorType = bun.StoredFileDescriptorType; +const StoredFileDescriptorType = bun.FD; +const FD = bun.FD; const string = bun.string; const JSC = bun.JSC; const VirtualMachine = JSC.VirtualMachine; @@ -42,7 +43,7 @@ pub const PathWatcherManager = struct { has_pending_tasks: std.atomic.Value(bool) = std.atomic.Value(bool).init(false), mutex: Mutex, const PathInfo = struct { - fd: StoredFileDescriptorType = .zero, + fd: FD = .invalid, is_file: bool = true, path: [:0]const u8, dirname: string, @@ -437,7 +438,7 @@ pub const PathWatcherManager = struct { const manager = this.manager; const path = this.path; const fd = path.fd; - var iter = fd.asDir().iterate(); + var iter = fd.stdDir().iterate(); // now we iterate over all files and directories while (iter.next() catch |err| { @@ -491,7 +492,7 @@ pub const PathWatcherManager = struct { child_path.path, child_path.hash, options.Loader.file, - .zero, + .invalid, null, false, )) { @@ -584,7 +585,7 @@ pub const PathWatcherManager = struct { const path = watcher.path; if (path.is_file) { - try this.main_watcher.addFile(path.fd, path.path, path.hash, .file, .zero, null, false).unwrap(); + try this.main_watcher.addFile(path.fd, path.path, path.hash, .file, .invalid, null, false).unwrap(); } else { if (comptime Environment.isMac) { if (watcher.fsevents_watcher != null) { @@ -707,7 +708,7 @@ pub const PathWatcherManager = struct { var it = this.file_paths.iterator(); while (it.next()) |*entry| { const path = entry.value_ptr.*; - _ = bun.sys.close(path.fd); + path.fd.close(); bun.default_allocator.free(path.path); } diff --git a/src/bun.js/node/types.zig b/src/bun.js/node/types.zig index 2c2edb9cdb..84ab5b8743 100644 --- a/src/bun.js/node/types.zig +++ b/src/bun.js/node/types.zig @@ -1,6 +1,6 @@ const std = @import("std"); const builtin = @import("builtin"); -const bun = @import("root").bun; +const bun = @import("bun"); const meta = bun.meta; const windows = bun.windows; const heap_allocator = bun.default_allocator; @@ -497,7 +497,7 @@ pub const StringOrBuffer = union(enum) { return result; } - pub fn toJS(this: *StringOrBuffer, ctx: JSC.C.JSContextRef) JSC.JSValue { + pub fn toJS(this: *StringOrBuffer, ctx: *JSC.JSGlobalObject) JSC.JSValue { return switch (this.*) { inline .threadsafe_string, .string => |*str| { return str.transferToJS(ctx); @@ -962,11 +962,11 @@ pub const PathLike = union(enum) { return sliceZWithForceCopy(this, buf, false); } - pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice) bun.JSError!?PathLike { + pub fn fromJS(ctx: *JSC.JSGlobalObject, arguments: *ArgumentsSlice) bun.JSError!?PathLike { return fromJSWithAllocator(ctx, arguments, bun.default_allocator); } - pub fn fromJSWithAllocator(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, allocator: std.mem.Allocator) bun.JSError!?PathLike { + pub fn fromJSWithAllocator(ctx: *JSC.JSGlobalObject, arguments: *ArgumentsSlice, allocator: std.mem.Allocator) bun.JSError!?PathLike { const arg = arguments.next() orelse return null; switch (arg.jsType()) { .Uint8Array, @@ -1063,7 +1063,7 @@ pub const PathLike = union(enum) { }; pub const Valid = struct { - pub fn pathSlice(zig_str: JSC.ZigString.Slice, ctx: JSC.C.JSContextRef) bun.JSError!void { + pub fn pathSlice(zig_str: JSC.ZigString.Slice, ctx: *JSC.JSGlobalObject) bun.JSError!void { switch (zig_str.len) { 0...bun.MAX_PATH_BYTES => return, else => { @@ -1075,7 +1075,7 @@ pub const Valid = struct { comptime unreachable; } - pub fn pathStringLength(len: usize, ctx: JSC.C.JSContextRef) bun.JSError!void { + pub fn pathStringLength(len: usize, ctx: *JSC.JSGlobalObject) bun.JSError!void { switch (len) { 0...bun.MAX_PATH_BYTES => return, else => { @@ -1087,11 +1087,11 @@ pub const Valid = struct { comptime unreachable; } - pub fn pathString(zig_str: JSC.ZigString, ctx: JSC.C.JSContextRef) bun.JSError!void { + pub fn pathString(zig_str: JSC.ZigString, ctx: *JSC.JSGlobalObject) bun.JSError!void { return pathStringLength(zig_str.len, ctx); } - pub fn pathBuffer(buffer: Buffer, ctx: JSC.C.JSContextRef) bun.JSError!void { + pub fn pathBuffer(buffer: Buffer, ctx: *JSC.JSGlobalObject) bun.JSError!void { const slice = buffer.slice(); switch (slice.len) { 0 => { @@ -1238,13 +1238,6 @@ pub const ArgumentsSlice = struct { } }; -pub fn fileDescriptorFromJS(ctx: JSC.C.JSContextRef, value: JSC.JSValue) bun.JSError!?bun.FileDescriptor { - return if (try bun.FDImpl.fromJSValidated(value, ctx)) |fd| - fd.encode() - else - null; -} - // Equivalent to `toUnixTimestamp` // // Node.js docs: @@ -1339,7 +1332,7 @@ fn timeLikeFromNow() TimeLike { }; } -pub fn modeFromJS(ctx: JSC.C.JSContextRef, value: JSC.JSValue) bun.JSError!?Mode { +pub fn modeFromJS(ctx: *JSC.JSGlobalObject, value: JSC.JSValue) bun.JSError!?Mode { const mode_int = if (value.isNumber()) brk: { const m = try validators.validateUint32(ctx, value, "mode", .{}, false); break :brk @as(Mode, @truncate(m)); @@ -1424,12 +1417,12 @@ pub const PathOrFileDescriptor = union(Tag) { } } - pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, allocator: std.mem.Allocator) bun.JSError!?JSC.Node.PathOrFileDescriptor { + pub fn fromJS(ctx: *JSC.JSGlobalObject, arguments: *ArgumentsSlice, allocator: std.mem.Allocator) bun.JSError!?JSC.Node.PathOrFileDescriptor { const first = arguments.next() orelse return null; - if (try bun.FDImpl.fromJSValidated(first, ctx)) |fd| { + if (try bun.FD.fromJSValidated(first, ctx)) |fd| { arguments.eat(); - return JSC.Node.PathOrFileDescriptor{ .fd = fd.encode() }; + return .{ .fd = fd }; } return JSC.Node.PathOrFileDescriptor{ @@ -1529,7 +1522,7 @@ pub const FileSystemFlags = enum(c_int) { .{ "SA+", O.APPEND | O.CREAT | O.RDWR | O.SYNC }, }); - pub fn fromJS(ctx: JSC.C.JSContextRef, val: JSC.JSValue) bun.JSError!?FileSystemFlags { + pub fn fromJS(ctx: *JSC.JSGlobalObject, val: JSC.JSValue) bun.JSError!?FileSystemFlags { if (val.isNumber()) { if (!val.isInt32()) { return ctx.throwValue(ctx.ERR_OUT_OF_RANGE("The value of \"flags\" is out of range. It must be an integer. Received {d}", .{val.asNumber()}).toJS()); diff --git a/src/bun.js/node/util/parse_args.zig b/src/bun.js/node/util/parse_args.zig index d828ad5be7..722a4baf6b 100644 --- a/src/bun.js/node/util/parse_args.zig +++ b/src/bun.js/node/util/parse_args.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const strings = bun.strings; const String = bun.String; diff --git a/src/bun.js/node/util/parse_args_utils.zig b/src/bun.js/node/util/parse_args_utils.zig index 07987707ad..b7e72b0059 100644 --- a/src/bun.js/node/util/parse_args_utils.zig +++ b/src/bun.js/node/util/parse_args_utils.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const testing = std.testing; const String = bun.String; const JSValue = bun.JSC.JSValue; diff --git a/src/bun.js/node/util/validators.zig b/src/bun.js/node/util/validators.zig index 114899f259..4da3a76b76 100644 --- a/src/bun.js/node/util/validators.zig +++ b/src/bun.js/node/util/validators.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const JSC = bun.JSC; const JSValue = JSC.JSValue; diff --git a/src/bun.js/node/win_watcher.zig b/src/bun.js/node/win_watcher.zig index 2445c07f0c..b891ac23af 100644 --- a/src/bun.js/node/win_watcher.zig +++ b/src/bun.js/node/win_watcher.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const windows = bun.windows; const uv = windows.libuv; const Path = @import("../../resolver/resolve_path.zig"); diff --git a/src/bun.js/rare_data.zig b/src/bun.js/rare_data.zig index de0f7ada7c..55139250f7 100644 --- a/src/bun.js/rare_data.zig +++ b/src/bun.js/rare_data.zig @@ -8,8 +8,7 @@ const Syscall = bun.sys; const JSC = bun.JSC; const std = @import("std"); const BoringSSL = bun.BoringSSL.c; -const bun = @import("root").bun; -const FDImpl = bun.FDImpl; +const bun = @import("bun"); const Environment = bun.Environment; const WebSocketClientMask = @import("../http/websocket_http_client.zig").Mask; const UUID = @import("./uuid.zig"); @@ -134,7 +133,7 @@ pub fn closeAllListenSocketsForWatchMode(this: *RareData) void { for (this.listening_sockets_for_watch_mode.items) |socket| { // Prevent TIME_WAIT state Syscall.disableLinger(socket); - _ = Syscall.close(socket); + socket.close(); } this.listening_sockets_for_watch_mode = .{}; } @@ -323,7 +322,7 @@ pub fn stderr(rare: *RareData) *Blob.Store { bun.Analytics.Features.@"Bun.stderr" += 1; return rare.stderr_store orelse brk: { var mode: bun.Mode = 0; - const fd = if (Environment.isWindows) FDImpl.fromUV(2).encode() else bun.STDERR_FD; + const fd = bun.FD.fromUV(2); switch (Syscall.fstat(fd)) { .result => |stat| { @@ -355,7 +354,7 @@ pub fn stdout(rare: *RareData) *Blob.Store { bun.Analytics.Features.@"Bun.stdout" += 1; return rare.stdout_store orelse brk: { var mode: bun.Mode = 0; - const fd = if (Environment.isWindows) FDImpl.fromUV(1).encode() else bun.STDOUT_FD; + const fd = bun.FD.fromUV(1); switch (Syscall.fstat(fd)) { .result => |stat| { @@ -385,7 +384,7 @@ pub fn stdin(rare: *RareData) *Blob.Store { bun.Analytics.Features.@"Bun.stdin" += 1; return rare.stdin_store orelse brk: { var mode: bun.Mode = 0; - const fd = if (Environment.isWindows) FDImpl.fromUV(0).encode() else bun.STDIN_FD; + const fd = bun.FD.fromUV(0); switch (Syscall.fstat(fd)) { .result => |stat| { @@ -398,10 +397,8 @@ pub fn stdin(rare: *RareData) *Blob.Store { .ref_count = std.atomic.Value(u32).init(2), .data = .{ .file = Blob.FileStore{ - .pathlike = .{ - .fd = fd, - }, - .is_atty = if (bun.STDIN_FD.isValid()) std.posix.isatty(bun.STDIN_FD.cast()) else false, + .pathlike = .{ .fd = fd }, + .is_atty = if (fd.unwrapValid()) |valid| std.posix.isatty(valid.native()) else false, .mode = mode, }, }, diff --git a/src/bun.js/test/diff_format.zig b/src/bun.js/test/diff_format.zig index c6e832088a..63093fe1fe 100644 --- a/src/bun.js/test/diff_format.zig +++ b/src/bun.js/test/diff_format.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const MutableString = bun.MutableString; const Output = bun.Output; const default_allocator = bun.default_allocator; diff --git a/src/bun.js/test/expect.zig b/src/bun.js/test/expect.zig index 86cd055e9b..db0ffd1945 100644 --- a/src/bun.js/test/expect.zig +++ b/src/bun.js/test/expect.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const default_allocator = bun.default_allocator; const string = bun.string; const MutableString = bun.MutableString; @@ -57,7 +57,11 @@ pub fn getMatcherFlags(comptime T: type, value: JSValue) Expect.Flags { /// https://jestjs.io/docs/expect // To support async tests, we need to track the test ID pub const Expect = struct { - pub usingnamespace JSC.Codegen.JSExpect; + pub const js = JSC.Codegen.JSExpect; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; + flags: Flags = .{}, parent: ParentScope = .{ .global = {} }, custom_label: bun.String = bun.String.empty, @@ -188,7 +192,7 @@ pub const Expect = struct { } pub fn getValue(this: *Expect, globalThis: *JSGlobalObject, thisValue: JSValue, matcher_name: string, comptime matcher_params_fmt: string) bun.JSError!JSValue { - const value = Expect.capturedValueGetCached(thisValue) orelse { + const value = js.capturedValueGetCached(thisValue) orelse { return globalThis.throw("Internal error: the expect(value) was garbage collected but it should not have been!", .{}); }; value.ensureStillAlive(); @@ -389,7 +393,7 @@ pub const Expect = struct { }; const expect_js_value = expect.toJS(globalThis); expect_js_value.ensureStillAlive(); - Expect.capturedValueSetCached(expect_js_value, globalThis, value); + js.capturedValueSetCached(expect_js_value, globalThis, value); expect_js_value.ensureStillAlive(); expect.postMatch(globalThis); @@ -2197,7 +2201,7 @@ pub const Expect = struct { } if (value.isObject()) { if (ExpectAny.fromJSDirect(value)) |_| { - if (ExpectAny.constructorValueGetCached(value)) |innerConstructorValue| { + if (ExpectAny.js.constructorValueGetCached(value)) |innerConstructorValue| { break :brk innerConstructorValue; } } @@ -3857,7 +3861,7 @@ pub const Expect = struct { const countAsNum = count.toU32(); - const expect_string = Expect.capturedValueGetCached(thisValue) orelse { + const expect_string = js.capturedValueGetCached(thisValue) orelse { return globalThis.throw("Internal consistency error: the expect(value) was garbage collected but it should not have been!", .{}); }; @@ -3950,7 +3954,7 @@ pub const Expect = struct { return globalThis.throw("toSatisfy() argument must be a function", .{}); } - const value = Expect.capturedValueGetCached(thisValue) orelse { + const value = js.capturedValueGetCached(thisValue) orelse { return globalThis.throw("Internal consistency error: the expect(value) was garbage collected but it should not have been!", .{}); }; value.ensureStillAlive(); @@ -4682,7 +4686,7 @@ pub const Expect = struct { } var expect_proto = Expect__getPrototype(globalThis); - var expect_constructor = Expect.getConstructor(globalThis); + var expect_constructor = Expect.js.getConstructor(globalThis); var expect_static_proto = ExpectStatic__getPrototype(globalThis); // SAFETY: already checked that args[0] is an object @@ -4904,10 +4908,10 @@ pub const Expect = struct { }; // retrieve the captured expected value - var value = Expect.capturedValueGetCached(thisValue) orelse { + var value = js.capturedValueGetCached(thisValue) orelse { return globalThis.throw("Internal consistency error: failed to retrieve the captured value", .{}); }; - value = try Expect.processPromise(expect.custom_label, expect.flags, globalThis, value, matcher_name, matcher_params, false); + value = try processPromise(expect.custom_label, expect.flags, globalThis, value, matcher_name, matcher_params, false); value.ensureStillAlive(); incrementExpectCallCounter(); @@ -5009,7 +5013,10 @@ pub const Expect = struct { /// Static instance of expect, holding a set of flags. /// Returned for example when executing `expect.not` pub const ExpectStatic = struct { - pub usingnamespace JSC.Codegen.JSExpectStatic; + pub const js = JSC.Codegen.JSExpectStatic; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; flags: Expect.Flags = .{}, @@ -5102,7 +5109,10 @@ pub const ExpectStatic = struct { }; pub const ExpectAnything = struct { - pub usingnamespace JSC.Codegen.JSExpectAnything; + pub const js = JSC.Codegen.JSExpectAnything; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; flags: Expect.Flags = .{}, @@ -5127,7 +5137,10 @@ pub const ExpectAnything = struct { }; pub const ExpectStringMatching = struct { - pub usingnamespace JSC.Codegen.JSExpectStringMatching; + pub const js = JSC.Codegen.JSExpectStringMatching; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; flags: Expect.Flags = .{}, @@ -5138,7 +5151,7 @@ pub const ExpectStringMatching = struct { } pub fn call(globalThis: *JSGlobalObject, callFrame: *CallFrame) bun.JSError!JSValue { - const args = callFrame.arguments_old(1).slice(); + const args = callFrame.arguments(); if (args.len == 0 or (!args[0].isString() and !args[0].isRegExp())) { const fmt = "expect.stringContaining(string)\n\nExpected a string or regular expression\n"; @@ -5151,7 +5164,7 @@ pub const ExpectStringMatching = struct { string_matching.* = .{}; const string_matching_js_value = string_matching.toJS(globalThis); - ExpectStringMatching.testValueSetCached(string_matching_js_value, globalThis, test_value); + js.testValueSetCached(string_matching_js_value, globalThis, test_value); var vm = globalThis.bunVM(); vm.autoGarbageCollect(); @@ -5160,7 +5173,10 @@ pub const ExpectStringMatching = struct { }; pub const ExpectCloseTo = struct { - pub usingnamespace JSC.Codegen.JSExpectCloseTo; + pub const js = JSC.Codegen.JSExpectCloseTo; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; flags: Expect.Flags = .{}, @@ -5192,8 +5208,8 @@ pub const ExpectCloseTo = struct { const instance_jsvalue = instance.toJS(globalThis); number_value.ensureStillAlive(); precision_value.ensureStillAlive(); - ExpectCloseTo.numberValueSetCached(instance_jsvalue, globalThis, number_value); - ExpectCloseTo.digitsValueSetCached(instance_jsvalue, globalThis, precision_value); + ExpectCloseTo.js.numberValueSetCached(instance_jsvalue, globalThis, number_value); + ExpectCloseTo.js.digitsValueSetCached(instance_jsvalue, globalThis, precision_value); var vm = globalThis.bunVM(); vm.autoGarbageCollect(); @@ -5202,7 +5218,10 @@ pub const ExpectCloseTo = struct { }; pub const ExpectObjectContaining = struct { - pub usingnamespace JSC.Codegen.JSExpectObjectContaining; + pub const js = JSC.Codegen.JSExpectObjectContaining; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; flags: Expect.Flags = .{}, @@ -5226,7 +5245,7 @@ pub const ExpectObjectContaining = struct { instance.* = .{}; const instance_jsvalue = instance.toJS(globalThis); - ExpectObjectContaining.objectValueSetCached(instance_jsvalue, globalThis, object_value); + ExpectObjectContaining.js.objectValueSetCached(instance_jsvalue, globalThis, object_value); var vm = globalThis.bunVM(); vm.autoGarbageCollect(); @@ -5235,7 +5254,10 @@ pub const ExpectObjectContaining = struct { }; pub const ExpectStringContaining = struct { - pub usingnamespace JSC.Codegen.JSExpectStringContaining; + pub const js = JSC.Codegen.JSExpectStringContaining; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; flags: Expect.Flags = .{}, @@ -5259,7 +5281,7 @@ pub const ExpectStringContaining = struct { string_containing.* = .{}; const string_containing_js_value = string_containing.toJS(globalThis); - ExpectStringContaining.stringValueSetCached(string_containing_js_value, globalThis, string_value); + ExpectStringContaining.js.stringValueSetCached(string_containing_js_value, globalThis, string_value); var vm = globalThis.bunVM(); vm.autoGarbageCollect(); @@ -5268,7 +5290,10 @@ pub const ExpectStringContaining = struct { }; pub const ExpectAny = struct { - pub usingnamespace JSC.Codegen.JSExpectAny; + pub const js = JSC.Codegen.JSExpectAny; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; flags: Expect.Flags = .{}, @@ -5307,7 +5332,7 @@ pub const ExpectAny = struct { const any_js_value = any.toJS(globalThis); any_js_value.ensureStillAlive(); - ExpectAny.constructorValueSetCached(any_js_value, globalThis, constructor); + ExpectAny.js.constructorValueSetCached(any_js_value, globalThis, constructor); any_js_value.ensureStillAlive(); var vm = globalThis.bunVM(); @@ -5318,7 +5343,10 @@ pub const ExpectAny = struct { }; pub const ExpectArrayContaining = struct { - pub usingnamespace JSC.Codegen.JSExpectArrayContaining; + pub const js = JSC.Codegen.JSExpectArrayContaining; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; flags: Expect.Flags = .{}, @@ -5342,7 +5370,7 @@ pub const ExpectArrayContaining = struct { array_containing.* = .{}; const array_containing_js_value = array_containing.toJS(globalThis); - ExpectArrayContaining.arrayValueSetCached(array_containing_js_value, globalThis, array_value); + ExpectArrayContaining.js.arrayValueSetCached(array_containing_js_value, globalThis, array_value); var vm = globalThis.bunVM(); vm.autoGarbageCollect(); @@ -5355,7 +5383,10 @@ pub const ExpectArrayContaining = struct { /// Reference: `AsymmetricMatcher` in https://github.com/jestjs/jest/blob/main/packages/expect/src/types.ts /// (but only created for *custom* matchers, as built-ins have their own classes) pub const ExpectCustomAsymmetricMatcher = struct { - pub usingnamespace JSC.Codegen.JSExpectCustomAsymmetricMatcher; + pub const js = JSC.Codegen.JSExpectCustomAsymmetricMatcher; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; flags: Expect.Flags = .{}, @@ -5390,7 +5421,7 @@ pub const ExpectCustomAsymmetricMatcher = struct { instance.flags = flags; // store the user-provided matcher function into the instance - ExpectCustomAsymmetricMatcher.matcherFnSetCached(instance_jsvalue, globalThis, matcher_fn); + js.matcherFnSetCached(instance_jsvalue, globalThis, matcher_fn); // capture the args as a JS array saved in the instance, so the matcher can be executed later on with them const args = callFrame.arguments(); @@ -5398,7 +5429,7 @@ pub const ExpectCustomAsymmetricMatcher = struct { for (args, 0..) |arg, i| { array.putIndex(globalThis, @truncate(i), arg); } - ExpectCustomAsymmetricMatcher.capturedArgsSetCached(instance_jsvalue, globalThis, array); + js.capturedArgsSetCached(instance_jsvalue, globalThis, array); array.ensureStillAlive(); // return the same instance, now fully initialized including the captured args (previously it was incomplete) @@ -5408,7 +5439,7 @@ pub const ExpectCustomAsymmetricMatcher = struct { /// Function called by c++ function "matchAsymmetricMatcher" to execute the custom matcher against the provided leftValue pub fn execute(this: *ExpectCustomAsymmetricMatcher, thisValue: JSValue, globalThis: *JSGlobalObject, received: JSValue) callconv(.C) bool { // retrieve the user-provided matcher implementation function (the function passed to expect.extend({ ... })) - const matcher_fn: JSValue = ExpectCustomAsymmetricMatcher.matcherFnGetCached(thisValue) orelse { + const matcher_fn: JSValue = js.matcherFnGetCached(thisValue) orelse { globalThis.throw("Internal consistency error: the ExpectCustomAsymmetricMatcher(matcherFn) was garbage collected but it should not have been!", .{}) catch {}; return false; }; @@ -5423,7 +5454,7 @@ pub const ExpectCustomAsymmetricMatcher = struct { // retrieve the asymmetric matcher args // if null, it means the function has not yet been called to capture the args, which is a misuse of the matcher - const captured_args: JSValue = ExpectCustomAsymmetricMatcher.capturedArgsGetCached(thisValue) orelse { + const captured_args: JSValue = js.capturedArgsGetCached(thisValue) orelse { globalThis.throw("expect.{s} misused, it needs to be instantiated by calling it with 0 or more arguments", .{matcher_name}) catch {}; return false; }; @@ -5453,10 +5484,10 @@ pub const ExpectCustomAsymmetricMatcher = struct { /// Calls a custom implementation (if provided) to stringify this asymmetric matcher, and returns true if it was provided and it succeed pub fn customPrint(_: *ExpectCustomAsymmetricMatcher, thisValue: JSValue, globalThis: *JSGlobalObject, writer: anytype, comptime dontThrow: bool) !bool { - const matcher_fn: JSValue = ExpectCustomAsymmetricMatcher.matcherFnGetCached(thisValue) orelse return false; + const matcher_fn: JSValue = js.matcherFnGetCached(thisValue) orelse return false; if (matcher_fn.get_unsafe(globalThis, "toAsymmetricMatcher")) |fn_value| { if (fn_value.jsType().isFunction()) { - const captured_args: JSValue = ExpectCustomAsymmetricMatcher.capturedArgsGetCached(thisValue) orelse return false; + const captured_args: JSValue = js.capturedArgsGetCached(thisValue) orelse return false; var stack_fallback = std.heap.stackFallback(256, globalThis.allocator()); const args_len = captured_args.getLength(globalThis); var args = try std.ArrayList(JSValue).initCapacity(stack_fallback.get(), args_len); @@ -5499,7 +5530,10 @@ pub const ExpectCustomAsymmetricMatcher = struct { /// Reference: `MatcherContext` in https://github.com/jestjs/jest/blob/main/packages/expect/src/types.ts pub const ExpectMatcherContext = struct { - pub usingnamespace JSC.Codegen.JSExpectMatcherContext; + pub const js = JSC.Codegen.JSExpectMatcherContext; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; flags: Expect.Flags = .{}, @@ -5543,7 +5577,10 @@ pub const ExpectMatcherContext = struct { /// Reference: `MatcherUtils` in https://github.com/jestjs/jest/blob/main/packages/expect/src/types.ts pub const ExpectMatcherUtils = struct { - pub usingnamespace JSC.Codegen.JSExpectMatcherUtils; + pub const js = JSC.Codegen.JSExpectMatcherUtils; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; fn createSingleton(globalThis: *JSGlobalObject) callconv(.C) JSValue { var instance = globalThis.bunVM().allocator.create(ExpectMatcherUtils) catch { diff --git a/src/bun.js/test/jest.zig b/src/bun.js/test/jest.zig index ac4ac1fad2..2c228efbb1 100644 --- a/src/bun.js/test/jest.zig +++ b/src/bun.js/test/jest.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const js_parser = bun.js_parser; const js_ast = bun.JSAst; const Api = @import("../../api/schema.zig").Api; @@ -16,7 +16,6 @@ const Expect = expect.Expect; const DiffFormatter = @import("./diff_format.zig").DiffFormatter; const JSC = bun.JSC; -const js = JSC.C; const logger = bun.logger; const Method = @import("../../http/method.zig").Method; @@ -259,6 +258,7 @@ pub const TestRunner = struct { status: Status = Status.pending, pub const ID = u32; + pub const null_id: ID = std.math.maxInt(Test.ID); pub const List = std.MultiArrayList(Test); pub const Status = enum(u4) { @@ -402,7 +402,7 @@ pub const Jest = struct { module.put( globalObject, ZigString.static("expect"), - Expect.getConstructor(globalObject), + Expect.js.getConstructor(globalObject), ); createMockObjects(globalObject, module); @@ -457,7 +457,7 @@ pub const Jest = struct { module.put( globalObject, ZigString.static("expect"), - Expect.getConstructor(globalObject), + Expect.js.getConstructor(globalObject), ); const vi = JSValue.createEmptyObject(globalObject, 3); @@ -633,21 +633,35 @@ pub const TestScope = struct { if (JSC.getFunctionData(function)) |data| { var task = bun.cast(*TestRunnerTask, data); + const expect_count = expect.active_test_expectation_counter.actual; + const current_test = task.testScope(); + const no_err_result: Result = if (current_test.tag == .fail) + .{ .fail_because_failing_test_passed = expect_count } + else + .{ .pass = expect_count }; JSC.setFunctionData(function, null); if (args.len > 0) { const err = args.ptr[0]; if (err.isEmptyOrUndefinedOrNull()) { debug("done()", .{}); - task.handleResult(.{ .pass = expect.active_test_expectation_counter.actual }, .callback); + task.handleResult(no_err_result, .callback); } else { debug("done(err)", .{}); - _ = globalThis.bunVM().uncaughtException(globalThis, err, true); - task.handleResult(.{ .fail = expect.active_test_expectation_counter.actual }, .callback); + const result: Result = if (current_test.tag == .fail) failing_passed: { + break :failing_passed if (globalThis.clearExceptionExceptTermination()) + Result{ .pass = expect_count } + else + Result{ .fail = expect_count }; // what is the correct thing to do when terminating? + } else passing_failed: { + _ = globalThis.bunVM().uncaughtException(globalThis, err, true); + break :passing_failed Result{ .fail = expect_count }; + }; + task.handleResult(result, .callback); } } else { debug("done()", .{}); - task.handleResult(.{ .pass = expect.active_test_expectation_counter.actual }, .callback); + task.handleResult(no_err_result, .callback); } } @@ -889,7 +903,7 @@ pub const DescribeScope = struct { } pub fn onDone( - ctx: js.JSContextRef, + ctx: *JSC.JSGlobalObject, callframe: *CallFrame, ) bun.JSError!JSValue { const function = callframe.callee(); @@ -1142,7 +1156,7 @@ pub const DescribeScope = struct { if (end == 0) { var runner = allocator.create(TestRunnerTask) catch unreachable; runner.* = .{ - .test_id = std.math.maxInt(TestRunner.Test.ID), + .test_id = TestRunner.Test.null_id, .describe = this, .globalThis = globalObject, .source_file_path = source.path.text, @@ -1174,8 +1188,8 @@ pub const DescribeScope = struct { pub fn onTestComplete(this: *DescribeScope, globalThis: *JSGlobalObject, test_id: TestRunner.Test.ID, skipped: bool) void { // invalidate it - this.current_test_id = std.math.maxInt(TestRunner.Test.ID); - if (test_id != std.math.maxInt(TestRunner.Test.ID)) this.pending_tests.unset(test_id); + this.current_test_id = TestRunner.Test.null_id; + if (test_id != TestRunner.Test.null_id) this.pending_tests.unset(test_id); globalThis.bunVM().onUnhandledRejectionCtx = null; if (!skipped) { @@ -1277,6 +1291,10 @@ pub const TestRunnerTask = struct { fulfilled, }; + pub inline fn testScope(this: *TestRunnerTask) *TestScope { + return &this.describe.tests.items[this.test_id]; + } + pub fn onUnhandledRejection(jsc_vm: *VirtualMachine, globalObject: *JSGlobalObject, rejection: JSValue) void { var deduped = false; const is_unhandled = jsc_vm.onUnhandledRejectionCtx == null; @@ -1309,7 +1327,11 @@ pub const TestRunnerTask = struct { if (jsc_vm.onUnhandledRejectionCtx) |ctx| { var this = bun.cast(*TestRunnerTask, ctx); jsc_vm.onUnhandledRejectionCtx = null; - this.handleResult(.{ .fail = expect.active_test_expectation_counter.actual }, .unhandledRejection); + const result: Result = if (this.testScope().tag == .fail) + .{ .pass = expect.active_test_expectation_counter.actual } + else + .{ .fail = expect.active_test_expectation_counter.actual }; + this.handleResult(result, .unhandledRejection); } else if (Jest.runner) |runner| { if (!deduped) runner.unhandled_errors_between_tests += 1; @@ -1343,7 +1365,7 @@ pub const TestRunnerTask = struct { jsc_vm.last_reported_error_for_dedupe = .zero; const test_id = this.test_id; - if (test_id == std.math.maxInt(TestRunner.Test.ID)) { + if (test_id == TestRunner.Test.null_id) { describe.onTestComplete(globalThis, test_id, true); Jest.runner.?.runNextTest(); this.deinit(); diff --git a/src/bun.js/test/pretty_format.zig b/src/bun.js/test/pretty_format.zig index ae97bc5081..3aca743f1c 100644 --- a/src/bun.js/test/pretty_format.zig +++ b/src/bun.js/test/pretty_format.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Output = bun.Output; const JSC = bun.JSC; const JSGlobalObject = JSC.JSGlobalObject; @@ -2063,7 +2063,7 @@ pub const JestPrettyFormat = struct { writer.writeAll("Anything"); } } else if (value.as(expect.ExpectAny)) |matcher| { - const constructor_value = expect.ExpectAny.constructorValueGetCached(value) orelse return true; + const constructor_value = expect.ExpectAny.js.constructorValueGetCached(value) orelse return true; printAsymmetricMatcherPromisePrefix(matcher.flags, this, writer); if (matcher.flags.not) { @@ -2081,8 +2081,8 @@ pub const JestPrettyFormat = struct { this.addForNewLine(1); writer.writeAll(">"); } else if (value.as(expect.ExpectCloseTo)) |matcher| { - const number_value = expect.ExpectCloseTo.numberValueGetCached(value) orelse return true; - const digits_value = expect.ExpectCloseTo.digitsValueGetCached(value) orelse return true; + const number_value = expect.ExpectCloseTo.js.numberValueGetCached(value) orelse return true; + const digits_value = expect.ExpectCloseTo.js.digitsValueGetCached(value) orelse return true; const number = number_value.toInt32(); const digits = digits_value.toInt32(); @@ -2097,7 +2097,7 @@ pub const JestPrettyFormat = struct { } writer.print("{d} ({d} digit{s})", .{ number, digits, if (digits == 1) "" else "s" }); } else if (value.as(expect.ExpectObjectContaining)) |matcher| { - const object_value = expect.ExpectObjectContaining.objectValueGetCached(value) orelse return true; + const object_value = expect.ExpectObjectContaining.js.objectValueGetCached(value) orelse return true; printAsymmetricMatcherPromisePrefix(matcher.flags, this, writer); if (matcher.flags.not) { @@ -2109,7 +2109,7 @@ pub const JestPrettyFormat = struct { } this.printAs(.Object, @TypeOf(writer_), writer_, object_value, .Object, enable_ansi_colors) catch {}; // TODO: } else if (value.as(expect.ExpectStringContaining)) |matcher| { - const substring_value = expect.ExpectStringContaining.stringValueGetCached(value) orelse return true; + const substring_value = expect.ExpectStringContaining.js.stringValueGetCached(value) orelse return true; printAsymmetricMatcherPromisePrefix(matcher.flags, this, writer); if (matcher.flags.not) { @@ -2121,7 +2121,7 @@ pub const JestPrettyFormat = struct { } this.printAs(.String, @TypeOf(writer_), writer_, substring_value, .String, enable_ansi_colors) catch {}; // TODO: } else if (value.as(expect.ExpectStringMatching)) |matcher| { - const test_value = expect.ExpectStringMatching.testValueGetCached(value) orelse return true; + const test_value = expect.ExpectStringMatching.js.testValueGetCached(value) orelse return true; printAsymmetricMatcherPromisePrefix(matcher.flags, this, writer); if (matcher.flags.not) { @@ -2140,8 +2140,8 @@ pub const JestPrettyFormat = struct { const printed = instance.customPrint(value, this.globalThis, writer_, true) catch unreachable; if (!printed) { // default print (non-overridden by user) const flags = instance.flags; - const args_value = expect.ExpectCustomAsymmetricMatcher.capturedArgsGetCached(value) orelse return true; - const matcher_fn = expect.ExpectCustomAsymmetricMatcher.matcherFnGetCached(value) orelse return true; + const args_value = expect.ExpectCustomAsymmetricMatcher.js.capturedArgsGetCached(value) orelse return true; + const matcher_fn = expect.ExpectCustomAsymmetricMatcher.js.matcherFnGetCached(value) orelse return true; const matcher_name = matcher_fn.getName(this.globalThis); printAsymmetricMatcherPromisePrefix(flags, this, writer); diff --git a/src/bun.js/test/snapshot.zig b/src/bun.js/test/snapshot.zig index becdc04039..c9ae1f1137 100644 --- a/src/bun.js/test/snapshot.zig +++ b/src/bun.js/test/snapshot.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const default_allocator = bun.default_allocator; const string = bun.string; const MutableString = bun.MutableString; @@ -253,7 +253,7 @@ pub const Snapshots = struct { }; var file: File = .{ .id = file_id, - .file = fd.asFile(), + .file = fd.stdFile(), }; errdefer file.file.close(); @@ -521,7 +521,7 @@ pub const Snapshots = struct { var file: File = .{ .id = file_id, - .file = fd.asFile(), + .file = fd.stdFile(), }; errdefer file.file.close(); diff --git a/src/bun.js/unbounded_queue.zig b/src/bun.js/unbounded_queue.zig index a9050d52dc..f3bcc4e18e 100644 --- a/src/bun.js/unbounded_queue.zig +++ b/src/bun.js/unbounded_queue.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const posix = std.posix; const mem = std.mem; diff --git a/src/bun.js/uuid.zig b/src/bun.js/uuid.zig index 8257cc7225..634ef76567 100644 --- a/src/bun.js/uuid.zig +++ b/src/bun.js/uuid.zig @@ -3,7 +3,7 @@ const std = @import("std"); const crypto = std.crypto; const fmt = std.fmt; const testing = std.testing; -const bun = @import("root").bun; +const bun = @import("bun"); pub const Error = error{InvalidUUID}; const UUID = @This(); diff --git a/src/bun.js/web_worker.zig b/src/bun.js/web_worker.zig index dc27084e0e..2b4ac5c95f 100644 --- a/src/bun.js/web_worker.zig +++ b/src/bun.js/web_worker.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const Output = bun.Output; const log = Output.scoped(.Worker, true); diff --git a/src/bun.js/webcore.zig b/src/bun.js/webcore.zig index 4c81c6350a..e0e921749c 100644 --- a/src/bun.js/webcore.zig +++ b/src/bun.js/webcore.zig @@ -10,7 +10,7 @@ pub const CookieMap = @import("./webcore/CookieMap.zig").CookieMap; pub const ObjectURLRegistry = @import("./webcore/ObjectURLRegistry.zig"); const JSC = bun.JSC; const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; pub const AbortSignal = @import("./bindings/bindings.zig").AbortSignal; pub const JSValue = @import("./bindings/bindings.zig").JSValue; @@ -268,11 +268,11 @@ pub const Prompt = struct { // unset `ENABLE_VIRTUAL_TERMINAL_INPUT` on windows. This prevents backspace from // deleting the entire line const original_mode: if (Environment.isWindows) ?bun.windows.DWORD else void = if (comptime Environment.isWindows) - bun.win32.updateStdioModeFlags(0, .{ .unset = bun.windows.ENABLE_VIRTUAL_TERMINAL_INPUT }) catch null; + bun.win32.updateStdioModeFlags(.std_in, .{ .unset = bun.windows.ENABLE_VIRTUAL_TERMINAL_INPUT }) catch null; defer if (comptime Environment.isWindows) { if (original_mode) |mode| { - _ = bun.windows.SetConsoleMode(bun.win32.STDIN_FD.cast(), mode); + _ = bun.windows.SetConsoleMode(bun.FD.stdin().native(), mode); } }; @@ -361,7 +361,13 @@ pub const Prompt = struct { }; pub const Crypto = struct { + pub const js = JSC.Codegen.JSCrypto; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; + garbage: i32 = 0, + const BoringSSL = bun.BoringSSL.c; fn throwInvalidParameter(globalThis: *JSC.JSGlobalObject) bun.JSError { @@ -542,8 +548,6 @@ pub const Crypto = struct { return ptr.toJS(globalThis); } - pub usingnamespace JSC.Codegen.JSCrypto; - comptime { _ = CryptoObject__create; } diff --git a/src/bun.js/webcore/AutoFlusher.zig b/src/bun.js/webcore/AutoFlusher.zig index 9952587e5a..49ef6b1f9f 100644 --- a/src/bun.js/webcore/AutoFlusher.zig +++ b/src/bun.js/webcore/AutoFlusher.zig @@ -22,5 +22,5 @@ pub fn registerDeferredMicrotaskWithTypeUnchecked(comptime Type: type, this: *Ty bun.assert(!vm.eventLoop().deferred_tasks.postTask(this, @ptrCast(&Type.onAutoFlush))); } -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; diff --git a/src/bun.js/webcore/CookieMap.zig b/src/bun.js/webcore/CookieMap.zig index 24b7b62fe4..a3018ecabc 100644 --- a/src/bun.js/webcore/CookieMap.zig +++ b/src/bun.js/webcore/CookieMap.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); pub const CookieMap = opaque { extern fn CookieMap__write(cookie_map: *CookieMap, global_this: *bun.JSC.JSGlobalObject, ssl_enabled: bool, uws_http_response: *anyopaque) void; diff --git a/src/bun.js/webcore/EncodingLabel.zig b/src/bun.js/webcore/EncodingLabel.zig index 7a8c43cd43..9a5cbbf2d6 100644 --- a/src/bun.js/webcore/EncodingLabel.zig +++ b/src/bun.js/webcore/EncodingLabel.zig @@ -154,7 +154,7 @@ pub const EncodingLabel = enum { } }; const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const encoding = @import("encoding.zig"); const string = []const u8; const strings = bun.strings; diff --git a/src/bun.js/webcore/ObjectURLRegistry.zig b/src/bun.js/webcore/ObjectURLRegistry.zig index c0226ca95e..446915c70a 100644 --- a/src/bun.js/webcore/ObjectURLRegistry.zig +++ b/src/bun.js/webcore/ObjectURLRegistry.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const UUID = bun.UUID; const assert = bun.assert; diff --git a/src/bun.js/webcore/S3Client.zig b/src/bun.js/webcore/S3Client.zig index dc9d349c8f..a5f1eee166 100644 --- a/src/bun.js/webcore/S3Client.zig +++ b/src/bun.js/webcore/S3Client.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const JSValue = JSC.JSValue; const Blob = JSC.WebCore.Blob; @@ -88,7 +88,10 @@ pub fn writeFormatCredentials(credentials: *S3Credentials, options: bun.S3.Multi pub const S3Client = struct { const log = bun.Output.scoped(.S3Client, false); - pub usingnamespace JSC.Codegen.JSS3Client; + pub const js = JSC.Codegen.JSS3Client; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; pub const new = bun.TrivialNew(@This()); credentials: *S3Credentials, diff --git a/src/bun.js/webcore/S3File.zig b/src/bun.js/webcore/S3File.zig index 6195753ab6..6a880eed7a 100644 --- a/src/bun.js/webcore/S3File.zig +++ b/src/bun.js/webcore/S3File.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const JSValue = JSC.JSValue; const Blob = JSC.WebCore.Blob; diff --git a/src/bun.js/webcore/S3Stat.zig b/src/bun.js/webcore/S3Stat.zig index 6c33ac785c..0436b5de00 100644 --- a/src/bun.js/webcore/S3Stat.zig +++ b/src/bun.js/webcore/S3Stat.zig @@ -1,9 +1,13 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; pub const S3Stat = struct { const log = bun.Output.scoped(.S3Stat, false); - pub usingnamespace JSC.Codegen.JSS3Stat; + pub const js = JSC.Codegen.JSS3Stat; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; + pub const new = bun.TrivialNew(@This()); size: u64, diff --git a/src/bun.js/webcore/TextDecoder.zig b/src/bun.js/webcore/TextDecoder.zig index 6c9222e4d6..abb5d627b8 100644 --- a/src/bun.js/webcore/TextDecoder.zig +++ b/src/bun.js/webcore/TextDecoder.zig @@ -16,7 +16,10 @@ ignore_bom: bool = false, fatal: bool = false, encoding: EncodingLabel = EncodingLabel.@"UTF-8", -pub usingnamespace JSC.Codegen.JSTextDecoder; +pub const js = JSC.Codegen.JSTextDecoder; +pub const toJS = js.toJS; +pub const fromJS = js.fromJS; +pub const fromJSDirect = js.fromJSDirect; pub const new = bun.TrivialNew(TextDecoder); @@ -334,7 +337,7 @@ pub fn constructor(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) b const TextDecoder = @This(); const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const Output = bun.Output; const MutableString = bun.MutableString; diff --git a/src/bun.js/webcore/TextEncoder.zig b/src/bun.js/webcore/TextEncoder.zig index 6f5ca0bbb0..a8f316eb91 100644 --- a/src/bun.js/webcore/TextEncoder.zig +++ b/src/bun.js/webcore/TextEncoder.zig @@ -245,7 +245,7 @@ pub export fn TextEncoder__encodeInto8( } const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const strings = bun.strings; const JSC = bun.JSC; const Environment = bun.Environment; diff --git a/src/bun.js/webcore/TextEncoderStreamEncoder.zig b/src/bun.js/webcore/TextEncoderStreamEncoder.zig index a921ff962e..c60d235fd6 100644 --- a/src/bun.js/webcore/TextEncoderStreamEncoder.zig +++ b/src/bun.js/webcore/TextEncoderStreamEncoder.zig @@ -2,7 +2,11 @@ pending_lead_surrogate: ?u16 = null, const log = Output.scoped(.TextEncoderStreamEncoder, false); -pub usingnamespace JSC.Codegen.JSTextEncoderStreamEncoder; +pub const js = JSC.Codegen.JSTextEncoderStreamEncoder; +pub const toJS = js.toJS; +pub const fromJS = js.fromJS; +pub const fromJSDirect = js.fromJSDirect; + pub const new = bun.TrivialNew(TextEncoderStreamEncoder); pub fn finalize(this: *TextEncoderStreamEncoder) void { @@ -195,7 +199,7 @@ fn flushBody(this: *TextEncoderStreamEncoder, globalObject: *JSGlobalObject) JSV const TextEncoderStreamEncoder = @This(); const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const Output = bun.Output; const MutableString = bun.MutableString; diff --git a/src/bun.js/webcore/blob.zig b/src/bun.js/webcore/blob.zig index 6428483265..dac86c7c90 100644 --- a/src/bun.js/webcore/blob.zig +++ b/src/bun.js/webcore/blob.zig @@ -1,11 +1,10 @@ const std = @import("std"); const Api = @import("../../api/schema.zig").Api; -const bun = @import("root").bun; +const bun = @import("bun"); const MimeType = http.MimeType; const ZigURL = @import("../../url.zig").URL; const http = bun.http; const JSC = bun.JSC; -const js = JSC.C; const io = bun.io; const Method = @import("../../http/method.zig").Method; const FetchHeaders = JSC.FetchHeaders; @@ -58,7 +57,10 @@ pub const Blob = struct { const bloblog = Output.scoped(.Blob, false); pub const new = bun.TrivialNew(@This()); - pub usingnamespace JSC.Codegen.JSBlob; + pub const js = JSC.Codegen.JSBlob; + // NOTE: toJS is overridden + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; const rf = @import("blob/ReadFile.zig"); pub const ReadFile = rf.ReadFile; @@ -476,7 +478,7 @@ pub const Blob = struct { switch (pathlike_tag) { .fd => { - const fd = try bun.FileDescriptor.readFrom(reader, .little); + const fd = try reader.readStruct(bun.FD); var path_or_fd = JSC.Node.PathOrFileDescriptor{ .fd = fd, @@ -719,27 +721,26 @@ pub const Blob = struct { ); }, .fd => |fd| { - const fd_impl = bun.FDImpl.decode(fd); - if (comptime Environment.isWindows) { - if (fd_impl.kind == .uv) { - try writer.print( + if (Environment.isWindows) { + switch (fd.decodeWindows()) { + .uv => |uv_file| try writer.print( comptime Output.prettyFmt(" (fd: {d})", enable_ansi_colors), - .{fd_impl.uv()}, - ); - } else { - if (Environment.allow_assert) { - comptime assert(Environment.isWindows); - @panic("this shouldn't be reachable."); - } - try writer.print( - comptime Output.prettyFmt(" (fd: {any})", enable_ansi_colors), - .{fd_impl.system()}, - ); + .{uv_file}, + ), + .windows => |handle| { + if (Environment.isDebug) { + @panic("this shouldn't be reachable."); + } + try writer.print( + comptime Output.prettyFmt(" (fd: 0x{x})", enable_ansi_colors), + .{@intFromPtr(handle)}, + ); + }, } } else { try writer.print( comptime Output.prettyFmt(" (fd: {d})", enable_ansi_colors), - .{fd_impl.system()}, + .{fd.native()}, ); } }, @@ -867,7 +868,7 @@ pub const Blob = struct { /// - doesn't exist and is created /// - exists and is truncated fn writeFileWithEmptySourceToDestination( - ctx: JSC.C.JSContextRef, + ctx: *JSC.JSGlobalObject, destination_blob: *Blob, options: WriteFileOptions, ) JSC.JSValue { @@ -937,7 +938,7 @@ pub const Blob = struct { break :err; }, .result => |fd| { - _ = bun.sys.close(fd); + fd.close(); return JSC.JSPromise.resolvedPromiseValue(ctx, .jsNumber(0)); }, } @@ -1012,7 +1013,7 @@ pub const Blob = struct { } pub fn writeFileWithSourceDestination( - ctx: JSC.C.JSContextRef, + ctx: *JSC.JSGlobalObject, source_blob: *Blob, destination_blob: *Blob, options: WriteFileOptions, @@ -1614,11 +1615,10 @@ pub const Blob = struct { // we only truncate if it's a path // if it's a file descriptor, we assume they want manual control over that behavior if (truncate) { - _ = bun.sys.ftruncate(fd, @as(i64, @intCast(written))); + _ = fd.truncate(@intCast(written)); } - if (needs_open) { - _ = bun.sys.close(fd); + fd.close(); } } if (!str.isEmpty()) { @@ -1697,11 +1697,7 @@ pub const Blob = struct { const truncate = needs_open or bytes.len == 0; var written: usize = 0; - defer { - if (needs_open) { - _ = bun.sys.close(fd); - } - } + defer if (needs_open) fd.close(); var remain = bytes; const end = remain.ptr + remain.len; @@ -1992,19 +1988,14 @@ pub const Blob = struct { break :brk copy; }, .fd => { - const optional_store: ?*Store = switch (bun.FDTag.get(path_or_fd.fd)) { - .stdin => vm.rareData().stdin(), - .stderr => vm.rareData().stderr(), - .stdout => vm.rareData().stdout(), - else => null, - }; - - if (optional_store) |store| { + if (path_or_fd.fd.stdioTag()) |tag| { + const store = switch (tag) { + .std_in => vm.rareData().stdin(), + .std_err => vm.rareData().stderr(), + .std_out => vm.rareData().stdout(), + }; store.ref(); - return Blob.initWithStore( - store, - globalThis, - ); + return Blob.initWithStore(store, globalThis); } break :brk path_or_fd.*; }, @@ -2228,7 +2219,7 @@ pub const Blob = struct { switch (file.pathlike) { .fd => |fd| { - try fd.writeTo(writer, .little); + try writer.writeStruct(fd); }, .path => |path| { const path_slice = path.slice(); @@ -2426,12 +2417,12 @@ pub const Blob = struct { if (is_allowed_to_close_fd and this.opened_fd != invalid_fd and - !this.opened_fd.isStdio()) + this.opened_fd.stdioTag() == null) { if (comptime Environment.isWindows) { - bun.Async.Closer.close(bun.uvfdcast(this.opened_fd), this.loop); + bun.Async.Closer.close(this.opened_fd, this.loop); } else { - _ = bun.sys.close(this.opened_fd); + _ = this.opened_fd.closeAllowingBadFileDescriptor(null); } this.opened_fd = invalid_fd; } @@ -2492,7 +2483,7 @@ pub const Blob = struct { const rc = libuv.uv_fs_read( loop, &this.io_request, - bun.uvfdcast(read_write_loop.source_fd), + read_write_loop.source_fd.uv(), @ptrCast(&read_write_loop.uv_buf), 1, -1, @@ -2539,7 +2530,7 @@ pub const Blob = struct { const rc2 = libuv.uv_fs_write( event_loop.virtual_machine.event_loop_handle.?, &this.io_request, - bun.uvfdcast(destination_fd), + destination_fd.uv(), @ptrCast(&this.read_write_loop.uv_buf), 1, -1, @@ -2590,7 +2581,7 @@ pub const Blob = struct { const rc2 = libuv.uv_fs_write( this.event_loop.virtual_machine.event_loop_handle.?, &this.io_request, - bun.uvfdcast(destination_fd), + destination_fd.uv(), @ptrCast(&this.read_write_loop.uv_buf), 1, -1, @@ -2618,26 +2609,26 @@ pub const Blob = struct { pub fn close(this: *ReadWriteLoop) void { if (this.must_close_source_fd) { - if (bun.toLibUVOwnedFD(this.source_fd)) |fd| { + if (this.source_fd.makeLibUVOwned()) |fd| { bun.Async.Closer.close( - bun.uvfdcast(fd), + fd, bun.Async.Loop.get(), ); } else |_| { - _ = bun.sys.close(this.source_fd); + this.source_fd.close(); } this.must_close_source_fd = false; this.source_fd = invalid_fd; } if (this.must_close_destination_fd) { - if (bun.toLibUVOwnedFD(this.destination_fd)) |fd| { + if (this.destination_fd.makeLibUVOwned()) |fd| { bun.Async.Closer.close( - bun.uvfdcast(fd), + fd, bun.Async.Loop.get(), ); } else |_| { - _ = bun.sys.close(this.destination_fd); + this.destination_fd.close(); } this.must_close_destination_fd = false; this.destination_fd = invalid_fd; @@ -2700,8 +2691,8 @@ pub const Blob = struct { bun.O.WRONLY | bun.O.CREAT, 0, )) { - .result => |result| bun.toLibUVOwnedFD(result) catch { - _ = bun.sys.close(result); + .result => |result| result.makeLibUVOwned() catch { + result.close(); return .{ .err = .{ .errno = @as(c_int, @intCast(@intFromEnum(bun.C.SystemErrno.EMFILE))), @@ -3135,14 +3126,14 @@ pub const Blob = struct { pub fn doCloseFile(this: *CopyFile, comptime which: IOWhich) void { switch (which) { .both => { - _ = bun.sys.close(this.destination_fd); - _ = bun.sys.close(this.source_fd); + this.destination_fd.close(); + this.source_fd.close(); }, .destination => { - _ = bun.sys.close(this.destination_fd); + this.destination_fd.close(); }, .source => { - _ = bun.sys.close(this.source_fd); + this.source_fd.close(); }, } } @@ -3161,7 +3152,7 @@ pub const Blob = struct { open_source_flags, 0, )) { - .result => |result| switch (bun.sys.toLibUVOwnedFD(result, .open, .close_on_fail)) { + .result => |result| switch (result.makeLibUVOwnedForSyscall(.open, .close_on_fail)) { .result => |result_fd| result_fd, .err => |errno| { this.system_error = errno.toSystemError(); @@ -3183,7 +3174,7 @@ pub const Blob = struct { open_destination_flags, JSC.Node.default_permission, )) { - .result => |result| switch (bun.sys.toLibUVOwnedFD(result, .open, .close_on_fail)) { + .result => |result| switch (result.makeLibUVOwnedForSyscall(.open, .close_on_fail)) { .result => |result_fd| result_fd, .err => |errno| { this.system_error = errno.toSystemError(); @@ -3195,8 +3186,8 @@ pub const Blob = struct { .@"continue" => continue, .fail => { if (which == .both) { - _ = bun.sys.close(this.source_fd); - this.source_fd = .zero; + this.source_fd.close(); + this.source_fd = .invalid; } return bun.errnoToZigErr(errno.errno); }, @@ -3204,8 +3195,8 @@ pub const Blob = struct { } if (which == .both) { - _ = bun.sys.close(this.source_fd); - this.source_fd = .zero; + this.source_fd.close(); + this.source_fd = .invalid; } this.system_error = errno.withPath(this.destination_file_store.pathlike.path.slice()).toSystemError(); @@ -3902,7 +3893,7 @@ pub const Blob = struct { callframe: *JSC.CallFrame, ) bun.JSError!JSC.JSValue { const thisValue = callframe.this(); - if (Blob.streamGetCached(thisValue)) |cached| { + if (js.streamGetCached(thisValue)) |cached| { return cached; } var recommended_chunk_size: SizeType = 0; @@ -3928,7 +3919,7 @@ pub const Blob = struct { // in the case we have a file descriptor store, we want to de-duplicate // readable streams. in every other case we want `.stream()` to be it's // own stream. - Blob.streamSetCached(thisValue, globalThis, stream); + js.streamSetCached(thisValue, globalThis, stream); }, else => {}, }, @@ -4370,10 +4361,10 @@ pub const Blob = struct { } } - break :brk switch (bun.FDTag.get(fd)) { - .stdout, .stderr => true, + break :brk if (fd.stdioTag()) |tag| switch (tag) { + .std_out, .std_err => true, else => false, - }; + } else false; }; var sink = JSC.WebCore.FileSink.init(fd, this.globalThis.bunVM().eventLoop()); sink.writer.owns_fd = pathlike != .fd; @@ -4613,10 +4604,10 @@ pub const Blob = struct { } } - break :brk switch (bun.FDTag.get(fd)) { - .stdout, .stderr => true, + break :brk if (fd.stdioTag()) |tag| switch (tag) { + .std_out, .std_err => true, else => false, - }; + } else false; }; var sink = JSC.WebCore.FileSink.init(fd, this.globalThis.bunVM().eventLoop()); sink.writer.owns_fd = pathlike != .fd; @@ -4869,7 +4860,7 @@ pub const Blob = struct { if (value.isEmptyOrUndefinedOrNull()) { this.name.deref(); this.name = bun.String.dead; - Blob.nameSetCached(jsThis, globalThis, value); + js.nameSetCached(jsThis, globalThis, value); return true; } if (value.isString()) { @@ -4886,7 +4877,7 @@ pub const Blob = struct { return false; }; // We don't need to increment the reference count since tryFromJS already did it. - Blob.nameSetCached(jsThis, globalThis, value); + js.nameSetCached(jsThis, globalThis, value); old_name.deref(); return true; } @@ -5323,7 +5314,7 @@ pub const Blob = struct { return S3File.toJSUnchecked(globalObject, this); } - return Blob.toJSUnchecked(globalObject, this); + return js.toJSUnchecked(globalObject, this); } pub fn deinit(this: *Blob) void { diff --git a/src/bun.js/webcore/blob/ReadFile.zig b/src/bun.js/webcore/blob/ReadFile.zig index 040ff469b4..5eb0c0efab 100644 --- a/src/bun.js/webcore/blob/ReadFile.zig +++ b/src/bun.js/webcore/blob/ReadFile.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const std = @import("std"); const Blob = bun.JSC.WebCore.Blob; @@ -632,7 +632,7 @@ pub const ReadFileUV = struct { this.req.deinit(); this.req.data = this; - if (libuv.uv_fs_fstat(this.loop, &this.req, bun.uvfdcast(opened_fd), &onFileInitialStat).errEnum()) |errno| { + if (libuv.uv_fs_fstat(this.loop, &this.req, opened_fd.uv(), &onFileInitialStat).errEnum()) |errno| { this.errno = bun.errnoToZigErr(errno); this.system_error = bun.sys.Error.fromCode(errno, .fstat).toSystemError(); this.onFinish(); @@ -756,7 +756,7 @@ pub const ReadFileUV = struct { const res = libuv.uv_fs_read( this.loop, &this.req, - bun.uvfdcast(this.opened_fd), + this.opened_fd.uv(), &bufs, bufs.len, @as(i64, @intCast(this.offset + this.read_off)), diff --git a/src/bun.js/webcore/blob/WriteFile.zig b/src/bun.js/webcore/blob/WriteFile.zig index 7c13a9a18e..9bdbc8ebb8 100644 --- a/src/bun.js/webcore/blob/WriteFile.zig +++ b/src/bun.js/webcore/blob/WriteFile.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const std = @import("std"); const Blob = JSC.WebCore.Blob; @@ -411,7 +411,7 @@ pub const WriteFileWindows = struct { } // The file stored descriptor is not stdin, stdout, or stderr. - break :brk bun.uvfdcast(file_blob.store.?.data.file.pathlike.fd); + break :brk file_blob.store.?.data.file.pathlike.fd.uv(); }; write_file.doWriteLoop(write_file.loop()); @@ -623,7 +623,7 @@ pub const WriteFileWindows = struct { pub fn deinit(this: *@This()) void { const fd = this.fd; if (fd > 0 and this.owned_fd) { - bun.Async.Closer.close(fd, this.io_request.loop); + bun.Async.Closer.close(.fromUV(fd), this.io_request.loop); } this.file_blob.store.?.deref(); this.bytes_blob.store.?.deref(); diff --git a/src/bun.js/webcore/body.zig b/src/bun.js/webcore/body.zig index b48011f7da..a3a63a0889 100644 --- a/src/bun.js/webcore/body.zig +++ b/src/bun.js/webcore/body.zig @@ -1,11 +1,10 @@ const std = @import("std"); const Api = @import("../../api/schema.zig").Api; -const bun = @import("root").bun; +const bun = @import("bun"); const MimeType = bun.http.MimeType; const ZigURL = @import("../../url.zig").URL; const HTTPClient = bun.http; const JSC = bun.JSC; -const js = JSC.C; const Method = @import("../../http/method.zig").Method; const FetchHeaders = JSC.FetchHeaders; @@ -144,7 +143,7 @@ pub const Body = struct { return true; } - if (T.bodyGetCached(this_value)) |body_value| { + if (T.js.bodyGetCached(this_value)) |body_value| { if (JSC.WebCore.ReadableStream.isDisturbedValue(body_value, globalObject)) { return true; } diff --git a/src/bun.js/webcore/encoding.zig b/src/bun.js/webcore/encoding.zig index 600b704fc4..f12a653c78 100644 --- a/src/bun.js/webcore/encoding.zig +++ b/src/bun.js/webcore/encoding.zig @@ -5,12 +5,11 @@ const ZigURL = @import("../../url.zig").URL; const HTTPClient = bun.http; const JSC = bun.JSC; -const js = JSC.C; const Method = @import("../../http/method.zig").Method; const ObjectPool = @import("../../pool.zig").ObjectPool; -const bun = @import("root").bun; +const bun = @import("bun"); const Output = bun.Output; const MutableString = bun.MutableString; const strings = bun.strings; diff --git a/src/bun.js/webcore/fetch.zig b/src/bun.js/webcore/fetch.zig index 28767cd2e0..cc2a2d598f 100644 --- a/src/bun.js/webcore/fetch.zig +++ b/src/bun.js/webcore/fetch.zig @@ -1,7 +1,7 @@ const headers_string = "headers"; const method_string = "method"; -const JSType = js.JSType; +const JSType = JSC.C.JSType; pub const fetch_error_no_args = "fetch() expects a string but received no arguments."; pub const fetch_error_blank_url = "fetch() URL must not be a blank string."; @@ -178,7 +178,7 @@ pub const FetchTasklet = struct { }, .Sendfile => { if (@max(this.Sendfile.offset, this.Sendfile.remain) > 0) - _ = bun.sys.close(this.Sendfile.fd); + this.Sendfile.fd.close(); this.Sendfile.offset = 0; this.Sendfile.remain = 0; }, @@ -1132,7 +1132,7 @@ pub const FetchTasklet = struct { pub fn onResolve(this: *FetchTasklet) JSValue { log("onResolve", .{}); const response = bun.new(Response, this.toResponse()); - const response_js = Response.makeMaybePooled(@as(js.JSContextRef, this.global_this), response); + const response_js = Response.makeMaybePooled(@as(*JSC.JSGlobalObject, this.global_this), response); response_js.ensureStillAlive(); this.response = JSC.Weak(FetchTasklet).create(response_js, this.global_this, .FetchResponse, this); this.native_response = response.ref(); @@ -2475,7 +2475,7 @@ pub fn Bun__fetch_( ); if (body.store().?.data.file.pathlike == .path) { - _ = bun.sys.close(opened_fd); + opened_fd.close(); } switch (res) { @@ -2537,7 +2537,7 @@ pub fn Bun__fetch_( .init = .{ .method = .PUT, .status_code = 200 }, .url = bun.String.createAtomIfPossible(self.url.href), }); - const response_js = Response.makeMaybePooled(@as(js.JSContextRef, global), response); + const response_js = Response.makeMaybePooled(@as(*JSC.JSGlobalObject, global), response); response_js.ensureStillAlive(); self.promise.resolve(global, response_js); }, @@ -2559,7 +2559,7 @@ pub fn Bun__fetch_( }, .url = bun.String.createAtomIfPossible(self.url.href), }); - const response_js = Response.makeMaybePooled(@as(js.JSContextRef, global), response); + const response_js = Response.makeMaybePooled(@as(*JSC.JSGlobalObject, global), response); response_js.ensureStillAlive(); self.promise.resolve(global, response_js); }, @@ -2732,9 +2732,8 @@ fn setHeaders(headers: *?Headers, new_headers: []const picohttp.Header, allocato } } const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; -const js = JSC.C; const DataURL = @import("../../resolver/data_url.zig").DataURL; const string = bun.string; const strings = bun.strings; diff --git a/src/bun.js/webcore/request.zig b/src/bun.js/webcore/request.zig index fb97c4aad5..1b7af9818f 100644 --- a/src/bun.js/webcore/request.zig +++ b/src/bun.js/webcore/request.zig @@ -1,11 +1,10 @@ const std = @import("std"); const Api = @import("../../api/schema.zig").Api; -const bun = @import("root").bun; +const bun = @import("bun"); const MimeType = bun.http.MimeType; const ZigURL = @import("../../url.zig").URL; const HTTPClient = bun.http; const JSC = bun.JSC; -const js = JSC.C; const Method = @import("../../http/method.zig").Method; const FetchHeaders = JSC.FetchHeaders; @@ -63,7 +62,11 @@ pub const Request = struct { internal_event_callback: InternalJSEventCallback = .{}, const RequestMixin = BodyMixin(@This()); - pub usingnamespace JSC.Codegen.JSRequest; + pub const js = JSC.Codegen.JSRequest; + // NOTE: toJS is overridden + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; + pub const new = bun.TrivialNew(@This()); pub const getText = RequestMixin.getText; @@ -212,7 +215,7 @@ pub const Request = struct { pub fn toJS(this: *Request, globalObject: *JSGlobalObject) JSValue { this.calculateEstimatedByteSize(); - return Request.toJSUnchecked(globalObject, this); + return js.toJSUnchecked(globalObject, this); } extern "JS" fn Bun__getParamsIfBunRequest(this_value: JSValue) JSValue; @@ -827,10 +830,9 @@ pub const Request = struct { // value to point to the new readable stream // We must do this on both the original and cloned request // but especially the original request since it will have a stale .body value now. - Request.bodySetCached(js_wrapper, globalThis, readable.value); - + js.bodySetCached(js_wrapper, globalThis, readable.value); if (this.body.value.Locked.readable.get(globalThis)) |other_readable| { - Request.bodySetCached(this_value, globalThis, other_readable.value); + js.bodySetCached(this_value, globalThis, other_readable.value); } } } diff --git a/src/bun.js/webcore/response.zig b/src/bun.js/webcore/response.zig index 6f01aeccc5..dca633dea8 100644 --- a/src/bun.js/webcore/response.zig +++ b/src/bun.js/webcore/response.zig @@ -1,12 +1,11 @@ const std = @import("std"); const Api = @import("../../api/schema.zig").Api; -const bun = @import("root").bun; +const bun = @import("bun"); const MimeType = bun.http.MimeType; const ZigURL = @import("../../url.zig").URL; const http = bun.http; const FetchRedirect = http.FetchRedirect; const JSC = bun.JSC; -const js = JSC.C; const Method = @import("../../http/method.zig").Method; const FetchHeaders = JSC.FetchHeaders; @@ -59,7 +58,10 @@ const s3 = bun.S3; pub const Response = struct { const ResponseMixin = BodyMixin(@This()); - pub usingnamespace JSC.Codegen.JSResponse; + pub const js = JSC.Codegen.JSResponse; + // NOTE: toJS is overridden + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; body: Body, init: Init, @@ -102,7 +104,7 @@ pub const Response = struct { pub fn toJS(this: *Response, globalObject: *JSGlobalObject) JSValue { this.calculateEstimatedByteSize(); - return Response.toJSUnchecked(globalObject, this); + return js.toJSUnchecked(globalObject, this); } pub fn getBodyValue( @@ -330,9 +332,9 @@ pub const Response = struct { // value to point to the new readable stream // We must do this on both the original and cloned response // but especially the original response since it will have a stale .body value now. - Response.bodySetCached(js_wrapper, globalThis, readable.value); + js.bodySetCached(js_wrapper, globalThis, readable.value); if (this.body.value.Locked.readable.get(globalThis)) |other_readable| { - Response.bodySetCached(this_value, globalThis, other_readable.value); + js.bodySetCached(this_value, globalThis, other_readable.value); } } } diff --git a/src/bun.js/webcore/streams.zig b/src/bun.js/webcore/streams.zig index bf2d171d50..30a4806173 100644 --- a/src/bun.js/webcore/streams.zig +++ b/src/bun.js/webcore/streams.zig @@ -1,6 +1,6 @@ const std = @import("std"); const Api = @import("../../api/schema.zig").Api; -const bun = @import("root").bun; +const bun = @import("bun"); const MimeType = HTTPClient.MimeType; const ZigURL = @import("../../url.zig").URL; const HTTPClient = bun.http; @@ -628,22 +628,18 @@ pub const StreamStart = union(Tag) { }; } - if (bun.FDImpl.fromJS(fd_value)) |fd| { + if (bun.FD.fromJS(fd_value)) |fd| { return .{ .FileSink = .{ .chunk_size = chunk_size, - .input_path = .{ - .fd = fd.encode(), - }, + .input_path = .{ .fd = fd }, }, }; } else { - return .{ - .err = Syscall.Error{ - .errno = @intFromEnum(bun.C.SystemErrno.EBADF), - .syscall = .write, - }, - }; + return .{ .err = Syscall.Error{ + .errno = @intFromEnum(bun.C.SystemErrno.EBADF), + .syscall = .write, + } }; } } @@ -3634,13 +3630,13 @@ pub const FileSink = struct { if (comptime Environment.isPosix) { switch (bun.sys.fstat(fd)) { .err => |err| { - _ = bun.sys.close(fd); + fd.close(); return .{ .err = err }; }, .result => |stat| { this.pollable = bun.sys.isPollable(stat.mode); if (!this.pollable) { - isatty = std.posix.isatty(fd.int()); + isatty = std.posix.isatty(fd.native()); } if (isatty) { @@ -3664,7 +3660,7 @@ pub const FileSink = struct { const flags = switch (bun.sys.getFcntlFlags(fd)) { .result => |flags| flags, .err => |err| { - _ = bun.sys.close(fd); + fd.close(); return .{ .err = err }; }, }; @@ -3694,7 +3690,7 @@ pub const FileSink = struct { this.pollable, )) { .err => |err| { - _ = bun.sys.close(fd); + fd.close(); return .{ .err = err }; }, .result => { @@ -3710,7 +3706,7 @@ pub const FileSink = struct { this.pollable, )) { .err => |err| { - _ = bun.sys.close(fd); + fd.close(); return .{ .err = err }; }, .result => { @@ -3996,10 +3992,9 @@ pub const FileSink = struct { fn getFd(this: *const @This()) i32 { if (Environment.isWindows) { - const fd_impl = this.fd.impl(); - return switch (fd_impl.kind) { - .system => -1, // TODO: - .uv => fd_impl.value.as_uv, + return switch (this.fd.decodeWindows()) { + .windows => -1, // TODO: + .uv => |num| num, }; } return this.fd.cast(); @@ -4094,14 +4089,14 @@ pub const FileReader = struct { var file_buf: bun.PathBuffer = undefined; var is_nonblocking = false; - const fd = if (file.pathlike == .fd) - if (file.pathlike.fd.isStdio()) brk: { + const fd: bun.FD = if (file.pathlike == .fd) + if (file.pathlike.fd.stdioTag() != null) brk: { if (comptime Environment.isPosix) { - const rc = bun.C.open_as_nonblocking_tty(file.pathlike.fd.int(), bun.O.RDONLY); + const rc = bun.C.open_as_nonblocking_tty(file.pathlike.fd.native(), bun.O.RDONLY); if (rc > -1) { is_nonblocking = true; file.is_atty = true; - break :brk bun.toFD(rc); + break :brk .fromNative(rc); } } break :brk file.pathlike.fd; @@ -4112,18 +4107,17 @@ pub const FileReader = struct { return .{ .err = duped.err.withFd(file.pathlike.fd) }; } - const fd = duped.result; - + const fd: bun.FD = duped.result; if (comptime Environment.isPosix) { - if (bun.FDTag.get(fd) == .none) { - is_nonblocking = switch (bun.sys.getFcntlFlags(fd)) { + if (fd.stdioTag() == null) { + is_nonblocking = switch (fd.getFcntlFlags()) { .result => |flags| (flags & bun.O.NONBLOCK) != 0, .err => false, }; } } - break :brk switch (bun.sys.toLibUVOwnedFD(fd, .dup, .close_on_fail)) { + break :brk switch (fd.makeLibUVOwnedForSyscall(.dup, .close_on_fail)) { .result => |owned_fd| owned_fd, .err => |err| { return .{ .err = err }; @@ -4139,9 +4133,9 @@ pub const FileReader = struct { if (comptime Environment.isPosix) { if ((file.is_atty orelse false) or - (fd.int() < 3 and std.posix.isatty(fd.cast())) or + (fd.stdioTag() != null and std.posix.isatty(fd.cast())) or (file.pathlike == .fd and - bun.FDTag.get(file.pathlike.fd) != .none and + file.pathlike.fd.stdioTag() != null and std.posix.isatty(file.pathlike.fd.cast()))) { // var termios = std.mem.zeroes(std.posix.termios); @@ -4154,7 +4148,7 @@ pub const FileReader = struct { const stat: bun.Stat = switch (Syscall.fstat(fd)) { .result => |result| result, .err => |err| { - _ = Syscall.close(fd); + fd.close(); return .{ .err = err }; }, }; diff --git a/src/bun.zig b/src/bun.zig index 1c9f0301b7..7afafa9818 100644 --- a/src/bun.zig +++ b/src/bun.zig @@ -1,13 +1,11 @@ -/// The functions in this file are used throughout Bun's codebase -// -// Do not import this file directly! -// To import it: -// @import("root").bun -// -// Otherwise, you risk a circular dependency or Zig including multiple copies of this file which leads to strange bugs. +//! This is the root source file of Bun's zig module. It can be imported using +//! `@import("bun")`, and should be able to reach all code via `.` syntax. +//! +//! Prefer adding new code into a separate file and adding an import, or putting +//! code in the relevant namespace. +const bun = @This(); const builtin = @import("builtin"); const std = @import("std"); -const bun = @This(); pub const Environment = @import("env.zig"); @@ -137,7 +135,7 @@ pub const ComptimeStringMapWithKeyType = comptime_string_map.ComptimeStringMapWi pub const glob = @import("./glob.zig"); pub const patch = @import("./patch.zig"); pub const ini = @import("./ini.zig"); -pub const Bitflags = @import("./bitflags.zig").Bitflags; +pub const bits = @import("bits.zig"); pub const css = @import("./css/css_parser.zig"); pub const csrf = @import("./csrf.zig"); pub const validators = @import("./bun.js/node/util/validators.zig"); @@ -147,133 +145,15 @@ pub const shell = @import("./shell/shell.zig"); pub const Output = @import("./output.zig"); pub const Global = @import("./Global.zig"); -// make this non-pub after https://github.com/ziglang/zig/issues/18462 is resolved -pub const FileDescriptorInt = if (Environment.isBrowser) - u0 -else if (Environment.isWindows) - // On windows, this is a bitcast "bun.FDImpl" struct - // Do not bitcast it to *anyopaque manually, but instead use `fdcast()` - u64 -else - std.posix.fd_t; +pub const FD = @import("fd.zig").FD; -pub const FD = FileDescriptor; -pub const FileDescriptor = enum(FileDescriptorInt) { - /// Zero is used in old filesystem code to indicate "no file descriptor" - /// This is problematic because on POSIX, this is ambiguous with stdin being 0. - /// All code that uses this should migrate to invalid_fd to represent invalid states. - zero = 0, - // Represents an invalid file descriptor. This is used instead of null to - // avoid an extra bit. - // invalid = @intFromEnum(invalid_fd), - _, - - /// Do not use this function in new code. - /// - /// Interpreting a FD as an integer is almost certainly a mistake. - /// On Windows, it is always a mistake, as the integer is bitcast of a tagged packed struct. - /// - /// TODO(@paperclover): remove this API. - pub fn int(self: FileDescriptor) std.posix.fd_t { - if (Environment.isWindows) - @compileError("FileDescriptor.int() is not allowed on Windows."); - return @intFromEnum(self); - } - - pub fn writeTo(fd: FileDescriptor, writer: anytype, endian: std.builtin.Endian) !void { - try writer.writeInt(FileDescriptorInt, @intFromEnum(fd), endian); - } - - pub fn readFrom(reader: anytype, endian: std.builtin.Endian) !FileDescriptor { - return @enumFromInt(try reader.readInt(FileDescriptorInt, endian)); - } - - /// converts a `bun.FileDescriptor` into the native operating system fd - /// - /// On non-windows this does nothing, but on windows it converts UV descriptors - /// to Windows' *HANDLE, and casts the types for proper usage. - /// - /// This may be needed in places where a FileDescriptor is given to `std` or `kernel32` apis - pub fn cast(fd: FileDescriptor) std.posix.fd_t { - if (!Environment.isWindows) return fd.int(); - // if not having this check, the cast may crash zig compiler? - if (@inComptime() and fd == invalid_fd) return FDImpl.invalid.system(); - return fd.impl().system(); - } - - pub fn asDir(fd: FileDescriptor) std.fs.Dir { - return std.fs.Dir{ .fd = fd.cast() }; - } - - pub fn asFile(fd: FileDescriptor) std.fs.File { - return std.fs.File{ .handle = fd.cast() }; - } - - pub fn format(fd: FileDescriptor, comptime fmt_: string, options_: std.fmt.FormatOptions, writer: anytype) !void { - try FDImpl.format(fd.impl(), fmt_, options_, writer); - } - - pub fn assertValid(fd: FileDescriptor) void { - fd.impl().assertValid(); - } - - pub fn isValid(fd: FileDescriptor) bool { - return fd.impl().isValid(); - } - - pub fn assertKind(fd: FileDescriptor, kind: FDImpl.Kind) void { - assert(fd.impl().kind == kind); - } - - pub fn cwd() FileDescriptor { - return toFD(std.fs.cwd().fd); - } - - pub fn eq(this: FileDescriptor, that: FileDescriptor) bool { - if (Environment.isPosix) return this.int() == that.int(); - - const this_ = FDImpl.decode(this); - const that_ = FDImpl.decode(that); - return switch (this_.kind) { - .system => switch (that_.kind) { - .system => this_.value.as_system == that_.value.as_system, - .uv => false, - }, - .uv => switch (that_.kind) { - .system => false, - .uv => this_.value.as_uv == that_.value.as_uv, - }, - }; - } - - pub fn isStdio(fd: FileDescriptor) bool { - // fd.assertValid(); - const decoded = fd.impl(); - return switch (Environment.os) { - else => decoded.value.as_system < 3, - .windows => switch (decoded.kind) { - .system => fd == win32.STDIN_FD or - fd == win32.STDOUT_FD or - fd == win32.STDERR_FD, - .uv => decoded.value.as_uv < 3, - }, - }; - } - - pub fn toJS(value: FileDescriptor, global: *JSC.JSGlobalObject) JSC.JSValue { - return FDImpl.decode(value).toJS(global); - } - - pub fn impl(fd: FileDescriptor) FDImpl { - return FDImpl.decode(fd); - } -}; - -pub const FDImpl = @import("./fd.zig").FDImpl; +/// Deprecated: Use `FD` instead. +pub const FileDescriptor = FD; // When we are on a computer with an absurdly high number of max open file handles // such is often the case with macOS // As a useful optimization, we can store file descriptors and just keep them open...forever +/// Deprecated: Rename to use `FD` instead. pub const StoredFileDescriptorType = FileDescriptor; /// Thin wrapper around iovec / libuv buffer @@ -616,7 +496,7 @@ pub fn isWritable(fd: FileDescriptor) PollFlag { if (comptime Environment.isWindows) { var polls = [_]std.os.windows.ws2_32.WSAPOLLFD{ .{ - .fd = socketcast(fd), + .fd = fd.asSocketFd(), .events = std.posix.POLL.WRNORM, .revents = 0, }, @@ -737,9 +617,9 @@ pub fn rangeOfSliceInBuffer(slice: []const u8, buffer: []const u8) ?[2]u32 { return r; } -/// on unix, this == std.math.maxInt(i32) -/// on windows, this is encode(.{ .system, std.math.maxInt(u63) }) -pub const invalid_fd: FileDescriptor = FDImpl.invalid.encode(); +// TODO: prefer .invalid decl literal over this +// Please prefer `bun.FD.Optional.none` over this +pub const invalid_fd: FileDescriptor = .invalid; pub const simdutf = @import("./bun.js/bindings/bun-simdutf.zig"); @@ -780,7 +660,7 @@ pub fn openFile(path_: []const u8, open_flags: std.fs.File.OpenFlags) !std.fs.Fi } const fd = try sys.openA(path_, flags, 0).unwrap(); - return fd.asFile(); + return fd.stdFile(); } return try openFileZ(&try std.posix.toPosixPath(path_), open_flags); @@ -788,37 +668,37 @@ pub fn openFile(path_: []const u8, open_flags: std.fs.File.OpenFlags) !std.fs.Fi pub fn openDir(dir: std.fs.Dir, path_: [:0]const u8) !std.fs.Dir { if (comptime Environment.isWindows) { - const res = try sys.openDirAtWindowsA(toFD(dir.fd), path_, .{ .iterable = true, .can_rename_or_delete = true, .read_only = true }).unwrap(); - return res.asDir(); + const res = try sys.openDirAtWindowsA(.fromStdDir(dir), path_, .{ .iterable = true, .can_rename_or_delete = true, .read_only = true }).unwrap(); + return res.stdDir(); } else { - const fd = try sys.openat(toFD(dir.fd), path_, O.DIRECTORY | O.CLOEXEC | O.RDONLY, 0).unwrap(); - return fd.asDir(); + const fd = try sys.openat(.fromStdDir(dir), path_, O.DIRECTORY | O.CLOEXEC | O.RDONLY, 0).unwrap(); + return fd.stdDir(); } } pub fn openDirNoRenamingOrDeletingWindows(dir: FileDescriptor, path_: [:0]const u8) !std.fs.Dir { if (comptime !Environment.isWindows) @compileError("use openDir!"); const res = try sys.openDirAtWindowsA(dir, path_, .{ .iterable = true, .can_rename_or_delete = false, .read_only = true }).unwrap(); - return res.asDir(); + return res.stdDir(); } pub fn openDirA(dir: std.fs.Dir, path_: []const u8) !std.fs.Dir { if (comptime Environment.isWindows) { - const res = try sys.openDirAtWindowsA(toFD(dir.fd), path_, .{ .iterable = true, .can_rename_or_delete = true, .read_only = true }).unwrap(); - return res.asDir(); + const res = try sys.openDirAtWindowsA(.fromStdDir(dir), path_, .{ .iterable = true, .can_rename_or_delete = true, .read_only = true }).unwrap(); + return res.stdDir(); } else { - const fd = try sys.openatA(toFD(dir.fd), path_, O.DIRECTORY | O.CLOEXEC | O.RDONLY, 0).unwrap(); - return fd.asDir(); + const fd = try sys.openatA(.fromStdDir(dir), path_, O.DIRECTORY | O.CLOEXEC | O.RDONLY, 0).unwrap(); + return fd.stdDir(); } } pub fn openDirForIteration(dir: std.fs.Dir, path_: []const u8) !std.fs.Dir { if (comptime Environment.isWindows) { - const res = try sys.openDirAtWindowsA(toFD(dir.fd), path_, .{ .iterable = true, .can_rename_or_delete = false, .read_only = true }).unwrap(); - return res.asDir(); + const res = try sys.openDirAtWindowsA(.fromStdDir(dir), path_, .{ .iterable = true, .can_rename_or_delete = false, .read_only = true }).unwrap(); + return res.stdDir(); } else { - const fd = try sys.openatA(toFD(dir.fd), path_, O.DIRECTORY | O.CLOEXEC | O.RDONLY, 0).unwrap(); - return fd.asDir(); + const fd = try sys.openatA(.fromStdDir(dir), path_, O.DIRECTORY | O.CLOEXEC | O.RDONLY, 0).unwrap(); + return fd.stdDir(); } } @@ -828,7 +708,7 @@ pub fn openDirAbsolute(path_: []const u8) !std.fs.Dir { else try sys.openA(path_, O.DIRECTORY | O.CLOEXEC | O.RDONLY, 0).unwrap(); - return fd.asDir(); + return fd.stdDir(); } pub fn openDirAbsoluteNotForDeletingOrRenaming(path_: []const u8) !std.fs.Dir { @@ -837,7 +717,7 @@ pub fn openDirAbsoluteNotForDeletingOrRenaming(path_: []const u8) !std.fs.Dir { else try sys.openA(path_, O.DIRECTORY | O.CLOEXEC | O.RDONLY, 0).unwrap(); - return fd.asDir(); + return fd.stdDir(); } pub const MimallocArena = @import("./allocators/mimalloc_arena.zig").Arena; @@ -894,38 +774,6 @@ pub fn getenvTruthy(key: [:0]const u8) bool { return false; } -pub const FDHashMapContext = struct { - pub fn hash(_: @This(), fd: FileDescriptor) u64 { - // a file descriptor is i32 on linux, u64 on windows - // the goal here is to do zero work and widen the 32 bit type to 64 - // this should compile error if FileDescriptor somehow is larger than 64 bits. - comptime assert(@bitSizeOf(FileDescriptor) <= 64); - return @intCast(fd.int()); - } - pub fn eql(_: @This(), a: FileDescriptor, b: FileDescriptor) bool { - return a == b; - } - pub fn pre(input: FileDescriptor) Prehashed { - return Prehashed{ - .value = @This().hash(.{}, input), - .input = input, - }; - } - - pub const Prehashed = struct { - value: u64, - input: FileDescriptor, - pub fn hash(this: @This(), fd: FileDescriptor) u64 { - if (fd == this.input) return this.value; - return fd; - } - - pub fn eql(_: @This(), a: FileDescriptor, b: FileDescriptor) bool { - return a == b; - } - }; -}; - pub const U32HashMapContext = struct { pub fn hash(_: @This(), value: u32) u64 { return @intCast(value); @@ -1108,7 +956,7 @@ pub fn StringHashMapUnmanaged(comptime Type: type) type { } pub fn FDHashMap(comptime Type: type) type { - return std.HashMap(StoredFileDescriptorType, Type, FDHashMapContext, std.hash_map.default_max_load_percentage); + return std.HashMap(FD, Type, FD.HashMapContext, std.hash_map.default_max_load_percentage); } pub fn U32HashMap(comptime Type: type) type { @@ -1335,6 +1183,7 @@ pub const FormData = @import("./url.zig").FormData; var needs_proc_self_workaround: bool = false; +/// TODO: move to bun.sys // This is our "polyfill" when /proc/self/fd is not available it's only // necessary on linux because other platforms don't have an optional // /proc/self/fd @@ -1358,14 +1207,13 @@ pub fn getcwdAlloc(allocator: std.mem.Allocator) ![:0]u8 { return allocator.dupeZ(u8, temp_slice); } +/// TODO: move to bun.sys and add a method onto FileDescriptor /// Get the absolute path to a file descriptor. /// On Linux, when `/proc/self/fd` is not available, this function will attempt to use `fchdir` and `getcwd` to get the path instead. -pub fn getFdPath(fd_: anytype, buf: *bun.PathBuffer) ![]u8 { - const fd = toFD(fd_).cast(); - +pub fn getFdPath(fd: FileDescriptor, buf: *bun.PathBuffer) ![]u8 { if (comptime Environment.isWindows) { var wide_buf: WPathBuffer = undefined; - const wide_slice = try windows.GetFinalPathNameByHandle(fd, .{}, wide_buf[0..]); + const wide_slice = try windows.GetFinalPathNameByHandle(fd.native(), .{}, wide_buf[0..]); const res = strings.copyUTF16IntoUTF8(buf[0..], @TypeOf(wide_slice), wide_slice, true); return buf[0..res.written]; } @@ -1382,36 +1230,34 @@ pub fn getFdPath(fd_: anytype, buf: *bun.PathBuffer) ![]u8 { needs_proc_self_workaround = strings.eql(getenvZ("BUN_NEEDS_PROC_SELF_WORKAROUND") orelse "0", "1"); } } else if (comptime !Environment.isLinux) { - return try std.os.getFdPath(fd, buf); + return try std.os.getFdPath(fd.native(), buf); } if (needs_proc_self_workaround) { - return getFdPathViaCWD(fd, buf); + return getFdPathViaCWD(fd.native(), buf); } - return std.os.getFdPath(fd, buf) catch |err| { + return std.os.getFdPath(fd.native(), buf) catch |err| { if (err == error.FileNotFound and !needs_proc_self_workaround) { needs_proc_self_workaround = true; - return getFdPathViaCWD(fd, buf); + return getFdPathViaCWD(fd.native(), buf); } return err; }; } -pub fn getFdPathZ(fd_: anytype, buf: *PathBuffer) ![:0]u8 { - const path_ = try getFdPath(fd_, buf); - buf[path_.len] = 0; - return buf[0..path_.len :0]; +/// TODO: move to bun.sys and add a method onto FileDescriptor +pub fn getFdPathZ(fd: FileDescriptor, buf: *PathBuffer) ![:0]u8 { + const fd_path = try getFdPath(fd, buf); + buf[fd_path.len] = 0; + return buf[0..fd_path.len :0]; } -pub fn getFdPathW(fd_: anytype, buf: *WPathBuffer) ![]u16 { - const fd = toFD(fd_).cast(); - +/// TODO: move to bun.sys and add a method onto FileDescriptor +pub fn getFdPathW(fd: FileDescriptor, buf: *WPathBuffer) ![]u16 { if (comptime Environment.isWindows) { - const wide_slice = try windows.GetFinalPathNameByHandle(fd, .{}, buf); - - return wide_slice; + return try windows.GetFinalPathNameByHandle(fd.native(), .{}, buf); } @panic("TODO unsupported platform for getFdPathW"); @@ -1744,9 +1590,9 @@ pub fn reloadProcess( // macOS doesn't have CLOEXEC, so we must go through posix_spawn if (comptime Environment.isMac) { var actions = PosixSpawn.Actions.init() catch unreachable; - actions.inherit(posix.STDIN_FD) catch unreachable; - actions.inherit(posix.STDOUT_FD) catch unreachable; - actions.inherit(posix.STDERR_FD) catch unreachable; + actions.inherit(.stdin()) catch unreachable; + actions.inherit(.stdout()) catch unreachable; + actions.inherit(.stderr()) catch unreachable; var attrs = PosixSpawn.Attr.init() catch unreachable; attrs.resetSignals() catch {}; @@ -2039,110 +1885,6 @@ pub inline fn todo(src: std.builtin.SourceLocation, value: anytype) @TypeOf(valu return value; } -/// Converts a native file descriptor into a `bun.FileDescriptor` -/// -/// Accepts either a UV descriptor (i32) or a windows handle (*anyopaque) -pub fn toFD(fd: anytype) callconv(callconv_inline) FileDescriptor { - const T = @TypeOf(fd); - if (Environment.isWindows) { - return (switch (T) { - FDImpl => fd, // TODO: remove the toFD call from these places and make this a @compileError - FDImpl.System => FDImpl.fromSystem(fd), - FDImpl.UV, i32, comptime_int => FDImpl.fromUV(fd), - FileDescriptor => FDImpl.decode(fd), - std.fs.Dir => FDImpl.fromSystem(fd.fd), - sys.File, std.fs.File => FDImpl.fromSystem(fd.handle), - // TODO: remove u32 - u32 => FDImpl.fromUV(@intCast(fd)), - else => @compileError("toFD() does not support type \"" ++ @typeName(T) ++ "\""), - }).encode(); - } else { - // TODO: remove intCast. we should not be casting u32 -> i32 - // even though file descriptors are always positive, linux/mac represents them as signed integers - return switch (T) { - FileDescriptor => fd, // TODO: remove the toFD call from these places and make this a @compileError - sys.File => fd.handle, - std.fs.File => @enumFromInt(fd.handle), - std.fs.Dir => @enumFromInt(@as(i32, @intCast(fd.fd))), - c_int, i32, u32, comptime_int => @enumFromInt(fd), - else => @compileError("bun.toFD() not implemented for: " ++ @typeName(T)), - }; - } -} - -/// Converts a native file descriptor into a `bun.FileDescriptor` -/// -/// Accepts either a UV descriptor (i32) or a windows handle (*anyopaque) -/// -/// On windows, this file descriptor will always be backed by libuv, so calling .close() is safe. -pub inline fn toLibUVOwnedFD(fd: anytype) !FileDescriptor { - const T = @TypeOf(fd); - if (Environment.isWindows) { - return (switch (T) { - FDImpl.System => try FDImpl.fromSystem(fd).makeLibUVOwned(), - FDImpl.UV => FDImpl.fromUV(fd), - FileDescriptor => try FDImpl.decode(fd).makeLibUVOwned(), - FDImpl => fd.makeLibUVOwned(), - else => @compileError("toLibUVOwnedFD() does not support type \"" ++ @typeName(T) ++ "\""), - }).encode(); - } else { - return toFD(fd); - } -} - -/// Converts FileDescriptor into a UV file descriptor. -/// -/// This explicitly is setup to disallow converting a Windows descriptor into a UV -/// descriptor. If this was allowed, then it would imply the caller still owns the -/// windows handle, but Win->UV will always invalidate the handle. -/// -/// In that situation, it is almost impossible to close the handle properly, -/// you want to use `bun.FDImpl.decode(fd)` or `bun.toLibUVOwnedFD` instead. -/// -/// This way, you can call .close() on the libuv descriptor. -pub inline fn uvfdcast(fd: anytype) FDImpl.UV { - const T = @TypeOf(fd); - if (Environment.isWindows) { - const decoded = (switch (T) { - FDImpl.System => @compileError("This cast (FDImpl.System -> FDImpl.UV) makes this file descriptor very hard to close. Use toLibUVOwnedFD() and FileDescriptor instead. If you truly need to do this conversion (Chloe will probably reject your PR), use bun.FDImpl.fromSystem(fd).uv()"), - FDImpl => fd, - FDImpl.UV => return fd, - FileDescriptor => FDImpl.decode(fd), - else => @compileError("uvfdcast() does not support type \"" ++ @typeName(T) ++ "\""), - }); - - // Specifically allow these anywhere: - if (fd == win32.STDIN_FD) { - return 0; - } - - if (fd == win32.STDOUT_FD) { - return 1; - } - - if (fd == win32.STDERR_FD) { - return 2; - } - - if (Environment.allow_assert) { - if (decoded.kind != .uv) { - std.debug.panic("uvfdcast({}) called on an windows handle", .{decoded}); - } - } - return decoded.uv(); - } else { - return fd.cast(); - } -} - -pub inline fn socketcast(fd: anytype) std.posix.socket_t { - if (Environment.isWindows) { - return @ptrCast(FDImpl.decode(fd).system()); - } else { - return fd.cast(); - } -} - pub const HOST_NAME_MAX = if (Environment.isWindows) // On Windows the maximum length, in bytes, of the string returned in the buffer pointed to by the name parameter is dependent on the namespace provider, but this string must be 256 bytes or less. // So if a buffer of 256 bytes is passed in the name parameter and the namelen parameter is set to 256, the buffer size will always be adequate. @@ -2256,31 +1998,15 @@ pub fn initArgv(allocator: std.mem.Allocator) !void { } pub const posix = struct { - pub const STDIN_FD = toFD(0); - pub const STDOUT_FD = toFD(1); - pub const STDERR_FD = toFD(2); - - pub fn stdio(i: anytype) FileDescriptor { - return switch (i) { - 1 => STDOUT_FD, - 2 => STDERR_FD, - 0 => STDIN_FD, - else => @panic("Invalid stdio fd"), - }; - } - pub const spawn = @import("./bun.js/api/bun/spawn.zig").PosixSpawn; }; pub const win32 = struct { const w = std.os.windows; - pub var STDOUT_FD: FileDescriptor = undefined; - pub var STDERR_FD: FileDescriptor = undefined; - pub var STDIN_FD: FileDescriptor = undefined; /// Returns the original mode, or null on failure - pub fn updateStdioModeFlags(i: anytype, opts: struct { set: w.DWORD = 0, unset: w.DWORD = 0 }) !w.DWORD { - const fd = stdio(i); + pub fn updateStdioModeFlags(i: bun.FD.Stdio, opts: struct { set: w.DWORD = 0, unset: w.DWORD = 0 }) !w.DWORD { + const fd = i.fd(); var original_mode: w.DWORD = 0; if (windows.GetConsoleMode(fd.cast(), &original_mode) != 0) { if (windows.SetConsoleMode(fd.cast(), (original_mode | opts.set) & ~opts.unset) == 0) { @@ -2295,15 +2021,6 @@ pub const win32 = struct { // this was randomly generated - we need to avoid using a common exit code that might be used by the script itself const watcher_reload_exit: w.DWORD = 3224497970; - pub fn stdio(i: anytype) FileDescriptor { - return switch (i) { - 0 => STDIN_FD, - 1 => STDOUT_FD, - 2 => STDERR_FD, - else => @panic("Invalid stdio fd"), - }; - } - pub const spawn = @import("./bun.js/api/bun/spawn.zig").PosixSpawn; pub fn isWatcherChild() bool { @@ -2487,56 +2204,6 @@ pub const Mode = C.Mode; pub const windows = @import("./windows.zig"); -pub const FDTag = enum { - none, - stderr, - stdin, - stdout, - pub fn get(fd_: anytype) FDTag { - const fd = toFD(fd_); - const T = @TypeOf(fd_); - if (comptime Environment.isWindows) { - if (@typeInfo(T) == .int or @typeInfo(T) == .comptime_int) { - switch (fd_) { - 0 => return .stdin, - 1 => return .stdout, - 2 => return .stderr, - else => {}, - } - } - - if (fd == win32.STDOUT_FD) { - return .stdout; - } else if (fd == win32.STDERR_FD) { - return .stderr; - } else if (fd == win32.STDIN_FD) { - return .stdin; - } - - return .none; - } else { - return switch (fd) { - posix.STDIN_FD => FDTag.stdin, - posix.STDOUT_FD => FDTag.stdout, - posix.STDERR_FD => FDTag.stderr, - else => .none, - }; - } - } -}; - -pub fn fdi32(fd_: anytype) i32 { - if (comptime Environment.isPosix) { - return @intCast(toFD(fd_)); - } - - if (comptime @TypeOf(fd_) == *anyopaque) { - return @intCast(@intFromPtr(fd_)); - } - - return @intCast(fd_); -} - pub const LazyBoolValue = enum { unknown, no, @@ -3990,7 +3657,9 @@ pub inline fn take(val: anytype) ?@typeInfo(@typeInfo(@TypeOf(val)).pointer.chil /// This function deinitializes the value and sets the optional to null. pub inline fn clear(val: anytype, allocator: std.mem.Allocator) void { if (val.*) |*v| { - v.deinit(allocator); + if (@hasDecl(@TypeOf(v.*), "deinit")) { + v.deinit(allocator); + } val.* = null; } } diff --git a/src/bun_js.zig b/src/bun_js.zig index 04ac47a26d..06b57de6f7 100644 --- a/src/bun_js.zig +++ b/src/bun_js.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/src/bundler/bundle_v2.zig b/src/bundler/bundle_v2.zig index 91cd87aa8a..b25f460153 100644 --- a/src/bundler/bundle_v2.zig +++ b/src/bundler/bundle_v2.zig @@ -42,7 +42,7 @@ // make mimalloc-debug // const Transpiler = bun.Transpiler; -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; @@ -3434,7 +3434,7 @@ pub const BundleV2 = struct { // To minimize contention, watchers are appended by the transpiler thread. if (this.bun_watcher) |watcher| { - if (parse_result.watcher_data.fd != bun.invalid_fd and parse_result.watcher_data.fd != .zero) { + if (parse_result.watcher_data.fd != bun.invalid_fd) { const source = switch (parse_result.value) { inline .empty, .err => |data| graph.input_files.items(.source)[data.source_index.get()], .success => |val| val.source, @@ -4590,10 +4590,7 @@ pub const ParseTask = struct { file_path.text, task.contents_or_fd.fd.dir, false, - if (contents.file != bun.invalid_fd and contents.file != .zero) - contents.file - else - null, + contents.file.unwrapValid(), ) catch |err| { const source = &Logger.Source.initEmptyFile(log.msgs.allocator.dupe(u8, file_path.text) catch unreachable); switch (err) { @@ -5051,7 +5048,8 @@ pub const ParseTask = struct { } const will_close_file_descriptor = task.contents_or_fd == .fd and - entry.fd.isValid() and !entry.fd.isStdio() and + entry.fd.isValid() and + entry.fd.stdioTag() == null and this.ctx.bun_watcher == null; if (will_close_file_descriptor) { _ = entry.closeFD(); @@ -7015,7 +7013,7 @@ pub const LinkerContext = struct { }; defer dir.close(); - break :dir try bun.getFdPath(bun.toFD(dir.fd), &real_path_buf); + break :dir try bun.FD.fromStdDir(dir).getFdPath(&real_path_buf); }; chunk.template.placeholder.dir = try resolve_path.relativeAlloc(this.allocator, this.resolver.opts.root_dir, dir); @@ -15268,7 +15266,7 @@ pub const LinkerContext = struct { }, }, .encoding = .buffer, - .dirfd = bun.toFD(root_dir.fd), + .dirfd = .fromStdDir(root_dir), .file = .{ .path = JSC.Node.PathLike{ .string = JSC.PathString.init(source_map_final_rel_path), @@ -15360,7 +15358,7 @@ pub const LinkerContext = struct { .encoding = .buffer, .mode = if (chunk.is_executable) 0o755 else 0o644, - .dirfd = bun.toFD(root_dir.fd), + .dirfd = .fromStdDir(root_dir), .file = .{ .path = JSC.Node.PathLike{ .string = JSC.PathString.init(fdpath[0 .. chunk.final_rel_path.len + bun.bytecode_extension.len]), @@ -15417,7 +15415,7 @@ pub const LinkerContext = struct { .encoding = .buffer, .mode = if (chunk.is_executable) 0o755 else 0o644, - .dirfd = bun.toFD(root_dir.fd), + .dirfd = .fromStdDir(root_dir), .file = .{ .path = JSC.Node.PathLike{ .string = JSC.PathString.init(rel_path), @@ -15534,7 +15532,7 @@ pub const LinkerContext = struct { }, }, .encoding = .buffer, - .dirfd = bun.toFD(root_dir.fd), + .dirfd = .fromStdDir(root_dir), .file = .{ .path = JSC.Node.PathLike{ .string = JSC.PathString.init(src.dest_path), diff --git a/src/bundler/entry_points.zig b/src/bundler/entry_points.zig index 2636cc7960..2777c5f5ac 100644 --- a/src/bundler/entry_points.zig +++ b/src/bundler/entry_points.zig @@ -1,6 +1,6 @@ const logger = bun.logger; const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Fs = @import("../fs.zig"); const js_ast = bun.JSAst; diff --git a/src/bunfig.zig b/src/bunfig.zig index 7fb47e16d0..9acd0d1c8e 100644 --- a/src/bunfig.zig +++ b/src/bunfig.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/src/c.zig b/src/c.zig index e05bddf14e..1c1c93e0d3 100644 --- a/src/c.zig +++ b/src/c.zig @@ -9,15 +9,15 @@ //! different definitions between platforms, as well as very common mistakes //! that can be made when porting definitions. It also keeps code much cleaner. const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Environment = @import("./env.zig"); pub const translated = @import("translated-c-headers"); const PlatformSpecific = switch (Environment.os) { - .mac => @import("./darwin_c.zig"), - .linux => @import("./linux_c.zig"), - .windows => @import("./windows_c.zig"), + .mac => @import("darwin_c.zig"), + .linux => @import("linux_c.zig"), + .windows => @import("windows_c.zig"), else => struct {}, }; pub usingnamespace PlatformSpecific; @@ -161,8 +161,8 @@ pub fn moveFileZSlowMaybe(from_dir: bun.FileDescriptor, filename: [:0]const u8, .result => |f| f, .err => |e| return .{ .err = e }, }; - defer _ = bun.sys.close(in_handle); - _ = bun.sys.unlinkat(from_dir, filename); + defer in_handle.close(); + _ = from_dir.unlinkat(filename); return copyFileZSlowWithHandle(in_handle, to_dir, destination); } @@ -202,13 +202,13 @@ pub fn copyFileZSlowWithHandle(in_handle: bun.FileDescriptor, to_dir: bun.FileDe .result => |fd| fd, .err => |e| return .{ .err = e }, }; - defer _ = bun.sys.close(out_handle); + defer out_handle.close(); if (comptime Environment.isLinux) { _ = std.os.linux.fallocate(out_handle.cast(), 0, 0, @intCast(stat_.size)); } - switch (bun.copyFile(in_handle.cast(), out_handle.cast())) { + switch (bun.copyFile(in_handle, out_handle)) { .err => |e| return .{ .err = e }, .result => {}, } diff --git a/src/cache.zig b/src/cache.zig index a56fc9d863..0b2c88e973 100644 --- a/src/cache.zig +++ b/src/cache.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const StoredFileDescriptorType = bun.StoredFileDescriptorType; @@ -73,11 +73,9 @@ pub const Fs = struct { } pub fn closeFD(entry: *Entry) ?bun.sys.Error { - if (entry.fd != bun.invalid_fd) { - defer { - entry.fd = bun.invalid_fd; - } - return bun.sys.close(entry.fd); + if (entry.fd.isValid()) { + defer entry.fd = .invalid; + return entry.fd.closeAllowingBadFileDescriptor(@returnAddress()); } return null; } @@ -183,10 +181,10 @@ pub const Fs = struct { ) !Entry { var rfs = _fs.fs; - var file_handle: std.fs.File = if (_file_handle) |__file| __file.asFile() else undefined; + var file_handle: std.fs.File = if (_file_handle) |__file| __file.stdFile() else undefined; if (_file_handle == null) { - if (FeatureFlags.store_file_descriptors and dirname_fd != bun.invalid_fd and dirname_fd != .zero) { + if (FeatureFlags.store_file_descriptors and dirname_fd.isValid()) { file_handle = (bun.sys.openatA(dirname_fd, std.fs.path.basename(path), bun.O.RDONLY, 0).unwrap() catch |err| brk: { switch (err) { error.ENOENT => { @@ -195,11 +193,11 @@ pub const Fs = struct { "Internal error: directory mismatch for directory \"{s}\", fd {}. You don't need to do anything, but this indicates a bug.", .{ path, dirname_fd }, ); - break :brk bun.toFD(handle.handle); + break :brk bun.FD.fromStdFile(handle); }, else => return err, } - }).asFile(); + }).stdFile(); } else { file_handle = try bun.openFile(path, .{ .mode = .read_only }); } @@ -208,7 +206,7 @@ pub const Fs = struct { } if (comptime !Environment.isWindows) // skip on Windows because NTCreateFile will do it. - debug("openat({}, {s}) = {}", .{ dirname_fd, path, bun.toFD(file_handle.handle) }); + debug("openat({}, {s}) = {}", .{ dirname_fd, path, bun.FD.fromStdFile(file_handle) }); const will_close = rfs.needToCloseFiles() and _file_handle == null; defer { @@ -235,7 +233,7 @@ pub const Fs = struct { return Entry{ .contents = file.contents, - .fd = if (FeatureFlags.store_file_descriptors and !will_close) bun.toFD(file_handle.handle) else bun.invalid_fd, + .fd = if (FeatureFlags.store_file_descriptors and !will_close) .fromStdFile(file_handle) else bun.invalid_fd, }; } }; diff --git a/src/ci_info.zig b/src/ci_info.zig index ed88efc291..df405b3739 100644 --- a/src/ci_info.zig +++ b/src/ci_info.zig @@ -6,7 +6,7 @@ // `name.toLowerCase().split(' ').join('-')` const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const strings = bun.strings; var ci_name: ?[]const u8 = null; diff --git a/src/cli.zig b/src/cli.zig index 1953fc2ae8..200f1312e2 100644 --- a/src/cli.zig +++ b/src/cli.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; @@ -9,7 +9,6 @@ const stringZ = bun.stringZ; const default_allocator = bun.default_allocator; const FeatureFlags = bun.FeatureFlags; const C = bun.C; -const root = @import("root"); const std = @import("std"); const lex = bun.js_lexer; const logger = bun.logger; @@ -335,7 +334,7 @@ pub const Arguments = struct { pub fn loadConfigPath(allocator: std.mem.Allocator, auto_loaded: bool, config_path: [:0]const u8, ctx: Command.Context, comptime cmd: Command.Tag) !void { var config_file = switch (bun.sys.openA(config_path, bun.O.RDONLY, 0)) { - .result => |fd| fd.asFile(), + .result => |fd| fd.stdFile(), .err => |err| { if (auto_loaded) return; Output.prettyErrorln("{}\nwhile opening config \"{s}\"", .{ diff --git a/src/cli/add_command.zig b/src/cli/add_command.zig index a0eccace2c..fe37545aba 100644 --- a/src/cli/add_command.zig +++ b/src/cli/add_command.zig @@ -1,6 +1,6 @@ const Command = @import("../cli.zig").Command; const PackageManager = @import("../install/install.zig").PackageManager; -const bun = @import("root").bun; +const bun = @import("bun"); pub const AddCommand = struct { pub fn exec(ctx: Command.Context) !void { diff --git a/src/cli/add_completions.zig b/src/cli/add_completions.zig index 70d7e497d9..2caed718f1 100644 --- a/src/cli/add_completions.zig +++ b/src/cli/add_completions.zig @@ -8,7 +8,7 @@ // This used to be a comptime block, but it made the build too slow. // Compressing the completions list saves about 100 KB of binary size. const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const zstd = bun.zstd; const Environment = bun.Environment; diff --git a/src/cli/build_command.zig b/src/cli/build_command.zig index e281ffbd53..c80a6f4813 100644 --- a/src/cli/build_command.zig +++ b/src/cli/build_command.zig @@ -1,6 +1,6 @@ const std = @import("std"); const Command = @import("../cli.zig").Command; -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; @@ -205,13 +205,13 @@ pub const BuildCommand = struct { break :brk2 resolve_path.getIfExistsLongestCommonPath(this_transpiler.options.entry_points) orelse "."; }; - var dir = bun.openDirForPath(&(try std.posix.toPosixPath(path))) catch |err| { + var dir = bun.FD.fromStdDir(bun.openDirForPath(&(try std.posix.toPosixPath(path))) catch |err| { Output.prettyErrorln("{s} opening root directory {}", .{ @errorName(err), bun.fmt.quote(path) }); Global.exit(1); - }; + }); defer dir.close(); - break :brk1 bun.getFdPath(bun.toFD(dir.fd), &src_root_dir_buf) catch |err| { + break :brk1 dir.getFdPath(&src_root_dir_buf) catch |err| { Output.prettyErrorln("{s} resolving root directory {}", .{ @errorName(err), bun.fmt.quote(path) }); Global.exit(1); }; diff --git a/src/cli/bunx_command.zig b/src/cli/bunx_command.zig index e5210fb97d..626dd1eed9 100644 --- a/src/cli/bunx_command.zig +++ b/src/cli/bunx_command.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Allocator = std.mem.Allocator; const Output = bun.Output; @@ -197,7 +197,7 @@ pub const BunxCommand = struct { if (dirs.expr.asProperty("bin")) |bin_prop| { if (bin_prop.expr.asString(transpiler.allocator)) |dir_name| { const bin_dir = try bun.sys.openatA(dir_fd, dir_name, bun.O.RDONLY | bun.O.DIRECTORY, 0).unwrap(); - defer _ = bun.sys.close(bin_dir); + defer bin_dir.close(); const dir = std.fs.Dir{ .fd = bin_dir.cast() }; var iterator = bun.DirIterator.iterate(dir, .u8); var entry = iterator.next(); @@ -277,7 +277,7 @@ pub const BunxCommand = struct { /// Check the enclosing package.json for a matching "bin" /// If not found, check bunx cache dir fn getBinName(transpiler: *bun.Transpiler, toplevel_fd: bun.FileDescriptor, tempdir_name: []const u8, package_name: []const u8) error{ NoBinFound, NeedToInstall }![]const u8 { - toplevel_fd.assertValid(); + bun.assert(toplevel_fd.isValid()); return getBinNameFromProjectDirectory(transpiler, toplevel_fd, package_name) catch |err| { if (err == error.NoBinFound) { return error.NoBinFound; @@ -548,7 +548,7 @@ pub const BunxCommand = struct { // and that error message is likely going to be better than the one from `bun add` break :is_stale false; }; - defer _ = bun.sys.close(fd); + defer fd.close(); var io_status_block: std.os.windows.IO_STATUS_BLOCK = undefined; var info: std.os.windows.FILE_BASIC_INFORMATION = undefined; @@ -599,7 +599,7 @@ pub const BunxCommand = struct { // 2. The "bin" is possibly not the same as the package name, so we load the package.json to figure out what "bin" to use const root_dir_fd = root_dir_info.getFileDescriptor(); - bun.assert(root_dir_fd != .zero); + bun.assert(root_dir_fd.isValid()); if (getBinName(&this_transpiler, root_dir_fd, bunx_cache_dir, initial_bin_name)) |package_name_for_bin| { // if we check the bin name and its actually the same, we don't need to check $PATH here again if (!strings.eqlLong(package_name_for_bin, initial_bin_name, true)) { diff --git a/src/cli/colon_list_type.zig b/src/cli/colon_list_type.zig index e766529250..3623185e8a 100644 --- a/src/cli/colon_list_type.zig +++ b/src/cli/colon_list_type.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/src/cli/create_command.zig b/src/cli/create_command.zig index eb1b9a3016..03f9abd815 100644 --- a/src/cli/create_command.zig +++ b/src/cli/create_command.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; @@ -444,12 +444,12 @@ pub const CreateCommand = struct { if (!create_options.skip_package_json) { const plucker = pluckers[0]; - if (plucker.found and plucker.fd != .zero) { + if (plucker.found and plucker.fd.isValid()) { node.name = "Updating package.json"; progress.refresh(); package_json_contents = plucker.contents; - package_json_file = plucker.fd.asFile(); + package_json_file = plucker.fd.stdFile(); } } }, @@ -557,7 +557,7 @@ pub const CreateCommand = struct { } if (entry.kind != .file) continue; - var outfile = destination_dir_.createFile(entry.path, .{}) catch brk: { + var outfile = bun.FD.fromStdFile(destination_dir_.createFile(entry.path, .{}) catch brk: { if (bun.Dirname.dirname(bun.OSPathChar, entry.path)) |entry_dirname| { bun.MakePath.makePath(bun.OSPathChar, destination_dir_, entry_dirname) catch {}; } @@ -567,22 +567,22 @@ pub const CreateCommand = struct { Output.err(err, "failed to copy file {}", .{bun.fmt.fmtOSPath(entry.path, .{})}); Global.crash(); }; - }; + }); defer outfile.close(); defer node_.completeOne(); - var infile = try entry.dir.openFile(entry.basename, .{ .mode = .read_only }); + const infile = bun.FD.fromStdFile(try entry.dir.openFile(entry.basename, .{ .mode = .read_only })); defer infile.close(); // Assumption: you only really care about making sure something that was executable is still executable - switch (bun.sys.fstat(bun.toFD(infile.handle))) { + switch (infile.stat()) { .err => {}, .result => |stat| { - _ = bun.sys.fchmod(bun.toFD(outfile.handle), @intCast(stat.mode)); + _ = outfile.chmod(@intCast(stat.mode)); }, } - CopyFile.copyFile(infile.handle, outfile.handle).unwrap() catch |err| { + CopyFile.copyFile(infile, outfile).unwrap() catch |err| { node_.end(); progress_.refresh(); Output.err(err, "failed to copy file {}", .{bun.fmt.fmtOSPath(entry.path, .{})}); @@ -1429,7 +1429,7 @@ pub const CreateCommand = struct { package_json_expr.data.e_object.properties = js_ast.G.Property.List.init(package_json_expr.data.e_object.properties.ptr[0..property_i]); } - const file = package_json_file.?; + const file: bun.FD = .fromStdFile(package_json_file.?); var buffer_writer = JSPrinter.BufferWriter.init(bun.default_allocator); buffer_writer.append_newline = true; @@ -1446,14 +1446,13 @@ pub const CreateCommand = struct { package_json_file = null; break :process_package_json; }; - const fd = bun.toFD(file); const written = package_json_writer.ctx.getWritten(); - bun.sys.File.writeAll(.{ .handle = fd }, written).unwrap() catch |err| { + bun.sys.File.writeAll(.{ .handle = file }, written).unwrap() catch |err| { Output.prettyErrorln("package.json failed to write due to error {s}", .{@errorName(err)}); package_json_file = null; break :process_package_json; }; - bun.sys.ftruncate(fd, @intCast(written.len)).unwrap() catch |err| { + file.truncate(@intCast(written.len)).unwrap() catch |err| { Output.prettyErrorln("package.json failed to write due to error {s}", .{@errorName(err)}); package_json_file = null; break :process_package_json; @@ -1741,7 +1740,7 @@ pub const CreateCommand = struct { const outdir_path_ = home_dir_buf[0..outdir_path.len :0]; if (bun.path.hasAnyIllegalChars(outdir_path_)) break :outer; - if (bun.sys.existsAtType(bun.toFD(std.fs.cwd()), outdir_path_).asValue()) |exists_at_type| { + if (bun.FD.cwd().existsAtType(outdir_path_).asValue()) |exists_at_type| { if (exists_at_type == .file) { const extension = std.fs.path.extension(positional); if (Example.Tag.fromFileExtension(extension)) |tag| { @@ -1765,7 +1764,7 @@ pub const CreateCommand = struct { home_dir_buf[outdir_path.len] = 0; const outdir_path_ = home_dir_buf[0..outdir_path.len :0]; if (bun.path.hasAnyIllegalChars(outdir_path_)) break :outer; - if (bun.sys.directoryExistsAt(bun.toFD(std.fs.cwd()), outdir_path_).isTrue()) { + if (bun.FD.cwd().directoryExistsAt(outdir_path_).isTrue()) { example_tag = Example.Tag.local_folder; break :brk outdir_path; } @@ -1778,7 +1777,7 @@ pub const CreateCommand = struct { home_dir_buf[outdir_path.len] = 0; const outdir_path_ = home_dir_buf[0..outdir_path.len :0]; if (bun.path.hasAnyIllegalChars(outdir_path_)) break :outer; - if (bun.sys.directoryExistsAt(bun.toFD(std.fs.cwd()), outdir_path_).isTrue()) { + if (bun.FD.cwd().directoryExistsAt(outdir_path_).isTrue()) { example_tag = Example.Tag.local_folder; break :brk outdir_path; } @@ -1791,7 +1790,7 @@ pub const CreateCommand = struct { home_dir_buf[outdir_path.len] = 0; const outdir_path_ = home_dir_buf[0..outdir_path.len :0]; if (bun.path.hasAnyIllegalChars(outdir_path_)) break :outer; - if (bun.sys.directoryExistsAt(bun.toFD(std.fs.cwd()), outdir_path_).isTrue()) { + if (bun.FD.cwd().directoryExistsAt(outdir_path_).isTrue()) { example_tag = Example.Tag.local_folder; break :brk outdir_path; } @@ -1911,26 +1910,26 @@ pub const Example = struct { var examples = std.ArrayList(Example).fromOwnedSlice(ctx.allocator, remote_examples); { var folders = [3]std.fs.Dir{ - bun.invalid_fd.asDir(), - bun.invalid_fd.asDir(), - bun.invalid_fd.asDir(), + bun.invalid_fd.stdDir(), + bun.invalid_fd.stdDir(), + bun.invalid_fd.stdDir(), }; if (env_loader.map.get("BUN_CREATE_DIR")) |home_dir| { var parts = [_]string{home_dir}; const outdir_path = filesystem.absBuf(&parts, &home_dir_buf); - folders[0] = std.fs.cwd().openDir(outdir_path, .{}) catch bun.invalid_fd.asDir(); + folders[0] = std.fs.cwd().openDir(outdir_path, .{}) catch bun.invalid_fd.stdDir(); } { var parts = [_]string{ filesystem.top_level_dir, BUN_CREATE_DIR }; const outdir_path = filesystem.absBuf(&parts, &home_dir_buf); - folders[1] = std.fs.cwd().openDir(outdir_path, .{}) catch bun.invalid_fd.asDir(); + folders[1] = std.fs.cwd().openDir(outdir_path, .{}) catch bun.invalid_fd.stdDir(); } if (env_loader.map.get(bun.DotEnv.home_env)) |home_dir| { var parts = [_]string{ home_dir, BUN_CREATE_DIR }; const outdir_path = filesystem.absBuf(&parts, &home_dir_buf); - folders[2] = std.fs.cwd().openDir(outdir_path, .{}) catch bun.invalid_fd.asDir(); + folders[2] = std.fs.cwd().openDir(outdir_path, .{}) catch bun.invalid_fd.stdDir(); } // subfolders with package.json diff --git a/src/cli/discord_command.zig b/src/cli/discord_command.zig index 06fff1238f..2bcdb456e4 100644 --- a/src/cli/discord_command.zig +++ b/src/cli/discord_command.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/src/cli/exec_command.zig b/src/cli/exec_command.zig index 13a76166c4..1644fa312a 100644 --- a/src/cli/exec_command.zig +++ b/src/cli/exec_command.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/src/cli/filter_arg.zig b/src/cli/filter_arg.zig index 8e7a0285a0..49e8702ce0 100644 --- a/src/cli/filter_arg.zig +++ b/src/cli/filter_arg.zig @@ -1,6 +1,5 @@ const std = @import("std"); -const root = @import("root"); -const bun = root.bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/src/cli/filter_run.zig b/src/cli/filter_run.zig index 6fc5c53f0b..3b2c0e597c 100644 --- a/src/cli/filter_run.zig +++ b/src/cli/filter_run.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const Output = bun.Output; const Global = bun.Global; const Environment = bun.Environment; @@ -430,7 +430,7 @@ const AbortHandler = struct { }; fn windowsIsTerminal() bool { - const res = bun.windows.GetFileType(bun.STDOUT_FD.cast()); + const res = bun.windows.GetFileType(bun.FD.stdout().native()); return res == bun.windows.FILE_TYPE_CHAR; } @@ -470,7 +470,7 @@ pub fn runScriptsWithFilter(ctx: Command.Context) !noreturn { const dirpath = std.fs.path.dirname(package_json_path) orelse Global.crash(); const path = bun.strings.withoutTrailingSlash(dirpath); - const pkgjson = bun.PackageJSON.parse(&this_transpiler.resolver, dirpath, .zero, null, .include_scripts, .main) orelse { + const pkgjson = bun.PackageJSON.parse(&this_transpiler.resolver, dirpath, .invalid, null, .include_scripts, .main) orelse { Output.warn("Failed to read package.json\n", .{}); continue; }; diff --git a/src/cli/init_command.zig b/src/cli/init_command.zig index c0e5263eff..3a7979afe3 100644 --- a/src/cli/init_command.zig +++ b/src/cli/init_command.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; @@ -41,11 +41,11 @@ pub const InitCommand = struct { // unset `ENABLE_VIRTUAL_TERMINAL_INPUT` on windows. This prevents backspace from // deleting the entire line const original_mode: if (Environment.isWindows) ?bun.windows.DWORD else void = if (comptime Environment.isWindows) - bun.win32.updateStdioModeFlags(0, .{ .unset = bun.windows.ENABLE_VIRTUAL_TERMINAL_INPUT }) catch null; + bun.win32.updateStdioModeFlags(.std_in, .{ .unset = bun.windows.ENABLE_VIRTUAL_TERMINAL_INPUT }) catch null; defer if (comptime Environment.isWindows) { if (original_mode) |mode| { - _ = bun.windows.SetConsoleMode(bun.win32.STDIN_FD.cast(), mode); + _ = bun.windows.SetConsoleMode(bun.FD.stdin().native(), mode); } }; @@ -206,7 +206,7 @@ pub const InitCommand = struct { // Set raw mode to read single characters without echo const original_mode: if (Environment.isWindows) ?bun.windows.DWORD else void = if (comptime Environment.isWindows) - bun.win32.updateStdioModeFlags(0, .{ + bun.win32.updateStdioModeFlags(.std_in, .{ // virtual terminal input enables arrow keys, processed input lets ctrl+c kill the program .set = bun.windows.ENABLE_VIRTUAL_TERMINAL_INPUT | bun.windows.ENABLE_PROCESSED_INPUT, // disabling line input sends keys immediately, disabling echo input makes sure it doesn't print to the terminal @@ -220,7 +220,7 @@ pub const InitCommand = struct { if (comptime Environment.isWindows) { if (original_mode) |mode| { _ = bun.windows.SetConsoleMode( - bun.win32.STDIN_FD.cast(), + bun.FD.stdin().native(), mode, ); } @@ -757,8 +757,8 @@ pub const InitCommand = struct { } write_package_json: { - var file = package_json_file orelse try std.fs.cwd().createFileZ("package.json", .{}); - defer file.close(); + var fd = bun.FD.fromStdFile(package_json_file orelse try std.fs.cwd().createFileZ("package.json", .{})); + defer fd.close(); var buffer_writer = JSPrinter.BufferWriter.init(bun.default_allocator); buffer_writer.append_newline = true; var package_json_writer = JSPrinter.BufferPrinter.init(buffer_writer); @@ -774,7 +774,6 @@ pub const InitCommand = struct { package_json_file = null; break :write_package_json; }; - const fd = bun.toFD(file); const written = package_json_writer.ctx.getWritten(); bun.sys.File.writeAll(.{ .handle = fd }, written).unwrap() catch |err| { Output.prettyErrorln("package.json failed to write due to error {s}", .{@errorName(err)}); diff --git a/src/cli/install_command.zig b/src/cli/install_command.zig index ca69c32e46..aff3fcad86 100644 --- a/src/cli/install_command.zig +++ b/src/cli/install_command.zig @@ -1,5 +1,5 @@ const Command = @import("../cli.zig").Command; -const bun = @import("root").bun; +const bun = @import("bun"); const PackageManager = @import("../install/install.zig").PackageManager; pub const InstallCommand = struct { diff --git a/src/cli/install_completions_command.zig b/src/cli/install_completions_command.zig index 28109a6131..0c0db9366b 100644 --- a/src/cli/install_completions_command.zig +++ b/src/cli/install_completions_command.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; @@ -467,7 +467,7 @@ pub const InstallCompletionsCommand = struct { // Check if they need to load the zsh completions file into their .zshrc if (shell == .zsh) { var completions_absolute_path_buf: bun.PathBuffer = undefined; - const completions_path = bun.getFdPath(output_file.handle, &completions_absolute_path_buf) catch unreachable; + const completions_path = bun.getFdPath(.fromStdFile(output_file), &completions_absolute_path_buf) catch unreachable; var zshrc_filepath: bun.PathBuffer = undefined; const needs_to_tell_them_to_add_completions_file = brk: { var dot_zshrc: std.fs.File = zshrc: { diff --git a/src/cli/list-of-yarn-commands.zig b/src/cli/list-of-yarn-commands.zig index 647cf2d29d..ca18c7ee56 100644 --- a/src/cli/list-of-yarn-commands.zig +++ b/src/cli/list-of-yarn-commands.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); pub const all_yarn_commands = bun.ComptimeStringMap(void, .{ // yarn v2.3 commands diff --git a/src/cli/outdated_command.zig b/src/cli/outdated_command.zig index 012cb1ea7d..404e6623e1 100644 --- a/src/cli/outdated_command.zig +++ b/src/cli/outdated_command.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Global = bun.Global; const Output = bun.Output; const Command = bun.CLI.Command; diff --git a/src/cli/pack_command.zig b/src/cli/pack_command.zig index 63e114b4fd..55113bcd8e 100644 --- a/src/cli/pack_command.zig +++ b/src/cli/pack_command.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Global = bun.Global; const Output = bun.Output; const Command = bun.CLI.Command; @@ -1623,17 +1623,17 @@ pub const PackCommand = struct { while (pack_queue.removeOrNull()) |pathname| { defer if (log_level.showProgress()) node.completeOne(); - const file = bun.sys.openat(bun.toFD(root_dir.fd), pathname, bun.O.RDONLY, 0).unwrap() catch |err| { + const file = bun.sys.openat(.fromStdDir(root_dir), pathname, bun.O.RDONLY, 0).unwrap() catch |err| { Output.err(err, "failed to open file: \"{s}\"", .{pathname}); Global.crash(); }; - const fd = bun.sys.toLibUVOwnedFD(file, .open, .close_on_fail).unwrap() catch |err| { + const fd = file.makeLibUVOwnedForSyscall(.open, .close_on_fail).unwrap() catch |err| { Output.err(err, "failed to open file: \"{s}\"", .{pathname}); Global.crash(); }; - defer _ = bun.sys.close(fd); + defer fd.close(); const stat = bun.sys.sys_uv.fstat(fd).unwrap() catch |err| { Output.err(err, "failed to stat file: \"{s}\"", .{pathname}); @@ -1659,7 +1659,7 @@ pub const PackCommand = struct { while (bundled_pack_queue.removeOrNull()) |pathname| { defer if (log_level.showProgress()) node.completeOne(); - const file = File.openat(root_dir, pathname, bun.O.RDONLY, 0).unwrap() catch |err| { + const file = File.openat(.fromStdDir(root_dir), pathname, bun.O.RDONLY, 0).unwrap() catch |err| { Output.err(err, "failed to open file: \"{s}\"", .{pathname}); Global.crash(); }; @@ -1945,7 +1945,7 @@ pub const PackCommand = struct { root_dir: std.fs.Dir, edited_package_json: string, ) OOM!*Archive.Entry { - const stat = bun.sys.fstatat(bun.toFD(root_dir), "package.json").unwrap() catch |err| { + const stat = bun.sys.fstatat(.fromStdDir(root_dir), "package.json").unwrap() catch |err| { Output.err(err, "failed to stat package.json", .{}); Global.crash(); }; @@ -2279,7 +2279,7 @@ pub const PackCommand = struct { default, @".npmignore", @".gitignore", - /// Exlusion pattern in "files" field within `package.json` + /// Exclusion pattern in "files" field within `package.json` @"package.json", }; @@ -2287,7 +2287,7 @@ pub const PackCommand = struct { fn ignoreFileFail(dir: std.fs.Dir, ignore_kind: Kind, reason: enum { read, open }, err: anyerror) noreturn { var buf: PathBuffer = undefined; - const dir_path = bun.getFdPath(dir, &buf) catch ""; + const dir_path = bun.getFdPath(.fromStdDir(dir), &buf) catch ""; Output.err(err, "failed to {s} {s} at: \"{s}{s}{s}\"", .{ @tagName(reason), @tagName(ignore_kind), @@ -2384,16 +2384,17 @@ pub const PackCommand = struct { fn printArchivedFilesAndPackages( ctx: *Context, - root_dir: std.fs.Dir, + root_dir_std: std.fs.Dir, comptime is_dry_run: bool, pack_list: if (is_dry_run) *PackQueue else PackList, package_json_len: usize, ) void { + const root_dir = bun.FD.fromStdDir(root_dir_std); if (ctx.manager.options.log_level == .silent) return; const packed_fmt = "packed {} {s}"; if (comptime is_dry_run) { - const package_json_stat = bun.sys.fstatat(bun.toFD(root_dir), "package.json").unwrap() catch |err| { + const package_json_stat = root_dir.statat("package.json").unwrap() catch |err| { Output.err(err, "failed to stat package.json", .{}); Global.crash(); }; @@ -2406,7 +2407,7 @@ pub const PackCommand = struct { }); while (pack_list.removeOrNull()) |filename| { - const stat = bun.sys.fstatat(bun.toFD(root_dir), filename).unwrap() catch |err| { + const stat = root_dir.statat(filename).unwrap() catch |err| { Output.err(err, "failed to stat file: \"{s}\"", .{filename}); Global.crash(); }; diff --git a/src/cli/package_manager_command.zig b/src/cli/package_manager_command.zig index 16a8a3f570..bef08d80e9 100644 --- a/src/cli/package_manager_command.zig +++ b/src/cli/package_manager_command.zig @@ -1,6 +1,6 @@ const std = @import("std"); const Progress = std.Progress; -const bun = @import("root").bun; +const bun = @import("bun"); const Global = bun.Global; const Output = bun.Output; const string = bun.string; @@ -247,7 +247,7 @@ pub const PackageManagerCommand = struct { } else if (strings.eqlComptime(subcommand, "cache")) { var dir: bun.PathBuffer = undefined; var fd = pm.getCacheDirectory(); - const outpath = bun.getFdPath(fd.fd, &dir) catch |err| { + const outpath = bun.getFdPath(.fromStdDir(fd), &dir) catch |err| { Output.prettyErrorln("{s} getting cache directory", .{@errorName(err)}); Global.crash(); }; diff --git a/src/cli/patch_command.zig b/src/cli/patch_command.zig index 9e56506345..4c9c7333d7 100644 --- a/src/cli/patch_command.zig +++ b/src/cli/patch_command.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const Command = @import("../cli.zig").Command; const PackageManager = @import("../install/install.zig").PackageManager; diff --git a/src/cli/patch_commit_command.zig b/src/cli/patch_commit_command.zig index af44f76241..7f6cbfe797 100644 --- a/src/cli/patch_commit_command.zig +++ b/src/cli/patch_commit_command.zig @@ -1,6 +1,6 @@ const Command = @import("../cli.zig").Command; const PackageManager = @import("../install/install.zig").PackageManager; -const bun = @import("root").bun; +const bun = @import("bun"); pub const PatchCommitCommand = struct { pub fn exec(ctx: Command.Context) !void { diff --git a/src/cli/pm_trusted_command.zig b/src/cli/pm_trusted_command.zig index 6361fc0971..b5a672af97 100644 --- a/src/cli/pm_trusted_command.zig +++ b/src/cli/pm_trusted_command.zig @@ -1,6 +1,6 @@ const std = @import("std"); const Progress = bun.Progress; -const bun = @import("root").bun; +const bun = @import("bun"); const logger = bun.logger; const Environment = bun.Environment; const Command = @import("../cli.zig").Command; diff --git a/src/cli/publish_command.zig b/src/cli/publish_command.zig index a87e32b858..ae79a19294 100644 --- a/src/cli/publish_command.zig +++ b/src/cli/publish_command.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Command = bun.CLI.Command; const Output = bun.Output; const Global = bun.Global; @@ -680,11 +680,11 @@ pub const PublishCommand = struct { // unset `ENABLE_VIRTUAL_TERMINAL_INPUT` on windows. This prevents backspace from // deleting the entire line const original_mode: if (Environment.isWindows) ?bun.windows.DWORD else void = if (comptime Environment.isWindows) - bun.win32.updateStdioModeFlags(0, .{ .unset = bun.windows.ENABLE_VIRTUAL_TERMINAL_INPUT }) catch null; + bun.win32.updateStdioModeFlags(.std_in, .{ .unset = bun.windows.ENABLE_VIRTUAL_TERMINAL_INPUT }) catch null; defer if (comptime Environment.isWindows) { if (original_mode) |mode| { - _ = bun.windows.SetConsoleMode(bun.win32.STDIN_FD.cast(), mode); + _ = bun.windows.SetConsoleMode(bun.FD.stdin().native(), mode); } }; @@ -951,7 +951,7 @@ pub const PublishCommand = struct { Output.err(err, "failed to open workspace directory", .{}); Global.crash(); }; - defer _ = bun.sys.close(workspace_root); + defer workspace_root.close(); try normalizeBin( allocator, @@ -1145,7 +1145,7 @@ pub const PublishCommand = struct { var dirs: std.ArrayListUnmanaged(struct { std.fs.Dir, string, bool }) = .{}; defer dirs.deinit(allocator); - try dirs.append(allocator, .{ bin_dir.asDir(), normalized_bin_dir, false }); + try dirs.append(allocator, .{ bin_dir.stdDir(), normalized_bin_dir, false }); while (dirs.pop()) |dir_info| { var dir, const dir_subpath, const close_dir = dir_info; diff --git a/src/cli/run_command.zig b/src/cli/run_command.zig index 74d0233ff3..7043f9b7da 100644 --- a/src/cli/run_command.zig +++ b/src/cli/run_command.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const Async = bun.Async; const string = bun.string; const Output = bun.Output; @@ -327,10 +327,10 @@ pub const RunCommand = struct { copy_script.items, }; - const ipc_fd = if (!Environment.isWindows) blk: { + const ipc_fd: ?bun.FD = if (!Environment.isWindows) blk: { const node_ipc_fd = bun.getenvZ("NODE_CHANNEL_FD") orelse break :blk null; - const fd = std.fmt.parseInt(u32, node_ipc_fd, 10) catch break :blk null; - break :blk bun.toFD(@as(i32, @intCast(fd))); + const fd = std.fmt.parseInt(u31, node_ipc_fd, 10) catch break :blk null; + break :blk bun.FD.fromNative(fd); } else null; // TODO: implement on Windows const spawn_result = switch ((bun.spawnSync(&.{ @@ -1288,7 +1288,7 @@ pub const RunCommand = struct { // TODO: optimize this pass for Windows. we can make better use of system apis available var file_path = script_name_to_search; { - const file = bun.toLibUVOwnedFD(((brk: { + const file = bun.FD.fromStdFile((brk: { if (std.fs.path.isAbsolute(script_name_to_search)) { var win_resolver = resolve_path.PosixToWinNormalizer{}; var resolved = win_resolver.resolveCWD(script_name_to_search) catch @panic("Could not resolve path"); @@ -1323,8 +1323,8 @@ pub const RunCommand = struct { const file_pathZ = script_name_buf[0..file_path.len :0]; break :brk bun.openFileZ(file_pathZ, .{ .mode = .read_only }); } - }) catch return false).handle) catch return false; - defer _ = bun.sys.close(file); + }) catch return false).makeLibUVOwnedForSyscall(.open, .close_on_fail).unwrap() catch return false; + defer file.close(); switch (bun.sys.fstat(file)) { .result => |stat| { @@ -1741,7 +1741,7 @@ pub const BunXFastPath = struct { }; if (Environment.isDebug) { - debug("run_ctx.handle: '{}'", .{bun.FDImpl.fromSystem(handle)}); + debug("run_ctx.handle: '{}'", .{bun.FD.fromSystem(handle)}); debug("run_ctx.base_path: '{}'", .{bun.fmt.utf16(run_ctx.base_path)}); debug("run_ctx.arguments: '{}'", .{bun.fmt.utf16(run_ctx.arguments)}); debug("run_ctx.force_use_bun: '{}'", .{run_ctx.force_use_bun}); diff --git a/src/cli/shell_completions.zig b/src/cli/shell_completions.zig index 7468104997..383961b616 100644 --- a/src/cli/shell_completions.zig +++ b/src/cli/shell_completions.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/src/cli/test/Scanner.zig b/src/cli/test/Scanner.zig index 087f36e9c4..15b5a7025f 100644 --- a/src/cli/test/Scanner.zig +++ b/src/cli/test/Scanner.zig @@ -1,7 +1,7 @@ const Scanner = @This(); const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const BundleOptions = @import("../../options.zig").BundleOptions; const Allocator = std.mem.Allocator; @@ -102,9 +102,9 @@ pub fn scan(this: *Scanner, path_literal: []const u8) Error!void { } while (this.dirs_to_scan.readItem()) |entry| { + bun.assert(entry.relative_dir.isValid()); if (!bun.Environment.isWindows) { - const dir = entry.relative_dir.asDir(); - bun.assert(bun.toFD(dir.fd) != bun.invalid_fd); + const dir = entry.relative_dir.stdDir(); const parts2 = &[_][]const u8{ entry.dir_path, entry.name.slice() }; var path2 = this.fs.absBuf(parts2, &this.open_dir_buf); @@ -115,9 +115,6 @@ pub fn scan(this: *Scanner, path_literal: []const u8) Error!void { FileSystem.setMaxFd(child_dir.fd); _ = this.readDirWithName(path2, child_dir) catch return error.OutOfMemory; } else { - const dir = entry.relative_dir.asDir(); - bun.assert(bun.toFD(dir.fd) != bun.invalid_fd); - const parts2 = &[_][]const u8{ entry.dir_path, entry.name.slice() }; const path2 = this.fs.absBufZ(parts2, &this.open_dir_buf); const child_dir = bun.openDirNoRenamingOrDeletingWindows(bun.invalid_fd, path2) catch continue; diff --git a/src/cli/test_command.zig b/src/cli/test_command.zig index 091359cb57..5858407a86 100644 --- a/src/cli/test_command.zig +++ b/src/cli/test_command.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; @@ -451,7 +451,7 @@ pub const JunitReporter = struct { @memcpy(junit_path_buf[0..path.len], path); junit_path_buf[path.len] = 0; - switch (bun.sys.File.openat(std.fs.cwd(), junit_path_buf[0..path.len :0], bun.O.WRONLY | bun.O.CREAT | bun.O.TRUNC, 0o664)) { + switch (bun.sys.File.openat(.cwd(), junit_path_buf[0..path.len :0], bun.O.WRONLY | bun.O.CREAT | bun.O.TRUNC, 0o664)) { .err => |err| { Output.err(error.JUnitReportFailed, "Failed to write JUnit report to {s}\n{}", .{ path, err }); }, @@ -840,7 +840,7 @@ pub const CommandLineReporter = struct { const tmpname = std.fmt.bufPrintZ(&shortname_buf, ".lcov.info.{s}.tmp", .{std.fmt.fmtSliceHexLower(&base64_bytes)}) catch unreachable; const path = bun.path.joinAbsStringBufZ(relative_dir, &lcov_name_buf, &.{ opts.reports_directory, tmpname }, .auto); const file = bun.sys.File.openat( - std.fs.cwd(), + .cwd(), path, bun.O.CREAT | bun.O.WRONLY | bun.O.TRUNC | bun.O.CLOEXEC, 0o644, @@ -943,10 +943,11 @@ pub const CommandLineReporter = struct { if (comptime reporters.lcov) { try lcov_buffered_writer.flush(); lcov_file.close(); + const cwd = bun.FD.cwd(); bun.C.moveFileZ( - bun.toFD(std.fs.cwd()), + cwd, lcov_name, - bun.toFD(std.fs.cwd()), + cwd, bun.path.joinAbsStringZ( relative_dir, &.{ opts.reports_directory, "lcov.info" }, diff --git a/src/cli/upgrade_command.zig b/src/cli/upgrade_command.zig index 29d9a89239..79c404c974 100644 --- a/src/cli/upgrade_command.zig +++ b/src/cli/upgrade_command.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; @@ -120,6 +120,8 @@ pub const Version = struct { }; pub const UpgradeCommand = struct { + pub const Bun__githubBaselineURL = Version.Bun__githubBaselineURL; + const default_github_headers: string = "Acceptapplication/vnd.github.v3+json"; var github_repository_url_buf: bun.PathBuffer = undefined; var current_executable_buf: bun.PathBuffer = undefined; @@ -530,7 +532,7 @@ pub const UpgradeCommand = struct { Global.exit(1); }; const save_dir = save_dir_it; - const tmpdir_path = bun.getFdPath(save_dir.fd, &tmpdir_path_buf) catch |err| { + const tmpdir_path = bun.FD.fromStdDir(save_dir).getFdPath(&tmpdir_path_buf) catch |err| { Output.errGeneric("Failed to read temporary directory: {s}", .{@errorName(err)}); Global.exit(1); }; @@ -809,7 +811,7 @@ pub const UpgradeCommand = struct { current_executable_buf[target_dir_.len] = 0; } - C.moveFileZ(bun.toFD(save_dir.fd), exe, bun.toFD(target_dir.fd), target_filename) catch |err| { + C.moveFileZ(.fromStdDir(save_dir), exe, .fromStdDir(target_dir), target_filename) catch |err| { defer save_dir_.deleteTree(version_name) catch {}; if (comptime Environment.isWindows) { @@ -997,7 +999,7 @@ pub const upgrade_js_bindings = struct { ); switch (bun.windows.Win32Error.fromNTStatus(rc)) { - .SUCCESS => tempdir_fd = bun.toFD(fd), + .SUCCESS => tempdir_fd = .fromNative(fd), else => {}, } @@ -1008,7 +1010,7 @@ pub const upgrade_js_bindings = struct { if (comptime !Environment.isWindows) return .undefined; if (tempdir_fd) |fd| { - _ = bun.sys.close(fd); + fd.close(); } return .undefined; diff --git a/src/codegen/bindgen.ts b/src/codegen/bindgen.ts index 200dcf0caa..72bdd03a71 100644 --- a/src/codegen/bindgen.ts +++ b/src/codegen/bindgen.ts @@ -1125,7 +1125,7 @@ const cpp = new CodeWriter(); const cppInternal = new CodeWriter(); const headers = new Set(); -zig.line('const bun = @import("root").bun;'); +zig.line('const bun = @import("bun");'); zig.line("const JSC = bun.JSC;"); zig.line("const JSHostFunctionType = JSC.JSHostFunctionType;\n"); diff --git a/src/codegen/generate-classes.ts b/src/codegen/generate-classes.ts index 2488dfce89..4626a53f27 100644 --- a/src/codegen/generate-classes.ts +++ b/src/codegen/generate-classes.ts @@ -2119,7 +2119,7 @@ pub const ${className(typeName)} = struct { if (comptime Environment.enable_logs) log_zig_to_js("${typeName}"); if (comptime Environment.allow_assert) { const value__ = ${symbolName(typeName, "create")}(globalObject, this); - @import("root").bun.assert(value__.as(${typeName}).? == this); // If this fails, likely a C ABI issue. + @import("bun").assert(value__.as(${typeName}).? == this); // If this fails, likely a C ABI issue. return value__; } else { return ${symbolName(typeName, "create")}(globalObject, this); @@ -2329,10 +2329,15 @@ const ZIG_GENERATED_CLASSES_HEADER = ` /// - C++: ZigGeneratedClasses.h, ZigGeneratedClasses.cpp /// 4. For the Zig code to successfully compile: /// - Add it to generated_classes_list.zig -/// - pub usingnamespace JSC.Codegen.JSMyClassName; +/// - \`\`\` +/// pub const js = JSC.Codegen.JSMyClassName; +/// pub const toJS = js.toJS; +/// pub const fromJS = js.fromJS; +/// pub const fromJSDirect = js.fromJSDirect; +/// \`\`\` /// 5. bun run build /// -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const Classes = JSC.GeneratedClassesList; const Environment = bun.Environment; diff --git a/src/codegen/generate-js2native.ts b/src/codegen/generate-js2native.ts index 8b2f46bbd0..c0fe8b0658 100644 --- a/src/codegen/generate-js2native.ts +++ b/src/codegen/generate-js2native.ts @@ -209,7 +209,7 @@ export function getJS2NativeCPP() { export function getJS2NativeZig(gs2NativeZigPath: string) { return [ "//! This file is generated by src/codegen/generate-js2native.ts based on seen calls to the $zig() JS macro", - `const bun = @import("root").bun;`, + `const bun = @import("bun");`, `const JSC = bun.JSC;`, ...nativeCalls .filter(x => x.type === "zig") diff --git a/src/codegen/generate-node-errors.ts b/src/codegen/generate-node-errors.ts index b776c857da..2227f6c2ae 100644 --- a/src/codegen/generate-node-errors.ts +++ b/src/codegen/generate-node-errors.ts @@ -53,7 +53,7 @@ static constexpr ErrorCodeData errors[${count}] = { zig = ` // Generated by: src/codegen/generate-node-errors.ts const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; pub fn ErrorBuilder(comptime code: Error, comptime fmt: [:0]const u8, Args: type) type { diff --git a/src/compile_target.zig b/src/compile_target.zig index 5e4484d2b0..98216036e3 100644 --- a/src/compile_target.zig +++ b/src/compile_target.zig @@ -4,7 +4,7 @@ /// It uses npm to download the bun binary from the npm registry /// It stores the downloaded binary into the bun install cache. /// -const bun = @import("root").bun; +const bun = @import("bun"); const std = @import("std"); const Environment = bun.Environment; const strings = bun.strings; @@ -123,7 +123,7 @@ pub fn exePath(this: *const CompileTarget, buf: *bun.PathBuffer, version_str: [: return buf[0..self_exe_path.len :0]; } - if (bun.sys.existsAt(bun.toFD(std.fs.cwd()), version_str)) { + if (bun.FD.cwd().existsAt(version_str)) { needs_download.* = false; return version_str; } @@ -138,7 +138,7 @@ pub fn exePath(this: *const CompileTarget, buf: *bun.PathBuffer, version_str: [: .auto, ); - if (bun.sys.existsAt(bun.toFD(std.fs.cwd()), dest)) { + if (bun.FD.cwd().existsAt(dest)) { needs_download.* = false; } @@ -297,7 +297,7 @@ pub fn downloadToPath(this: *const CompileTarget, env: *bun.DotEnv.Loader, alloc var did_retry = false; while (true) { - bun.C.moveFileZ(bun.toFD(tmpdir), if (this.os == .windows) "bun.exe" else "bun", bun.invalid_fd, dest_z) catch |err| { + bun.C.moveFileZ(.fromStdDir(tmpdir), if (this.os == .windows) "bun.exe" else "bun", bun.invalid_fd, dest_z) catch |err| { if (!did_retry) { did_retry = true; const dirname = bun.path.dirname(dest_z, .loose); diff --git a/src/comptime_string_map.zig b/src/comptime_string_map.zig index 0093549ed8..e1205d22d2 100644 --- a/src/comptime_string_map.zig +++ b/src/comptime_string_map.zig @@ -1,6 +1,6 @@ const JSC = bun.JSC; const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const mem = std.mem; const strings = @import("./string_immutable.zig"); diff --git a/src/copy_file.zig b/src/copy_file.zig index f4f47d60bc..e3c37bc862 100644 --- a/src/copy_file.zig +++ b/src/copy_file.zig @@ -4,7 +4,7 @@ const std = @import("std"); const posix = std.posix; const math = std.math; -const bun = @import("root").bun; +const bun = @import("bun"); const strings = bun.strings; const Environment = bun.Environment; @@ -22,7 +22,7 @@ pub const CopyFileRangeError = error{ FileBusy, } || posix.PReadError || posix.PWriteError || posix.UnexpectedError; -const InputType = if (Environment.isWindows) bun.OSPathSliceZ else posix.fd_t; +const InputType = if (Environment.isWindows) bun.OSPathSliceZ else bun.FD; /// In a `bun install` with prisma, this reduces the system call count from ~18,000 to ~12,000 /// @@ -61,7 +61,7 @@ const CopyFileReturnType = bun.sys.Maybe(void); pub fn copyFileWithState(in: InputType, out: InputType, copy_file_state: *CopyFileState) CopyFileReturnType { if (comptime Environment.isMac) { - const rc = posix.system.fcopyfile(in, out, null, posix.system.COPYFILE{ .DATA = true }); + const rc = posix.system.fcopyfile(in.native(), out.native(), null, posix.system.COPYFILE{ .DATA = true }); switch (posix.errno(rc)) { .SUCCESS => return CopyFileReturnType.success, @@ -76,9 +76,9 @@ pub fn copyFileWithState(in: InputType, out: InputType, copy_file_state: *CopyFi if (can_use_ioctl_ficlone() and !copy_file_state.has_seen_exdev and !copy_file_state.has_ioctl_ficlone_failed) { // We only check once if the ioctl is supported, and cache the result. // EXT4 does not support FICLONE. - const rc = bun.C.linux.ioctl_ficlone(bun.toFD(out), bun.toFD(in)); + const rc = bun.C.linux.ioctl_ficlone(out, in); // the ordering is flipped but it is consistent with other system calls. - bun.sys.syslog("ioctl_ficlone({d}, {d}) = {d}", .{ in, out, rc }); + bun.sys.syslog("ioctl_ficlone({}, {}) = {d}", .{ in, out, rc }); switch (bun.C.getErrno(rc)) { .SUCCESS => return CopyFileReturnType.success, .XDEV => { @@ -107,7 +107,7 @@ pub fn copyFileWithState(in: InputType, out: InputType, copy_file_state: *CopyFi // The kernel checks the u64 value `offset+count` for overflow, use // a 32 bit value so that the syscall won't return EINVAL except for // impossibly large files (> 2^64-1 - 2^32-1). - const amt = switch (copyFileRange(in, out, math.maxInt(i32) - 1, 0, copy_file_state)) { + const amt = switch (copyFileRange(in.native(), out.native(), math.maxInt(i32) - 1, 0, copy_file_state)) { .result => |a| a, .err => |err| return .{ .err = err }, }; @@ -127,7 +127,7 @@ pub fn copyFileWithState(in: InputType, out: InputType, copy_file_state: *CopyFi } while (true) { - switch (copyFileReadWriteLoop(in, out, math.maxInt(i32) - 1)) { + switch (copyFileReadWriteLoop(in.native(), out.native(), math.maxInt(i32) - 1)) { .err => |err| return .{ .err = err }, .result => |amt| { if (amt == 0) break; @@ -280,13 +280,13 @@ pub fn copyFileReadWriteLoop( ) Maybe(usize) { var buf: [8 * 4096]u8 = undefined; const adjusted_count = @min(buf.len, len); - switch (bun.sys.read(bun.toFD(in), buf[0..adjusted_count])) { + switch (bun.sys.read(.fromNative(in), buf[0..adjusted_count])) { .result => |amt_read| { var amt_written: usize = 0; if (amt_read == 0) return .{ .result = 0 }; while (amt_written < amt_read) { - switch (bun.sys.write(bun.toFD(out), buf[amt_written..amt_read])) { + switch (bun.sys.write(.fromNative(out), buf[amt_written..amt_read])) { .result => |wrote| { if (wrote == 0) { return .{ .result = amt_written }; diff --git a/src/crash_handler.zig b/src/crash_handler.zig index e8cef84648..b3c6034834 100644 --- a/src/crash_handler.zig +++ b/src/crash_handler.zig @@ -18,7 +18,7 @@ //! A lot of this handler is based on the Zig Standard Library implementation //! for std.debug.panicImpl and their code for gathering backtraces. const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const builtin = @import("builtin"); const mimalloc = @import("allocators/mimalloc.zig"); const SourceMap = @import("./sourcemap/sourcemap.zig"); @@ -1415,9 +1415,9 @@ fn report(url: []const u8) void { .hStdInput = null, .hStdOutput = null, .hStdError = null, - // .hStdInput = bun.win32.STDIN_FD.cast(), - // .hStdOutput = bun.win32.STDOUT_FD.cast(), - // .hStdError = bun.win32.STDERR_FD.cast(), + // .hStdInput = bun.FD.stdin().native(), + // .hStdOutput = bun.FD.stdout().native(), + // .hStdError = bun.FD.stderr().native(), }; var cmd_line = std.BoundedArray(u16, 4096){}; cmd_line.appendSliceAssumeCapacity(std.unicode.utf8ToUtf16LeStringLiteral("powershell -ExecutionPolicy Bypass -Command \"try{Invoke-RestMethod -Uri '")); diff --git a/src/create/SourceFileProjectGenerator.zig b/src/create/SourceFileProjectGenerator.zig index 0bca6ee48f..dc532afcc9 100644 --- a/src/create/SourceFileProjectGenerator.zig +++ b/src/create/SourceFileProjectGenerator.zig @@ -79,7 +79,7 @@ pub fn generate(_: Command.Context, _: Example.Tag, entry_point: string, result: // Create a file with given contents, returns if file was newly created fn createFile(filename: []const u8, contents: []const u8) bun.JSC.Maybe(bool) { // Check if file exists and has same contents - if (bun.sys.File.readFrom(bun.toFD(std.fs.cwd()), filename, default_allocator).asValue()) |source_contents| { + if (bun.sys.File.readFrom(bun.FD.cwd(), filename, default_allocator).asValue()) |source_contents| { defer default_allocator.free(source_contents); if (strings.eqlLong(source_contents, contents, true)) { return .{ .result = false }; @@ -92,11 +92,11 @@ fn createFile(filename: []const u8, contents: []const u8) bun.JSC.Maybe(bool) { } // Open file for writing - const fd = switch (bun.sys.openatA(bun.toFD(std.fs.cwd()), filename, bun.O.WRONLY | bun.O.CREAT | bun.O.TRUNC, 0o644)) { + const fd = switch (bun.sys.openatA(.cwd(), filename, bun.O.WRONLY | bun.O.CREAT | bun.O.TRUNC, 0o644)) { .result => |fd| fd, .err => |err| return .{ .err = err }, }; - defer _ = bun.sys.close(fd); + defer fd.close(); // Write contents switch (bun.sys.File.writeAll(.{ .handle = fd }, contents)) { @@ -616,7 +616,7 @@ fn findReactComponentExport(bundler: *BundleV2) ?[]const u8 { return null; } -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/src/csrf.zig b/src/csrf.zig index a4305375f5..c150e35255 100644 --- a/src/csrf.zig +++ b/src/csrf.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const std = @import("std"); const JSC = bun.JSC; const boring = bun.BoringSSL.c; diff --git a/src/css/build-prefixes.js b/src/css/build-prefixes.js index bd799194c2..91f399e208 100644 --- a/src/css/build-prefixes.js +++ b/src/css/build-prefixes.js @@ -513,20 +513,12 @@ let enumify = f => .replace(/(^|-)([a-z])/g, (_, a, x) => (a === "-" ? "_" + x : x)), ); -let allBrowsers = Object.keys(browsers) - .filter(b => !(b in BROWSER_MAPPING)) - .sort(); -let browsersZig = `pub const Browsers = struct { - ${allBrowsers.join(": ?u32 = null,\n")}: ?u32 = null, - pub usingnamespace BrowsersImpl(@This()); -}`; let field_len = 0; let flagsZig = `pub const Features = packed struct(u32) { ${flags .map((flag, i) => { if (Array.isArray(flag)) { - // return `const ${flag[0]} = ${flag[1].map(f => `Self::${f}.bits()`).join(" | ")};`; - return `pub const ${flag[0]} = Features.fromNames(&.{${flag[1].map(f => `"${f}"`).join(", ")}});`; + return `pub const ${flag[0]}: @This() = .{${flag[1].map(f => `.${f} = true,`).join("")}};`; } else { field_len++; return `${flag}: bool = false,`; @@ -541,14 +533,10 @@ let flagsZig = `pub const Features = packed struct(u32) { return 0; }) .join("\n ")} - - pub usingnamespace css.Bitflags(@This()); - pub usingnamespace FeaturesImpl(@This()); }`; let targets = fs .readFileSync("src/css/targets.zig", "utf8") - .replace(/pub const Browsers = struct \{((?:.|\n)+?)\}/, browsersZig) - .replace(/pub const Features = packed struct\(u32\) \{((?:.|\n)+?)\}/, flagsZig); + .replace(/pub const Features = packed struct\(u32\) \{((?:.|\n)+?)\n\}/, flagsZig); console.log("TARGETS", targets); fs.writeFileSync("src/css/targets.zig", targets); diff --git a/src/css/context.zig b/src/css/context.zig index 7a76deafba..100300ecaf 100644 --- a/src/css/context.zig +++ b/src/css/context.zig @@ -1,6 +1,6 @@ const std = @import("std"); const Allocator = std.mem.Allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const logger = bun.logger; const Log = logger.Log; diff --git a/src/css/css_internals.zig b/src/css/css_internals.zig index af046a7093..e9b69ffdc2 100644 --- a/src/css/css_internals.zig +++ b/src/css/css_internals.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const std = @import("std"); const builtin = @import("builtin"); const Arena = @import("../allocators/mimalloc_arena.zig").Arena; @@ -169,9 +169,7 @@ fn parserOptionsFromJS(globalThis: *JSC.JSGlobalObject, allocator: Allocator, op const str = bunstr.toUTF8(bun.default_allocator); defer str.deinit(); if (std.mem.eql(u8, str.slice(), "DEEP_SELECTOR_COMBINATOR")) { - opts.flags.insert(bun.css.ParserFlags{ - .deep_selector_combinator = true, - }); + opts.flags.deep_selector_combinator = true; } else { return globalThis.throw("invalid flag: {s}", .{str.slice()}); } diff --git a/src/css/css_modules.zig b/src/css/css_modules.zig index c81f8cc9ed..0ba43a4ae4 100644 --- a/src/css/css_modules.zig +++ b/src/css/css_modules.zig @@ -1,6 +1,6 @@ const std = @import("std"); const Allocator = std.mem.Allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const logger = bun.logger; const Log = logger.Log; diff --git a/src/css/css_parser.zig b/src/css/css_parser.zig index 639a6b3546..78c1387377 100644 --- a/src/css/css_parser.zig +++ b/src/css/css_parser.zig @@ -1,6 +1,6 @@ const std = @import("std"); const Allocator = std.mem.Allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const logger = bun.logger; const Log = logger.Log; @@ -139,7 +139,6 @@ pub fn OOM(e: anyerror) noreturn { } pub const SmallList = @import("./small_list.zig").SmallList; -pub const Bitflags = bun.Bitflags; pub const todo_stuff = struct { pub const think_mem_mgmt = "TODO: think about memory management"; @@ -173,6 +172,15 @@ pub const VendorPrefix = packed struct(u8) { o: bool = false, __unused: u3 = 0, + pub const empty = VendorPrefix{}; + pub const all = VendorPrefix{ + .none = true, + .moz = true, + .ms = true, + .o = true, + .webkit = true, + }; + pub const NONE = VendorPrefix{ .none = true }; pub const WEBKIT = VendorPrefix{ .webkit = true }; pub const MOZ = VendorPrefix{ .moz = true }; @@ -182,8 +190,6 @@ pub const VendorPrefix = packed struct(u8) { /// Fields listed here so we can iterate them in the order we want pub const FIELDS: []const []const u8 = &.{ "webkit", "moz", "ms", "o", "none" }; - pub usingnamespace Bitflags(@This()); - pub fn toCss(this: *const VendorPrefix, comptime W: type, dest: *Printer(W)) PrintErr!void { return switch (this.asBits()) { VendorPrefix.asBits(.{ .webkit = true }) => dest.writeStr("-webkit-"), @@ -194,6 +200,14 @@ pub const VendorPrefix = packed struct(u8) { }; } + pub inline fn fromName(comptime name: []const u8) VendorPrefix { + comptime { + var vp: VendorPrefix = .{}; + @field(vp, name) = true; + return vp; + } + } + /// Returns VendorPrefix::None if empty. pub inline fn orNone(this: VendorPrefix) VendorPrefix { return this._or(VendorPrefix{ .none = true }); @@ -204,6 +218,22 @@ pub const VendorPrefix = packed struct(u8) { if (this.isEmpty()) return other; return this; } + + pub fn difference(left: @This(), right: @This()) @This() { + return @bitCast(@as(u8, @bitCast(left)) - @as(u8, @bitCast(right))); + } + + pub fn isEmpty(this: VendorPrefix) bool { + return this == VendorPrefix{}; + } + + pub fn bitwiseAnd(a: @This(), b: @This()) @This() { + return bun.bits.@"and"(@This(), a, b); + } + + pub fn asBits(vp: @This()) u8 { + return @bitCast(vp); + } }; pub const SourceLocation = struct { @@ -576,7 +606,7 @@ pub fn DeriveParse(comptime T: type) type { break :counts .{ payload_count, first_payload_index.?, void_count, first_void_index }; }; - return gnerateCode(input, first_payload_index, first_void_index, void_count, payload_count); + return generateCode(input, first_payload_index, first_void_index, void_count, payload_count); } const location = input.currentSourceLocation(); @@ -625,7 +655,7 @@ pub fn DeriveParse(comptime T: type) type { /// and then try to parse the void fields. /// /// This parsing order is a detail copied from LightningCSS. I'm not sure if it is necessary. But it could be. - inline fn gnerateCode( + inline fn generateCode( input: *Parser, comptime first_payload_index: usize, comptime maybe_first_void_index: ?usize, @@ -873,14 +903,6 @@ pub fn DefineEnumProperty(comptime T: type) type { return @intFromEnum(lhs.*) == @intFromEnum(rhs.*); } - pub fn asStr(this: *const T) []const u8 { - const tag = @intFromEnum(this.*); - inline for (fields) |field| { - if (tag == field.value) return field.name; - } - unreachable; - } - pub fn parse(input: *Parser) Result(T) { const location = input.currentSourceLocation(); const ident = switch (input.expectIdent()) { @@ -894,13 +916,10 @@ pub fn DefineEnumProperty(comptime T: type) type { } return .{ .err = location.newUnexpectedTokenError(.{ .ident = ident }) }; - // @panic("TODO renable this"); } - pub fn deinit(_: *T, _: std.mem.Allocator) void {} - pub fn toCss(this: *const T, comptime W: type, dest: *Printer(W)) PrintErr!void { - return dest.writeStr(asStr(this)); + return dest.writeStr(@tagName(this.*)); } pub inline fn deepClone(this: *const T, _: std.mem.Allocator) T { @@ -1151,7 +1170,7 @@ fn parse_until_before( closure: anytype, comptime parse_fn: *const fn (@TypeOf(closure), *Parser) Result(T), ) Result(T) { - const delimiters = parser.stop_before.bitwiseOr(delimiters_); + const delimiters = bun.bits.@"or"(Delimiters, parser.stop_before, delimiters_); const result = result: { var delimited_parser = Parser{ .input = parser.input, @@ -1176,7 +1195,7 @@ fn parse_until_before( // FIXME: have a special-purpose tokenizer method for this that does less work. while (true) { - if (delimiters.contains(Delimiters.fromByte(parser.input.tokenizer.nextByte()))) break; + if (bun.bits.contains(Delimiters, delimiters, Delimiters.fromByte(parser.input.tokenizer.nextByte()))) break; switch (parser.input.tokenizer.next()) { .result => |token| { @@ -1207,8 +1226,9 @@ pub fn parse_until_after( return result; } const next_byte = parser.input.tokenizer.nextByte(); - if (next_byte != null and !parser.stop_before.contains(Delimiters.fromByte(next_byte))) { - bun.debugAssert(delimiters.contains(Delimiters.fromByte(next_byte))); + if (next_byte != null and !bun.bits.contains(Delimiters, parser.stop_before, .fromByte(next_byte))) { + if (bun.Environment.isDebug) bun.debugAssert(bun.bits.contains(Delimiters, delimiters, Delimiters.fromByte(next_byte))); + // We know this byte is ASCII. parser.input.tokenizer.advance(1); if (next_byte == '{') { @@ -2453,7 +2473,7 @@ pub fn NestedRuleParser(comptime T: type) type { .style = css_rules.style.StyleRule(T.CustomAtRuleParser.AtRule){ .selectors = selectors, .declarations = declarations, - .vendor_prefix = VendorPrefix.empty(), + .vendor_prefix = .{}, .rules = rules, .loc = loc, }, @@ -2778,7 +2798,7 @@ pub fn NestedRuleParser(comptime T: type) type { selector.parser.Selector.fromComponent(input.allocator(), .nesting), ), .declarations = declarations, - .vendor_prefix = VendorPrefix.empty(), + .vendor_prefix = .{}, .rules = .{}, .loc = loc, }, @@ -2947,8 +2967,6 @@ pub const CssRef = packed struct(u32) { pub const ID = Tag{ .id = true }; pub const CLASS = Tag{ .class = true }; - pub usingnamespace Bitflags(@This()); - pub fn canBeComposed(this: @This()) bool { return this.class; } @@ -3088,7 +3106,7 @@ pub fn StyleSheet(comptime AtRule: type) type { // @custom-media rules may be defined after they are referenced, but may only be defined at the top level // of a stylesheet. Do a pre-scan here and create a lookup table by name. - var custom_media: ?std.StringArrayHashMapUnmanaged(css_rules.custom_media.CustomMediaRule) = if (this.options.flags.contains(ParserFlags{ .custom_media = true }) and options.targets.shouldCompileSame(.custom_media_queries)) brk: { + var custom_media: ?std.StringArrayHashMapUnmanaged(css_rules.custom_media.CustomMediaRule) = if (this.options.flags.custom_media and options.targets.shouldCompileSame(.custom_media_queries)) brk: { var custom_media = std.StringArrayHashMapUnmanaged(css_rules.custom_media.CustomMediaRule){}; for (this.rules.v.items) |*rule| { @@ -3768,8 +3786,6 @@ pub const ParserFlags = packed struct(u8) { /// Whether to enable the non-standard >>> and /deep/ selector combinators used by Vue and Angular. deep_selector_combinator: bool = false, __unused: u5 = 0, - - pub usingnamespace Bitflags(@This()); }; const ParseUntilErrorBehavior = enum { @@ -3816,7 +3832,7 @@ pub const Parser = struct { bun.assert(this.extra != null); if (comptime bun.Environment.allow_assert) { // tag should only have one bit set, or none - bun.assert(@popCount(tag.asBits()) <= 1); + bun.assert(@popCount(bun.bits.asInt(CssRef.Tag, tag)) <= 1); } const extra = this.extra.?; @@ -3838,7 +3854,7 @@ pub const Parser = struct { const prev_tag = entry.value_ptr.ref.tag; if (!prev_tag.class and tag.class) { entry.value_ptr.loc = loc; - entry.value_ptr.ref.tag = entry.value_ptr.ref.tag.bitwiseOr(tag); + entry.value_ptr.ref.tag = bun.bits.@"or"(CssRef.Tag, entry.value_ptr.ref.tag, tag); } } @@ -4000,7 +4016,7 @@ pub const Parser = struct { /// the internal state of the parser (including position within the input) /// is restored to what it was before the call. /// - /// func needs to be a funtion like this: `fn func(*Parser, ...@TypeOf(args_)) T` + /// func needs to be a function like this: `fn func(*Parser, ...@TypeOf(args_)) T` pub inline fn tryParse(this: *Parser, comptime func: anytype, args_: anytype) bun.meta.ReturnOf(func) { const start = this.state(); const result = result: { @@ -4405,7 +4421,7 @@ pub const Parser = struct { pub fn nextByte(this: *@This()) ?u8 { const byte = this.input.tokenizer.nextByte(); - if (this.stop_before.contains(Delimiters.fromByte(byte))) { + if (bun.bits.contains(Delimiters, this.stop_before, .fromByte(byte))) { return null; } return byte; @@ -4440,7 +4456,7 @@ pub const Parser = struct { } const byte = this.input.tokenizer.nextByte(); - if (this.stop_before.contains(Delimiters.fromByte(byte))) { + if (bun.bits.contains(Delimiters, this.stop_before, .fromByte(byte))) { return .{ .err = this.newError(BasicParseErrorKind.end_of_input) }; } @@ -4505,8 +4521,6 @@ pub const Delimiters = packed struct(u8) { close_parenthesis: bool = false, __unused: u1 = 0, - pub usingnamespace Bitflags(Delimiters); - const NONE: Delimiters = .{}; pub fn getDelimiter(comptime tag: @TypeOf(.enum_literal)) Delimiters { diff --git a/src/css/declaration.zig b/src/css/declaration.zig index 02f2f58454..f48636ac88 100644 --- a/src/css/declaration.zig +++ b/src/css/declaration.zig @@ -1,6 +1,6 @@ const std = @import("std"); const Allocator = std.mem.Allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const logger = bun.logger; const Log = logger.Log; diff --git a/src/css/dependencies.zig b/src/css/dependencies.zig index 3ad9eda93f..d513e03c1c 100644 --- a/src/css/dependencies.zig +++ b/src/css/dependencies.zig @@ -1,6 +1,6 @@ const std = @import("std"); const Allocator = std.mem.Allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const logger = bun.logger; const Log = logger.Log; diff --git a/src/css/error.zig b/src/css/error.zig index 4a7c555a49..949549090e 100644 --- a/src/css/error.zig +++ b/src/css/error.zig @@ -1,6 +1,6 @@ const std = @import("std"); const Allocator = std.mem.Allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const logger = bun.logger; const Log = logger.Log; diff --git a/src/css/generics.zig b/src/css/generics.zig index 3876d69e84..25af27e188 100644 --- a/src/css/generics.zig +++ b/src/css/generics.zig @@ -1,6 +1,6 @@ const std = @import("std"); const Allocator = std.mem.Allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const logger = bun.logger; const Log = logger.Log; @@ -452,8 +452,10 @@ pub inline fn eql(comptime T: type, lhs: *const T, rhs: *const T) bool { CustomIdent, DashedIdent, Ident => bun.strings.eql(lhs.v, rhs.v), []const u8 => bun.strings.eql(lhs.*, rhs.*), bun.logger.Loc => lhs.eql(rhs.*), - // css.VendorPrefix => css.VendorPrefix.eq(lhs.*, rhs.*), - else => T.eql(lhs, rhs), + else => if (@typeInfo(T) == .@"struct" and @typeInfo(T).@"struct".layout == .@"packed") + lhs.* == rhs.* + else + T.eql(lhs, rhs), }; } diff --git a/src/css/logical.zig b/src/css/logical.zig index adcbf8a346..bc3375bf35 100644 --- a/src/css/logical.zig +++ b/src/css/logical.zig @@ -1,6 +1,6 @@ const std = @import("std"); const Allocator = std.mem.Allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const logger = bun.logger; const Log = logger.Log; diff --git a/src/css/media_query.zig b/src/css/media_query.zig index 1f4980f42d..37b81621d1 100644 --- a/src/css/media_query.zig +++ b/src/css/media_query.zig @@ -1,6 +1,6 @@ const std = @import("std"); const Allocator = std.mem.Allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const logger = bun.logger; const Log = logger.Log; @@ -201,12 +201,12 @@ pub const MediaQuery = struct { }; const condition = if (explicit_media_type == null) - switch (MediaCondition.parseWithFlags(input, QueryConditionFlags{ .allow_or = true })) { + switch (MediaCondition.parseWithFlags(input, .{ .allow_or = true })) { .result => |v| v, .err => |e| return .{ .err = e }, } else if (input.tryParse(css.Parser.expectIdentMatching, .{"and"}).isOk()) - switch (MediaCondition.parseWithFlags(input, QueryConditionFlags.empty())) { + switch (MediaCondition.parseWithFlags(input, .{})) { .result => |v| v, .err => |e| return .{ .err = e }, } @@ -274,8 +274,6 @@ pub const QueryConditionFlags = packed struct(u8) { /// Whether to allow style container queries. allow_style: bool = false, __unused: u6 = 0, - - pub usingnamespace css.Bitflags(@This()); }; pub fn toCssWithParensIfNeeded( @@ -488,7 +486,7 @@ pub fn parseQueryCondition( if (bun.strings.eqlCaseInsensitiveASCIIICheckLength(ident, "not")) break :brk .{ true, false }; }, .function => |f| { - if (flags.contains(QueryConditionFlags{ .allow_style = true }) and + if (flags.allow_style and bun.strings.eqlCaseInsensitiveASCIIICheckLength(f, "style")) { break :brk .{ false, true }; @@ -536,7 +534,7 @@ pub fn parseQueryCondition( else return .{ .result = first_condition }; - if (!flags.contains(QueryConditionFlags{ .allow_or = true }) and operator == .@"or") { + if (!flags.allow_or and operator == .@"or") { return .{ .err = location.newUnexpectedTokenError(css.Token{ .ident = "or" }) }; } @@ -587,7 +585,7 @@ pub fn parseParensOrFunction( switch (t.*) { .open_paren => return parseParenBlock(QueryCondition, input, flags), .function => |f| { - if (flags.contains(QueryConditionFlags{ .allow_style = true }) and + if (flags.allow_style and bun.strings.eqlCaseInsensitiveASCIIICheckLength(f, "style")) { return QueryCondition.parseStyleQuery(input); @@ -708,7 +706,7 @@ pub const MediaFeatureId = enum { /// The non-standard -moz-device-pixel-ratio media feature. @"-moz-device-pixel-ratio", - pub usingnamespace css.DeriveValueType(@This(), ValueTypeMap); + pub const valueType = css.DeriveValueType(@This(), ValueTypeMap).valueType; pub const ValueTypeMap = .{ .width = MediaFeatureType.length, diff --git a/src/css/prefixes.zig b/src/css/prefixes.zig index dfb384fe54..a653596f1a 100644 --- a/src/css/prefixes.zig +++ b/src/css/prefixes.zig @@ -196,1956 +196,1956 @@ pub const Feature = enum { .border_radius, .border_top_left_radius, .border_top_right_radius, .border_bottom_right_radius, .border_bottom_left_radius => { if (browsers.android) |version| { if (version <= 131328) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.chrome) |version| { if (version <= 262144) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.firefox) |version| { if (version >= 131072 and version <= 198144) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .moz = true }); + prefixes.moz = true; } } if (browsers.ios_saf) |version| { if (version <= 197120) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 196864 and version <= 262144) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .box_shadow => { if (browsers.android) |version| { if (version >= 131328 and version <= 196608) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.chrome) |version| { if (version >= 262144 and version <= 589824) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.firefox) |version| { if (version >= 197888 and version <= 198144) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .moz = true }); + prefixes.moz = true; } } if (browsers.ios_saf) |version| { if (version >= 197120 and version <= 262656) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 196864 and version <= 327680) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .animation, .animation_name, .animation_duration, .animation_delay, .animation_direction, .animation_fill_mode, .animation_iteration_count, .animation_play_state, .animation_timing_function, .at_keyframes => { if (browsers.android) |version| { if (version >= 131328 and version <= 263171) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.chrome) |version| { if (version >= 262144 and version <= 2752512) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.firefox) |version| { if (version >= 327680 and version <= 983040) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .moz = true }); + prefixes.moz = true; } } if (browsers.ios_saf) |version| { if (version >= 197120 and version <= 524544) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.opera) |version| { if (version == 786432) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .o = true }); + prefixes.o = true; } if (version >= 983040 and version <= 1900544) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 262144 and version <= 524288) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .transition, .transition_property, .transition_duration, .transition_delay, .transition_timing_function => { if (browsers.android) |version| { if (version >= 131328 and version <= 262656) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.chrome) |version| { if (version >= 262144 and version <= 1638400) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.firefox) |version| { if (version >= 262144 and version <= 983040) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .moz = true }); + prefixes.moz = true; } } if (browsers.ios_saf) |version| { if (version >= 197120 and version <= 393216) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.opera) |version| { if (version >= 655360 and version <= 786432) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .o = true }); + prefixes.o = true; } } if (browsers.safari) |version| { if (version >= 196864 and version <= 393216) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .transform, .transform_origin => { if (browsers.android) |version| { if (version >= 131328 and version <= 263171) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.chrome) |version| { if (version >= 262144 and version <= 2293760) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.firefox) |version| { if (version >= 197888 and version <= 983040) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .moz = true }); + prefixes.moz = true; } } if (browsers.ie) |version| { if (version <= 589824) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .ms = true }); + prefixes.ms = true; } } if (browsers.ios_saf) |version| { if (version >= 197120 and version <= 524544) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.opera) |version| { if (version >= 656640 and version <= 786432) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .o = true }); + prefixes.o = true; } if (version >= 983040 and version <= 1441792) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 196864 and version <= 524288) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .perspective, .perspective_origin, .transform_style => { if (browsers.android) |version| { if (version >= 196608 and version <= 263171) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.chrome) |version| { if (version >= 786432 and version <= 2293760) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.firefox) |version| { if (version >= 655360 and version <= 983040) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .moz = true }); + prefixes.moz = true; } } if (browsers.ios_saf) |version| { if (version >= 197120 and version <= 524544) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.opera) |version| { if (version >= 983040 and version <= 1441792) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 262144 and version <= 524288) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .backface_visibility => { if (browsers.android) |version| { if (version >= 196608 and version <= 263171) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.chrome) |version| { if (version >= 786432 and version <= 2293760) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.firefox) |version| { if (version >= 655360 and version <= 983040) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .moz = true }); + prefixes.moz = true; } } if (browsers.ios_saf) |version| { if (version >= 197120 and version <= 983552) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.opera) |version| { if (version >= 983040 and version <= 1441792) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 262144 and version <= 983552) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .linear_gradient, .repeating_linear_gradient, .radial_gradient, .repeating_radial_gradient => { if (browsers.android) |version| { if (version >= 131328 and version <= 262656) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.chrome) |version| { if (version >= 262144 and version <= 1638400) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.firefox) |version| { if (version >= 198144 and version <= 983040) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .moz = true }); + prefixes.moz = true; } } if (browsers.ios_saf) |version| { if (version >= 197120 and version <= 393216) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.opera) |version| { if (version >= 721152 and version <= 786432) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .o = true }); + prefixes.o = true; } } if (browsers.safari) |version| { if (version >= 262144 and version <= 393216) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .box_sizing => { if (browsers.android) |version| { if (version >= 131328 and version <= 196608) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.chrome) |version| { if (version >= 262144 and version <= 589824) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.firefox) |version| { if (version >= 131072 and version <= 1835008) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .moz = true }); + prefixes.moz = true; } } if (browsers.ios_saf) |version| { if (version >= 197120 and version <= 262656) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 196864 and version <= 327680) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .filter => { if (browsers.android) |version| { if (version >= 263168 and version <= 263171) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.chrome) |version| { if (version >= 1179648 and version <= 3407872) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.ios_saf) |version| { if (version >= 393216 and version <= 589824) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.opera) |version| { if (version >= 983040 and version <= 2555904) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 393216 and version <= 589824) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.samsung) |version| { if (version >= 262144 and version <= 393728) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .filter_function => { if (browsers.ios_saf) |version| { if (version >= 589824 and version <= 590592) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version <= 589824) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .backdrop_filter => { if (browsers.edge) |version| { if (version >= 1114112 and version <= 1179648) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.ios_saf) |version| { if (version >= 589824 and version <= 1115648) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 589824 and version <= 1115648) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .element => { if (browsers.firefox) |version| { if (version >= 131072 and version <= 8650752) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .moz = true }); + prefixes.moz = true; } } }, .columns, .column_width, .column_gap, .column_rule, .column_rule_color, .column_rule_width, .column_count, .column_rule_style, .column_span, .column_fill => { if (browsers.android) |version| { if (version >= 131328 and version <= 263171) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.chrome) |version| { if (version >= 262144 and version <= 3211264) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.firefox) |version| { if (version >= 131072 and version <= 3342336) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .moz = true }); + prefixes.moz = true; } } if (browsers.ios_saf) |version| { if (version >= 197120 and version <= 524544) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.opera) |version| { if (version >= 983040 and version <= 2359296) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 196864 and version <= 524288) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.samsung) |version| { if (version <= 262144) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .break_before, .break_after, .break_inside => { if (browsers.android) |version| { if (version >= 131328 and version <= 263171) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.chrome) |version| { if (version >= 262144 and version <= 3211264) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.ios_saf) |version| { if (version >= 197120 and version <= 524544) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.opera) |version| { if (version >= 983040 and version <= 2359296) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 196864 and version <= 524288) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.samsung) |version| { if (version <= 262144) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .user_select => { if (browsers.android) |version| { if (version >= 131328 and version <= 263171) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.chrome) |version| { if (version >= 262144 and version <= 3473408) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.edge) |version| { if (version >= 786432 and version <= 1179648) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .ms = true }); + prefixes.ms = true; } } if (browsers.firefox) |version| { if (version >= 131072 and version <= 4456448) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .moz = true }); + prefixes.moz = true; } } if (browsers.ie) |version| { if (version >= 655360) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .ms = true }); + prefixes.ms = true; } } if (browsers.ios_saf) |version| { if (version >= 197120 and version <= 1179648) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.opera) |version| { if (version >= 983040 and version <= 2621440) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 196864 and version <= 1179648) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.samsung) |version| { if (version >= 262144 and version <= 327680) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .display_flex, .inline_flex, .flex, .flex_grow, .flex_shrink, .flex_basis, .flex_direction, .flex_wrap, .flex_flow, .justify_content, .order, .align_items, .align_self, .align_content => { if (browsers.android) |version| { if (version >= 131328 and version <= 262656) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.chrome) |version| { if (version >= 262144 and version <= 1835008) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.firefox) |version| { if (version >= 131072 and version <= 1376256) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .moz = true }); + prefixes.moz = true; } } if (browsers.ie) |version| { if (version == 655360) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .ms = true }); + prefixes.ms = true; } } if (browsers.ios_saf) |version| { if (version >= 197120 and version <= 524544) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.opera) |version| { if (version >= 983040 and version <= 1048576) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 196864 and version <= 524288) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .calc => { if (browsers.chrome) |version| { if (version >= 1245184 and version <= 1638400) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.firefox) |version| { if (version >= 262144 and version <= 983040) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .moz = true }); + prefixes.moz = true; } } if (browsers.ios_saf) |version| { if (version <= 393216) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version <= 393216) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .background_origin, .background_size => { if (browsers.android) |version| { if (version >= 131328 and version <= 131840) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.firefox) |version| { if (version <= 198144) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .moz = true }); + prefixes.moz = true; } } if (browsers.opera) |version| { if (version <= 655360) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .o = true }); + prefixes.o = true; } } }, .background_clip => { if (browsers.android) |version| { if (version >= 262144 and version <= 263171) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.chrome) |version| { if (version >= 262144 and version <= 7798784) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.edge) |version| { if (version >= 786432 and version <= 917504) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .ms = true }); + prefixes.ms = true; } if (version >= 5177344 and version <= 7798784) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.ios_saf) |version| { if (version >= 393216 and version <= 852992) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.opera) |version| { if (version >= 983040 and version <= 6881280) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 262144 and version <= 852224) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.samsung) |version| { if (version >= 262144 and version <= 1572864) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .font_feature_settings, .font_variant_ligatures, .font_language_override => { if (browsers.android) |version| { if (version >= 263168 and version <= 263171) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.chrome) |version| { if (version >= 1048576 and version <= 3080192) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.firefox) |version| { if (version >= 262144 and version <= 2162688) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .moz = true }); + prefixes.moz = true; } } if (browsers.opera) |version| { if (version >= 983040 and version <= 2228224) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.samsung) |version| { if (version <= 262144) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .font_kerning => { if (browsers.android) |version| { if (version <= 263168) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.chrome) |version| { if (version >= 1900544 and version <= 2097152) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.ios_saf) |version| { if (version >= 524288 and version <= 721664) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.opera) |version| { if (version >= 1048576 and version <= 1245184) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 458752 and version <= 589824) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .border_image => { if (browsers.android) |version| { if (version >= 131328 and version <= 262656) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.chrome) |version| { if (version >= 262144 and version <= 917504) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.firefox) |version| { if (version >= 197888 and version <= 917504) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .moz = true }); + prefixes.moz = true; } } if (browsers.ios_saf) |version| { if (version >= 197120 and version <= 327680) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.opera) |version| { if (version >= 720896 and version <= 786688) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .o = true }); + prefixes.o = true; } } if (browsers.safari) |version| { if (version >= 196864 and version <= 327936) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .pseudo_element_selection => { if (browsers.firefox) |version| { if (version >= 131072 and version <= 3997696) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .moz = true }); + prefixes.moz = true; } } }, .pseudo_element_placeholder => { if (browsers.android) |version| { if (version >= 131328 and version <= 263171) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.chrome) |version| { if (version >= 262144 and version <= 3670016) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.edge) |version| { if (version >= 786432 and version <= 1179648) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .ms = true }); + prefixes.ms = true; } } if (browsers.firefox) |version| { if (version >= 1179648 and version <= 3276800) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .moz = true }); + prefixes.moz = true; } } if (browsers.ie) |version| { if (version >= 655360) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .ms = true }); + prefixes.ms = true; } } if (browsers.ios_saf) |version| { if (version >= 262656 and version <= 655360) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.opera) |version| { if (version >= 983040 and version <= 2818048) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 327680 and version <= 655360) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.samsung) |version| { if (version >= 262144 and version <= 393728) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .pseudo_class_placeholder_shown => { if (browsers.firefox) |version| { if (version >= 262144 and version <= 3276800) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .moz = true }); + prefixes.moz = true; } } if (browsers.ie) |version| { if (version >= 655360) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .ms = true }); + prefixes.ms = true; } } }, .hyphens => { if (browsers.edge) |version| { if (version >= 786432 and version <= 1179648) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .ms = true }); + prefixes.ms = true; } } if (browsers.firefox) |version| { if (version >= 393216 and version <= 2752512) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .moz = true }); + prefixes.moz = true; } } if (browsers.ie) |version| { if (version >= 655360) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .ms = true }); + prefixes.ms = true; } } if (browsers.ios_saf) |version| { if (version >= 262656 and version <= 1050112) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 327936 and version <= 1050112) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .pseudo_class_fullscreen => { if (browsers.chrome) |version| { if (version >= 983040 and version <= 4587520) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.firefox) |version| { if (version >= 655360 and version <= 4128768) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .moz = true }); + prefixes.moz = true; } } if (browsers.ie) |version| { if (version >= 720896) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .ms = true }); + prefixes.ms = true; } } if (browsers.opera) |version| { if (version >= 983040 and version <= 4128768) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 327936 and version <= 1049344) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.samsung) |version| { if (version >= 262144 and version <= 590336) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .pseudo_element_backdrop => { if (browsers.android) |version| { if (version >= 263168 and version <= 263171) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.chrome) |version| { if (version >= 2097152 and version <= 2359296) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.edge) |version| { if (version >= 786432 and version <= 1179648) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .ms = true }); + prefixes.ms = true; } } if (browsers.ie != null) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .ms = true }); + prefixes.ms = true; } if (browsers.opera) |version| { if (version >= 1245184 and version <= 1507328) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .pseudo_element_file_selector_button => { if (browsers.android) |version| { if (version >= 263168 and version <= 263171) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.chrome) |version| { if (version >= 262144 and version <= 5767168) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.edge) |version| { if (version >= 786432 and version <= 1179648) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .ms = true }); + prefixes.ms = true; } if (version >= 5177344 and version <= 5767168) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.ie) |version| { if (version >= 655360) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .ms = true }); + prefixes.ms = true; } } if (browsers.ios_saf) |version| { if (version >= 197120 and version <= 917504) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.opera) |version| { if (version >= 983040 and version <= 4849664) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 196864 and version <= 917504) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.samsung) |version| { if (version >= 262144 and version <= 917504) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .pseudo_class_autofill => { if (browsers.android) |version| { if (version >= 263168 and version <= 263171) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.chrome) |version| { if (version >= 262144 and version <= 7143424) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.edge) |version| { if (version >= 5177344 and version <= 7143424) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.ios_saf) |version| { if (version >= 197120 and version <= 918784) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.opera) |version| { if (version >= 983040 and version <= 6225920) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 196864 and version <= 917760) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.samsung) |version| { if (version >= 262144 and version <= 1310720) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .tab_size => { if (browsers.firefox) |version| { if (version >= 262144 and version <= 5898240) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .moz = true }); + prefixes.moz = true; } } if (browsers.opera) |version| { if (version >= 656896 and version <= 786688) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .o = true }); + prefixes.o = true; } } }, .max_content, .min_content => { if (browsers.android) |version| { if (version >= 263168 and version <= 263171) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.chrome) |version| { if (version >= 1441792 and version <= 2949120) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.firefox) |version| { if (version >= 196608 and version <= 4259840) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .moz = true }); + prefixes.moz = true; } } if (browsers.ios_saf) |version| { if (version >= 458752 and version <= 852992) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.opera) |version| { if (version >= 983040 and version <= 2097152) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 393472 and version <= 655616) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.samsung) |version| { if (version <= 262144) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .fill, .fill_available => { if (browsers.chrome) |version| { if (version >= 1441792 and version <= 8519680) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.android) |version| { if (version >= 263168 and version <= 8323072) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.edge) |version| { if (version >= 5177344 and version <= 8323072) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.firefox) |version| { if (version >= 196608 and version <= 4259840) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .moz = true }); + prefixes.moz = true; } } if (browsers.ios_saf) |version| { if (version >= 458752 and version <= 852992) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.opera) |version| { if (version >= 983040) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 393472 and version <= 655616) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.samsung) |version| { if (version >= 262144 and version <= 1638400) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .fit_content => { if (browsers.android) |version| { if (version >= 263168 and version <= 263171) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.chrome) |version| { if (version >= 1441792 and version <= 2949120) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.firefox) |version| { if (version >= 196608 and version <= 6094848) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .moz = true }); + prefixes.moz = true; } } if (browsers.ios_saf) |version| { if (version >= 458752 and version <= 852992) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.opera) |version| { if (version >= 983040 and version <= 2097152) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 393472 and version <= 655616) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.samsung) |version| { if (version <= 262144) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .stretch => { if (browsers.chrome) |version| { if (version >= 1441792 and version <= 8519680) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.firefox) |version| { if (version >= 196608 and version <= 8650752) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .moz = true }); + prefixes.moz = true; } } if (browsers.android) |version| { if (version >= 263168 and version <= 8323072) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.edge) |version| { if (version >= 5177344 and version <= 8323072) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.ios_saf) |version| { if (version >= 458752 and version <= 1179648) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.opera) |version| { if (version >= 983040) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 458752 and version <= 1179648) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.samsung) |version| { if (version >= 327680 and version <= 1638400) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .zoom_in, .zoom_out => { if (browsers.chrome) |version| { if (version >= 262144 and version <= 2359296) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.firefox) |version| { if (version >= 131072 and version <= 1507328) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .moz = true }); + prefixes.moz = true; } } if (browsers.opera) |version| { if (version >= 983040 and version <= 1507328) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 196864 and version <= 524288) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .grab, .grabbing => { if (browsers.chrome) |version| { if (version >= 262144 and version <= 4390912) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.firefox) |version| { if (version >= 131072 and version <= 1703936) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .moz = true }); + prefixes.moz = true; } } if (browsers.opera) |version| { if (version >= 983040 and version <= 3538944) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 196864 and version <= 655616) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .sticky => { if (browsers.ios_saf) |version| { if (version >= 393216 and version <= 786944) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 393472 and version <= 786688) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .touch_action => { if (browsers.ie) |version| { if (version == 655360) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .ms = true }); + prefixes.ms = true; } } }, .text_decoration_skip, .text_decoration_skip_ink => { if (browsers.ios_saf) |version| { if (version >= 524288 and version <= 1179648) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 459008 and version <= 786432) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .text_decoration => { if (browsers.ios_saf) |version| { if (version >= 524288 and version <= 1179648) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 524288 and version <= 1179648) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .text_decoration_color, .text_decoration_line, .text_decoration_style => { if (browsers.firefox) |version| { if (version >= 393216 and version <= 2293760) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .moz = true }); + prefixes.moz = true; } } if (browsers.ios_saf) |version| { if (version >= 524288 and version <= 786432) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 524288 and version <= 786432) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .text_size_adjust => { if (browsers.firefox) |version| { if (version <= 8323072) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .moz = true }); + prefixes.moz = true; } } if (browsers.edge) |version| { if (version >= 786432 and version <= 1179648) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .ms = true }); + prefixes.ms = true; } } if (browsers.ie) |version| { if (version >= 655360) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .ms = true }); + prefixes.ms = true; } } if (browsers.ios_saf) |version| { if (version >= 327680 and version <= 1179648) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .mask_clip, .mask_composite, .mask_image, .mask_origin, .mask_repeat, .mask_border_repeat, .mask_border_source, .mask, .mask_position, .mask_size, .mask_border, .mask_border_outset, .mask_border_width, .mask_border_slice => { if (browsers.android) |version| { if (version >= 131328 and version <= 263171) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.chrome) |version| { if (version >= 262144 and version <= 7798784) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.edge) |version| { if (version >= 5177344 and version <= 7798784) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.ios_saf) |version| { if (version >= 197120 and version <= 983552) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.opera) |version| { if (version >= 983040 and version <= 6881280) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 262144 and version <= 983552) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.samsung) |version| { if (version >= 262144 and version <= 1572864) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .clip_path => { if (browsers.android) |version| { if (version >= 263168 and version <= 263171) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.chrome) |version| { if (version >= 1572864 and version <= 3538944) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.ios_saf) |version| { if (version >= 458752 and version <= 589824) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.opera) |version| { if (version >= 983040 and version <= 2686976) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 458752 and version <= 589824) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.samsung) |version| { if (version >= 262144 and version <= 327680) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .box_decoration_break => { if (browsers.chrome) |version| { if (version >= 1441792 and version <= 8519680) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.android) |version| { if (version >= 263168 and version <= 8323072) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.edge) |version| { if (version >= 5177344 and version <= 8323072) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.ios_saf) |version| { if (version >= 458752 and version <= 1179648) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.opera) |version| { if (version >= 983040) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 393472 and version <= 1179648) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.samsung) |version| { if (version >= 262144 and version <= 1638400) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .object_fit, .object_position => { if (browsers.opera) |version| { if (version >= 656896 and version <= 786688) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .o = true }); + prefixes.o = true; } } }, .shape_margin, .shape_outside, .shape_image_threshold => { if (browsers.ios_saf) |version| { if (version >= 524288 and version <= 655360) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 459008 and version <= 655360) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .text_overflow => { if (browsers.opera) |version| { if (version >= 589824 and version <= 786432) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .o = true }); + prefixes.o = true; } } }, .at_viewport => { if (browsers.edge) |version| { if (version >= 786432 and version <= 1179648) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .ms = true }); + prefixes.ms = true; } } if (browsers.ie) |version| { if (version >= 655360) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .ms = true }); + prefixes.ms = true; } } if (browsers.opera) |version| { if (version >= 720896 and version <= 786688) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .o = true }); + prefixes.o = true; } } }, .at_resolution => { if (browsers.android) |version| { if (version >= 131840 and version <= 262656) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.chrome) |version| { if (version >= 262144 and version <= 1835008) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.firefox) |version| { if (version >= 197888 and version <= 983040) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .moz = true }); + prefixes.moz = true; } } if (browsers.ios_saf) |version| { if (version >= 262144 and version <= 984576) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.opera) |version| { if (version >= 591104 and version <= 786432) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .o = true }); + prefixes.o = true; } } if (browsers.safari) |version| { if (version >= 262144 and version <= 984576) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .text_align_last => { if (browsers.firefox) |version| { if (version >= 786432 and version <= 3145728) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .moz = true }); + prefixes.moz = true; } } }, .pixelated => { if (browsers.firefox) |version| { if (version >= 198144 and version <= 4194304) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .moz = true }); + prefixes.moz = true; } } if (browsers.ios_saf) |version| { if (version >= 327680 and version <= 393216) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.opera) |version| { if (version >= 722432 and version <= 786688) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .o = true }); + prefixes.o = true; } } if (browsers.safari) |version| { if (version <= 393216) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .image_rendering => { if (browsers.ie) |version| { if (version >= 458752) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .ms = true }); + prefixes.ms = true; } } }, .border_inline_start, .border_inline_end, .margin_inline_start, .margin_inline_end, .padding_inline_start, .padding_inline_end => { if (browsers.android) |version| { if (version >= 131328 and version <= 263171) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.chrome) |version| { if (version >= 262144 and version <= 4456448) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.firefox) |version| { if (version >= 196608 and version <= 2621440) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .moz = true }); + prefixes.moz = true; } } if (browsers.ios_saf) |version| { if (version >= 197120 and version <= 786432) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.opera) |version| { if (version >= 983040 and version <= 3604480) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 196864 and version <= 786432) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.samsung) |version| { if (version >= 262144 and version <= 590336) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .border_block_start, .border_block_end, .margin_block_start, .margin_block_end, .padding_block_start, .padding_block_end => { if (browsers.android) |version| { if (version >= 131328 and version <= 263171) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.chrome) |version| { if (version >= 262144 and version <= 4456448) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.ios_saf) |version| { if (version >= 197120 and version <= 786432) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.opera) |version| { if (version >= 983040 and version <= 3604480) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 196864 and version <= 786432) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.samsung) |version| { if (version >= 262144 and version <= 590336) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .appearance => { if (browsers.android) |version| { if (version >= 131328 and version <= 263171) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.chrome) |version| { if (version >= 262144 and version <= 5439488) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.edge) |version| { if (version >= 786432 and version <= 1179648) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .ms = true }); + prefixes.ms = true; } if (version >= 5177344 and version <= 5439488) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.firefox) |version| { if (version >= 131072 and version <= 5177344) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .moz = true }); + prefixes.moz = true; } } if (browsers.ie != null) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .ms = true }); + prefixes.ms = true; } if (browsers.ios_saf) |version| { if (version >= 197120 and version <= 983552) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.opera) |version| { if (version >= 983040 and version <= 4718592) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 196864 and version <= 983552) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.samsung) |version| { if (version >= 262144 and version <= 851968) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .scroll_snap_type, .scroll_snap_coordinate, .scroll_snap_destination, .scroll_snap_points_x, .scroll_snap_points_y => { if (browsers.edge) |version| { if (version >= 786432 and version <= 1179648) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .ms = true }); + prefixes.ms = true; } } if (browsers.ie) |version| { if (version >= 655360) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .ms = true }); + prefixes.ms = true; } } if (browsers.ios_saf) |version| { if (version >= 589824 and version <= 656128) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 589824 and version <= 655616) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .flow_into, .flow_from, .region_fragment => { if (browsers.chrome) |version| { if (version >= 983040 and version <= 1179648) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.edge) |version| { if (version >= 786432 and version <= 1179648) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .ms = true }); + prefixes.ms = true; } } if (browsers.ie) |version| { if (version >= 655360) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .ms = true }); + prefixes.ms = true; } } if (browsers.ios_saf) |version| { if (version >= 458752 and version <= 720896) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 393472 and version <= 720896) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .image_set => { if (browsers.android) |version| { if (version >= 263168 and version <= 263171) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.chrome) |version| { if (version >= 1376256 and version <= 7340032) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.edge) |version| { if (version >= 5177344 and version <= 7340032) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.ios_saf) |version| { if (version >= 393216 and version <= 590592) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.opera) |version| { if (version >= 983040 and version <= 6422528) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 393216 and version <= 590080) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.samsung) |version| { if (version >= 262144 and version <= 1441792) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .writing_mode => { if (browsers.android) |version| { if (version >= 196608 and version <= 263171) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.chrome) |version| { if (version >= 524288 and version <= 3080192) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.ie) |version| { if (version >= 328960) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .ms = true }); + prefixes.ms = true; } } if (browsers.ios_saf) |version| { if (version >= 327680 and version <= 656128) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.opera) |version| { if (version >= 983040 and version <= 2228224) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 327936 and version <= 655616) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.samsung) |version| { if (version <= 262144) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .cross_fade => { if (browsers.chrome) |version| { if (version >= 1114112 and version <= 8519680) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.android) |version| { if (version >= 263168 and version <= 8323072) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.edge) |version| { if (version >= 5177344 and version <= 8323072) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.ios_saf) |version| { if (version >= 327680 and version <= 590592) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.opera) |version| { if (version >= 983040) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 327936 and version <= 590080) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.samsung) |version| { if (version >= 262144 and version <= 1638400) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .pseudo_class_read_only, .pseudo_class_read_write => { if (browsers.firefox) |version| { if (version >= 196608 and version <= 5046272) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .moz = true }); + prefixes.moz = true; } } }, .text_emphasis, .text_emphasis_position, .text_emphasis_style, .text_emphasis_color => { if (browsers.android) |version| { if (version >= 263168 and version <= 263171) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.chrome) |version| { if (version >= 1638400 and version <= 6422528) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.edge) |version| { if (version >= 5177344 and version <= 6422528) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.opera) |version| { if (version >= 983040 and version <= 5570560) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 393472 and version <= 458752) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.samsung) |version| { if (version >= 262144 and version <= 1114112) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .display_grid, .inline_grid, .grid_template_columns, .grid_template_rows, .grid_row_start, .grid_column_start, .grid_row_end, .grid_column_end, .grid_row, .grid_column, .grid_area, .grid_template, .grid_template_areas, .place_self, .grid_column_align, .grid_row_align => { if (browsers.edge) |version| { if (version >= 786432 and version <= 983040) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .ms = true }); + prefixes.ms = true; } } if (browsers.ie) |version| { if (version >= 655360) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .ms = true }); + prefixes.ms = true; } } }, .text_spacing => { if (browsers.edge) |version| { if (version >= 786432 and version <= 1179648) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .ms = true }); + prefixes.ms = true; } } if (browsers.ie) |version| { if (version >= 524288) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .ms = true }); + prefixes.ms = true; } } }, .pseudo_class_any_link => { if (browsers.android) |version| { if (version >= 263168 and version <= 263171) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.chrome) |version| { if (version >= 983040 and version <= 4194304) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.firefox) |version| { if (version >= 196608 and version <= 3211264) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .moz = true }); + prefixes.moz = true; } } if (browsers.ios_saf) |version| { if (version >= 393216 and version <= 524544) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.opera) |version| { if (version >= 983040 and version <= 3342336) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 393472 and version <= 524288) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.samsung) |version| { if (version >= 327680 and version <= 524800) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .isolate => { if (browsers.chrome) |version| { if (version >= 1048576 and version <= 3080192) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.firefox) |version| { if (version >= 655360 and version <= 3211264) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .moz = true }); + prefixes.moz = true; } } if (browsers.ios_saf) |version| { if (version >= 393216 and version <= 656128) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.opera) |version| { if (version >= 983040 and version <= 2228224) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 393216 and version <= 655616) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .plaintext => { if (browsers.firefox) |version| { if (version >= 655360 and version <= 3211264) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .moz = true }); + prefixes.moz = true; } } if (browsers.ios_saf) |version| { if (version >= 393216 and version <= 656128) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 393216 and version <= 655616) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .isolate_override => { if (browsers.firefox) |version| { if (version >= 1114112 and version <= 3211264) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .moz = true }); + prefixes.moz = true; } } if (browsers.ios_saf) |version| { if (version >= 458752 and version <= 656128) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 458752 and version <= 655616) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .overscroll_behavior => { if (browsers.edge) |version| { if (version >= 786432 and version <= 1114112) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .ms = true }); + prefixes.ms = true; } } if (browsers.ie) |version| { if (version >= 655360) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .ms = true }); + prefixes.ms = true; } } }, .text_orientation => { if (browsers.safari) |version| { if (version >= 655616 and version <= 852224) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .print_color_adjust, .color_adjust => { if (browsers.chrome) |version| { if (version >= 1114112 and version <= 8519680) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.android) |version| { if (version >= 263168 and version <= 8323072) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.edge) |version| { if (version >= 5177344 and version <= 8323072) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.firefox) |version| { if (version >= 3145728 and version <= 6291456) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .moz = true }); + prefixes.moz = true; } } if (browsers.ios_saf) |version| { if (version >= 393216 and version <= 983552) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.opera) |version| { if (version >= 983040) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 393216 and version <= 983552) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.samsung) |version| { if (version >= 262144 and version <= 1638400) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, .any_pseudo => { if (browsers.chrome) |version| { if (version >= 786432 and version <= 5701632) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.edge) |version| { if (version >= 5177344 and version <= 5701632) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.firefox) |version| { if (version >= 262144 and version <= 5111808) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .moz = true }); + prefixes.moz = true; } } if (browsers.opera) |version| { if (version >= 917504 and version <= 4784128) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.safari) |version| { if (version >= 327680 and version <= 851968) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.ios_saf) |version| { if (version >= 327680 and version <= 851968) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.samsung) |version| { if (version >= 65536 and version <= 917504) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } if (browsers.android) |version| { if (version >= 2424832 and version <= 5701632) { - prefixes = prefixes.bitwiseOr(VendorPrefix{ .webkit = true }); + prefixes.webkit = true; } } }, diff --git a/src/css/printer.zig b/src/css/printer.zig index d666763877..f5d5053bd9 100644 --- a/src/css/printer.zig +++ b/src/css/printer.zig @@ -1,6 +1,6 @@ const std = @import("std"); const Allocator = std.mem.Allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const logger = bun.logger; const Log = logger.Log; @@ -122,7 +122,7 @@ pub fn Printer(comptime Writer: type) type { col: u32 = 0, minify: bool, targets: Targets, - vendor_prefix: css.VendorPrefix = css.VendorPrefix.empty(), + vendor_prefix: css.VendorPrefix = .{}, in_calc: bool = false, css_module: ?css.CssModule = null, dependencies: ?ArrayList(css.Dependency) = null, diff --git a/src/css/properties/align.zig b/src/css/properties/align.zig index 60e6a68eb3..f8ce2c51ec 100644 --- a/src/css/properties/align.zig +++ b/src/css/properties/align.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Allocator = std.mem.Allocator; const ArrayList = std.ArrayListUnmanaged; @@ -57,8 +57,8 @@ pub const AlignContent = union(enum) { } }, - pub usingnamespace css.DeriveParse(@This()); - pub usingnamespace css.DeriveToCss(@This()); + pub const parse = css.DeriveParse(@This()).parse; + pub const toCss = css.DeriveToCss(@This()).toCss; pub fn eql(lhs: *const @This(), rhs: *const @This()) bool { return css.implementEql(@This(), lhs, rhs); @@ -300,8 +300,8 @@ pub const AlignSelf = union(enum) { } }, - pub usingnamespace css.DeriveParse(@This()); - pub usingnamespace css.DeriveToCss(@This()); + pub const parse = css.DeriveParse(@This()).parse; + pub const toCss = css.DeriveToCss(@This()).toCss; pub fn deepClone(this: *const @This(), allocator: std.mem.Allocator) @This() { return css.implementDeepClone(@This(), this, allocator); @@ -494,8 +494,8 @@ pub const AlignItems = union(enum) { } }, - pub usingnamespace css.DeriveParse(@This()); - pub usingnamespace css.DeriveToCss(@This()); + pub const parse = css.DeriveParse(@This()).parse; + pub const toCss = css.DeriveToCss(@This()).toCss; pub fn eql(lhs: *const @This(), rhs: *const @This()) bool { return css.implementEql(@This(), lhs, rhs); @@ -728,8 +728,8 @@ pub const GapValue = union(enum) { /// An explicit length. length_percentage: LengthPercentage, - pub usingnamespace css.DeriveParse(@This()); - pub usingnamespace css.DeriveToCss(@This()); + pub const parse = css.DeriveParse(@This()).parse; + pub const toCss = css.DeriveToCss(@This()).toCss; pub fn eql(lhs: *const @This(), rhs: *const @This()) bool { return css.implementEql(@This(), lhs, rhs); @@ -747,8 +747,6 @@ pub const Gap = struct { /// The column gap. column: GapValue, - pub usingnamespace css.DefineShorthand(@This(), css.PropertyIdTag.gap, PropertyFieldMap); - pub const PropertyFieldMap = .{ .row = "row-gap", .column = "column-gap", @@ -790,8 +788,6 @@ pub const PlaceItems = struct { /// The item justification. justify: JustifyItems, - pub usingnamespace css.DefineShorthand(@This(), css.PropertyIdTag.@"place-items", PropertyFieldMap); - pub const PropertyFieldMap = .{ .@"align" = "align-items", .justify = "justify-items", @@ -862,8 +858,6 @@ pub const PlaceSelf = struct { /// The item justification. justify: JustifySelf, - pub usingnamespace css.DefineShorthand(@This(), css.PropertyIdTag.@"place-self", PropertyFieldMap); - pub const PropertyFieldMap = .{ .@"align" = "align-self", .justify = "justify-self", @@ -946,7 +940,12 @@ pub const SelfPosition = enum { /// Item is aligned to the end of the container, within flexbox layouts. @"flex-end", - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; }; /// A value for the [place-content](https://www.w3.org/TR/css-align-3/#place-content) shorthand property. @@ -956,8 +955,6 @@ pub const PlaceContent = struct { /// The content justification. justify: JustifyContent, - pub usingnamespace css.DefineShorthand(@This(), css.PropertyIdTag.@"place-content", PropertyFieldMap); - pub const PropertyFieldMap = .{ .@"align" = css.PropertyIdTag.@"align-content", .justify = css.PropertyIdTag.@"justify-content", @@ -1036,7 +1033,12 @@ pub const ContentDistribution = enum { /// Items are stretched evenly to fill free space. stretch, - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; }; /// An [``](https://www.w3.org/TR/css-align-3/#typedef-overflow-position) value. @@ -1048,7 +1050,12 @@ pub const OverflowPosition = enum { /// container, the given alignment value is honored. unsafe, - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; }; /// A [``](https://www.w3.org/TR/css-align-3/#typedef-content-position) value. @@ -1064,7 +1071,12 @@ pub const ContentPosition = enum { /// Same as `end` when within a flexbox container. @"flex-end", - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; }; pub const SelfPositionInner = struct { @@ -1280,7 +1292,7 @@ pub const AlignHandler = struct { // If two vendor prefixes for the same property have different // values, we need to flush what we have immediately to preserve order. if (@field(this, prop)) |*v| { - if (!val.eql(&v[0]) and !v[1].contains(vp)) { + if (!val.eql(&v[0]) and !bun.bits.contains(VendorPrefix, v[1], vp)) { this.flush(dest, context); } } @@ -1291,7 +1303,7 @@ pub const AlignHandler = struct { // Otherwise, update the value and add the prefix. if (@field(this, prop)) |*tuple| { tuple.*[0] = css.generic.deepClone(@TypeOf(val.*), val, context.allocator); - tuple.*[1].insert(vp); + bun.bits.insert(VendorPrefix, &tuple.*[1], vp); } else { @field(this, prop) = .{ css.generic.deepClone(@TypeOf(val.*), val, context.allocator), vp }; this.has_any = true; @@ -1303,10 +1315,8 @@ pub const AlignHandler = struct { var prefix = context.targets.prefixes(VendorPrefix.NONE, feature); // Firefox only implemented the 2009 spec prefixed. // Microsoft only implemented the 2012 spec prefixed. - prefix.remove(VendorPrefix{ - .moz = true, - .ms = true, - }); + prefix.moz = false; + prefix.ms = false; return prefix; } @@ -1315,7 +1325,7 @@ pub const AlignHandler = struct { const val = v[0]; var prefix = v[1]; // If we have an unprefixed property, override necessary prefixes. - prefix = if (prefix.contains(VendorPrefix.NONE)) flushPrefixesHelper(this, context, feature) else prefix; + prefix = if (prefix.none) flushPrefixesHelper(this, context, feature) else prefix; dest.append(context.allocator, @unionInit(Property, prop, .{ val, prefix })) catch bun.outOfMemory(); } } @@ -1336,16 +1346,16 @@ pub const AlignHandler = struct { // If we have an unprefixed standard property, generate legacy prefixed versions. prefix = context.targets.prefixes(prefix, feature); - if (prefix.contains(VendorPrefix.NONE)) { + if (prefix.none) { if (comptime prop_2009) |p2009| { // 2009 spec, implemented by webkit and firefox. if (context.targets.browsers) |targets| { - var prefixes_2009 = VendorPrefix.empty(); + var prefixes_2009 = VendorPrefix{}; if (Feature.isFlex2009(targets)) { - prefixes_2009.insert(VendorPrefix.WEBKIT); + prefixes_2009.webkit = true; } - if (prefix.contains(VendorPrefix.MOZ)) { - prefixes_2009.insert(VendorPrefix.MOZ); + if (prefix.moz) { + prefixes_2009.moz = true; } if (!prefixes_2009.isEmpty()) { const s = brk: { @@ -1365,7 +1375,7 @@ pub const AlignHandler = struct { } // 2012 spec, implemented by microsoft. - if (prefix.contains(VendorPrefix.MS)) { + if (prefix.ms) { if (comptime prop_2012) |p2012| { const s = brk: { const T = comptime p2012[0]; @@ -1382,8 +1392,8 @@ pub const AlignHandler = struct { } // Remove Firefox and IE from standard prefixes. - prefix.remove(VendorPrefix.MOZ); - prefix.remove(VendorPrefix.MS); + prefix.moz = false; + prefix.ms = false; } } @@ -1429,10 +1439,10 @@ pub const AlignHandler = struct { const intersection = align_prefix.bitwiseAnd(if (comptime justify_prop != null) __v2.*[1] else align_prefix.*); // Only use shorthand if unprefixed. - if (intersection.contains(VendorPrefix.NONE)) { + if (intersection.none) { // Add prefixed longhands if needed. align_prefix.* = flushPrefixesHelper(this, context, align_prop.feature); - align_prefix.remove(VendorPrefix.NONE); + align_prefix.none = false; if (!align_prefix.isEmpty()) { dest.append( context.allocator, @@ -1444,7 +1454,7 @@ pub const AlignHandler = struct { const justify_actual = &__v2.*[0]; const justify_prefix = &__v2.*[1]; justify_prefix.* = this.flushPrefixesHelper(context, justify_prop.?.feature); - justify_prefix.remove(css.VendorPrefix.NONE); + justify_prefix.none = false; if (!justify_prefix.isEmpty()) { dest.append( diff --git a/src/css/properties/animation.zig b/src/css/properties/animation.zig index aed8627d78..3d8a5d9ca1 100644 --- a/src/css/properties/animation.zig +++ b/src/css/properties/animation.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Allocator = std.mem.Allocator; const ArrayList = std.ArrayListUnmanaged; @@ -46,8 +46,6 @@ pub const Animation = struct { /// The animation timeline. timeline: AnimationTimeline, - pub usingnamespace css.DefineListShorthand(@This()); - pub const PropertyFieldMap = .{ .name = css.PropertyIdTag.@"animation-name", .duration = css.PropertyIdTag.@"animation-duration", @@ -288,8 +286,8 @@ pub const AnimationIterationCount = union(enum) { /// The animation will repeat forever. infinite, - pub usingnamespace css.DeriveParse(@This()); - pub usingnamespace css.DeriveToCss(@This()); + pub const parse = css.DeriveParse(@This()).parse; + pub const toCss = css.DeriveToCss(@This()).toCss; pub fn default() AnimationIterationCount { return .{ .number = 1.0 }; @@ -311,7 +309,12 @@ pub const AnimationDirection = enum { /// The animation iterations alternate between forward and reverse, with reverse occurring first. @"alternate-reverse", - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; pub fn default() AnimationDirection { return .normal; @@ -325,7 +328,12 @@ pub const AnimationPlayState = enum { /// The animation is paused. paused, - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; pub fn default() AnimationPlayState { return .running; @@ -343,7 +351,12 @@ pub const AnimationFillMode = enum { /// Both forwards and backwards apply. both, - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; pub fn default() AnimationFillMode { return .none; @@ -359,7 +372,12 @@ pub const AnimationComposition = enum { /// The effect value is accumulated onto the underlying value. accumulate, - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; }; /// A value for the [animation-timeline](https://drafts.csswg.org/css-animations-2/#animation-timeline) property. @@ -375,8 +393,8 @@ pub const AnimationTimeline = union(enum) { /// The view() function. view: ViewTimeline, - pub usingnamespace css.DeriveParse(@This()); - pub usingnamespace css.DeriveToCss(@This()); + pub const parse = css.DeriveParse(@This()).parse; + pub const toCss = css.DeriveToCss(@This()).toCss; pub fn eql(lhs: *const @This(), rhs: *const @This()) bool { return css.implementEql(@This(), lhs, rhs); @@ -412,7 +430,12 @@ pub const Scroller = enum { /// Specifies to use the element's own principal box as the scroll container. self, - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; pub fn default() Scroller { return .nearest; @@ -430,7 +453,12 @@ pub const ScrollAxis = enum { /// Specifies to use the measure of progress along the vertical axis of the scroll container. y, - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; pub fn default() ScrollAxis { return .block; diff --git a/src/css/properties/background.zig b/src/css/properties/background.zig index 69c74b3ac9..4b869b0dc8 100644 --- a/src/css/properties/background.zig +++ b/src/css/properties/background.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Allocator = std.mem.Allocator; const ArrayList = std.ArrayListUnmanaged; @@ -234,7 +234,11 @@ pub const Background = struct { } pub fn getNecessaryFallbacks(this: *const @This(), targets: css.targets.Targets) css.ColorFallbackKind { - return this.color.getNecessaryFallbacks(targets).bitwiseOr(this.getImage().getNecessaryFallbacks(targets)); + return bun.bits.@"or"( + css.ColorFallbackKind, + this.color.getNecessaryFallbacks(targets), + this.getImage().getNecessaryFallbacks(targets), + ); } pub inline fn deepClone(this: *const @This(), allocator: Allocator) @This() { @@ -327,8 +331,6 @@ pub const BackgroundPosition = struct { /// The y-position. y: VerticalPosition, - pub usingnamespace css.DefineListShorthand(@This()); - const PropertyFieldMap = .{ .x = css.PropertyIdTag.@"background-position-x", .y = css.PropertyIdTag.@"background-position-y", @@ -448,7 +450,12 @@ pub const BackgroundRepeatKeyword = enum { /// The image is placed once and not repeated in this direction. @"no-repeat", - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; }; /// A value for the [background-attachment](https://www.w3.org/TR/css-backgrounds-3/#background-attachment) property. @@ -460,7 +467,12 @@ pub const BackgroundAttachment = enum { /// The background is fixed with regard to the element's contents. local, - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; pub fn default() @This() { return .scroll; @@ -476,7 +488,12 @@ pub const BackgroundOrigin = enum { /// The position is relative to the content box. @"content-box", - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; }; /// A value for the [background-clip](https://drafts.csswg.org/css-backgrounds-4/#background-clip) property. @@ -492,7 +509,12 @@ pub const BackgroundClip = enum { /// The background is clipped to the text content of the element. text, - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; pub fn default() BackgroundClip { return .@"border-box"; @@ -535,8 +557,6 @@ pub const BackgroundProperty = packed struct(u16) { clip: bool = false, __unused: u7 = 0, - pub usingnamespace css.Bitflags(@This()); - pub const @"background-color" = BackgroundProperty{ .color = true }; pub const @"background-image" = BackgroundProperty{ .image = true }; pub const @"background-position-x" = BackgroundProperty{ .@"position-x" = true }; @@ -560,6 +580,10 @@ pub const BackgroundProperty = packed struct(u16) { .clip = true, }; + pub fn isEmpty(this: @This()) bool { + return bun.bits.asInt(@This(), this) == 0; + } + pub fn tryFromPropertyId(property_id: css.PropertyId) ?BackgroundProperty { return switch (property_id) { .@"background-color" => @"background-color", @@ -646,7 +670,7 @@ pub const BackgroundHandler = struct { if (this.clips) |*clips_and_vp| { var clips: *SmallList(BackgroundClip, 1) = &clips_and_vp.*[0]; const vp: *VendorPrefix = &clips_and_vp.*[1]; - if (!vendor_prefix.eql(vp.*) and !val.eql(clips)) { + if (vendor_prefix != vp.* and !val.eql(clips)) { this.flush(allocator, dest, context); clips.deinit(allocator); this.clips = .{ val.deepClone(allocator), vendor_prefix }; @@ -655,7 +679,7 @@ pub const BackgroundHandler = struct { clips.deinit(allocator); clips.* = val.deepClone(allocator); } - vp.insert(vendor_prefix); + bun.bits.insert(VendorPrefix, vp, vendor_prefix); } } else { this.clips = .{ val.deepClone(allocator), vendor_prefix }; @@ -675,10 +699,10 @@ pub const BackgroundHandler = struct { } var clips_vp = VendorPrefix{ .none = true }; if (this.clips) |*clips_and_vp| { - if (!clips_vp.eql(clips_and_vp.*[1]) and !clips_and_vp.*[0].eql(&clips_and_vp[0])) { + if (clips_vp != clips_and_vp.*[1] and !clips_and_vp.*[0].eql(&clips_and_vp[0])) { this.flush(allocator, dest, context); } else { - clips_vp.insert(clips_and_vp.*[1]); + bun.bits.insert(VendorPrefix, &clips_vp, clips_and_vp.*[1]); } } @@ -718,7 +742,7 @@ pub const BackgroundHandler = struct { var unparsed = val.deepClone(allocator); context.addUnparsedFallbacks(&unparsed); if (BackgroundProperty.tryFromPropertyId(val.property_id)) |prop| { - this.flushed_properties.insert(prop); + bun.bits.insert(BackgroundProperty, &this.flushed_properties, prop); } dest.append(allocator, Property{ .unparsed = unparsed }) catch bun.outOfMemory(); @@ -801,7 +825,7 @@ pub const BackgroundHandler = struct { fn push(self: *BackgroundHandler, alloc: Allocator, d: *css.DeclarationList, comptime property_field_name: []const u8, val: anytype) void { d.append(alloc, @unionInit(Property, property_field_name, val)) catch bun.outOfMemory(); const prop = @field(BackgroundProperty, property_field_name); - self.flushed_properties.insert(prop); + bun.bits.insert(BackgroundProperty, &self.flushed_properties, prop); } }.push; @@ -858,7 +882,7 @@ pub const BackgroundHandler = struct { return clip.* == BackgroundClip.text; } }.predicate)) context.targets.prefixes(clips.*[1], .background_clip) else clips.*[1]; - const clip_property = if (!clip_prefixes.eql(css.VendorPrefix{ .none = true })) + const clip_property = if (clip_prefixes != css.VendorPrefix{ .none = true }) css.Property{ .@"background-clip" = .{ clips.*[0].deepClone(allocator), clip_prefixes } } else null; @@ -883,7 +907,7 @@ pub const BackgroundHandler = struct { .size = size, .attachment = attachment, .origin = origin, - .clip = if (clip_prefixes.eql(css.VendorPrefix{ .none = true })) clip else BackgroundClip.default(), + .clip = if (clip_prefixes == css.VendorPrefix{ .none = true }) clip else BackgroundClip.default(), }); } defer { @@ -897,7 +921,7 @@ pub const BackgroundHandler = struct { clips.*[0].clearRetainingCapacity(); } - if (!this.flushed_properties.intersects(BackgroundProperty.background)) { + if (this.flushed_properties.isEmpty()) { for (backgrounds.getFallbacks(allocator, context.targets).slice()) |fallback| { push(this, allocator, dest, "background", fallback); } @@ -907,7 +931,7 @@ pub const BackgroundHandler = struct { if (clip_property) |clip| { dest.append(allocator, clip) catch bun.outOfMemory(); - this.flushed_properties.insert(BackgroundProperty.@"background-clip"); + this.flushed_properties.clip = true; } this.reset(allocator); @@ -915,9 +939,9 @@ pub const BackgroundHandler = struct { } } - if (bun.take(&maybe_color)) |color_| { - var color: CssColor = color_; - if (!this.flushed_properties.contains(BackgroundProperty.@"background-color")) { + if (bun.take(&maybe_color)) |color_const| { + var color: CssColor = color_const; + if (!this.flushed_properties.color) { for (color.getFallbacks(allocator, context.targets).slice()) |fallback| { push(this, allocator, dest, "background-color", fallback); } @@ -927,7 +951,7 @@ pub const BackgroundHandler = struct { if (bun.take(&maybe_images)) |images_| { var images: css.SmallList(Image, 1) = images_; - if (!this.flushed_properties.contains(BackgroundProperty.@"background-image")) { + if (!this.flushed_properties.image) { var fallbacks = images.getFallbacks(allocator, context.targets); for (fallbacks.slice()) |fallback| { push(this, allocator, dest, "background-image", fallback); @@ -982,7 +1006,7 @@ pub const BackgroundHandler = struct { .@"background-clip" = .{ clips.deepClone(allocator), prefixes }, }, ) catch bun.outOfMemory(); - this.flushed_properties.insert(BackgroundProperty.@"background-clip"); + this.flushed_properties.clip = true; } this.reset(allocator); @@ -1024,7 +1048,7 @@ pub const BackgroundHandler = struct { this.decls.clearRetainingCapacity(); this.flush(allocator, dest, context); - this.flushed_properties = BackgroundProperty.empty(); + this.flushed_properties = BackgroundProperty{}; } }; diff --git a/src/css/properties/border.zig b/src/css/properties/border.zig index aff3d92ad6..1bdf38ed3c 100644 --- a/src/css/properties/border.zig +++ b/src/css/properties/border.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Allocator = std.mem.Allocator; const ArrayList = std.ArrayListUnmanaged; @@ -194,7 +194,12 @@ pub const LineStyle = enum { /// Two parallel solid lines with some space between them. double, - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; pub fn isCompatible(_: *const @This(), _: bun.css.targets.Browsers) bool { return true; @@ -216,8 +221,8 @@ pub const BorderSideWidth = union(enum) { /// An explicit width. length: Length, - pub usingnamespace css.DeriveParse(@This()); - pub usingnamespace css.DeriveToCss(@This()); + pub const parse = css.DeriveParse(@This()).parse; + pub const toCss = css.DeriveToCss(@This()).toCss; pub fn isCompatible(this: *const @This(), browsers: bun.css.targets.Browsers) bool { return switch (this.*) { @@ -250,9 +255,11 @@ pub const BorderColor = struct { left: CssColor, // TODO: bring this back - // pub usingnamespace css.DefineShorthand(@This(), css.PropertyIdTag.@"border-color"); - pub usingnamespace css.DefineRectShorthand(@This(), CssColor); - pub usingnamespace ImplFallbacks(@This()); + // (old using name space) css.DefineShorthand(@This(), css.PropertyIdTag.@"border-color"); + const css_impl = css.DefineRectShorthand(@This(), CssColor); + pub const toCss = css_impl.toCss; + pub const parse = css_impl.parse; + pub const getFallbacks = ImplFallbacks(@This()).getFallbacks; pub const PropertyFieldMap = .{ .top = css.PropertyIdTag.@"border-top-color", @@ -278,8 +285,10 @@ pub const BorderStyle = struct { left: LineStyle, // TODO: bring this back - // pub usingnamespace css.DefineShorthand(@This(), css.PropertyIdTag.@"border-style"); - pub usingnamespace css.DefineRectShorthand(@This(), LineStyle); + // (old using name space) css.DefineShorthand(@This(), css.PropertyIdTag.@"border-style"); + const css_impl = css.DefineRectShorthand(@This(), LineStyle); + pub const toCss = css_impl.toCss; + pub const parse = css_impl.parse; pub const PropertyFieldMap = .{ .top = css.PropertyIdTag.@"border-top-style", @@ -305,8 +314,10 @@ pub const BorderWidth = struct { left: BorderSideWidth, // TODO: bring this back - // pub usingnamespace css.DefineShorthand(@This(), css.PropertyIdTag.@"border-width"); - pub usingnamespace css.DefineRectShorthand(@This(), BorderSideWidth); + // (old using name space) css.DefineShorthand(@This(), css.PropertyIdTag.@"border-width"); + const css_impl = css.DefineRectShorthand(@This(), BorderSideWidth); + pub const toCss = css_impl.toCss; + pub const parse = css_impl.parse; pub const PropertyFieldMap = .{ .top = css.PropertyIdTag.@"border-top-width", @@ -333,9 +344,11 @@ pub const BorderBlockColor = struct { end: CssColor, // TODO: bring this back - // pub usingnamespace css.DefineShorthand(@This(), css.PropertyIdTag.@"border-block-color"); - pub usingnamespace css.DefineSizeShorthand(@This(), CssColor); - pub usingnamespace ImplFallbacks(@This()); + // (old using name space) css.DefineShorthand(@This(), css.PropertyIdTag.@"border-block-color"); + const css_impl = css.DefineSizeShorthand(@This(), CssColor); + pub const toCss = css_impl.toCss; + pub const parse = css_impl.parse; + pub const getFallbacks = ImplFallbacks(@This()).getFallbacks; pub const PropertyFieldMap = .{ .start = css.PropertyIdTag.@"border-block-start-color", @@ -359,8 +372,10 @@ pub const BorderBlockStyle = struct { end: LineStyle, // TODO: bring this back - // pub usingnamespace css.DefineShorthand(@This(), css.PropertyIdTag.@"border-block-style"); - pub usingnamespace css.DefineSizeShorthand(@This(), LineStyle); + // (old using name space) css.DefineShorthand(@This(), css.PropertyIdTag.@"border-block-style"); + const css_impl = css.DefineSizeShorthand(@This(), LineStyle); + pub const toCss = css_impl.toCss; + pub const parse = css_impl.parse; pub const PropertyFieldMap = .{ .start = css.PropertyIdTag.@"border-block-start-style", @@ -384,8 +399,10 @@ pub const BorderBlockWidth = struct { end: BorderSideWidth, // TODO: bring this back - // pub usingnamespace css.DefineShorthand(@This(), css.PropertyIdTag.@"border-block-width"); - pub usingnamespace css.DefineSizeShorthand(@This(), BorderSideWidth); + // (old using name space) css.DefineShorthand(@This(), css.PropertyIdTag.@"border-block-width"); + const css_impl = css.DefineSizeShorthand(@This(), BorderSideWidth); + pub const toCss = css_impl.toCss; + pub const parse = css_impl.parse; pub const PropertyFieldMap = .{ .start = css.PropertyIdTag.@"border-block-start-width", @@ -410,9 +427,11 @@ pub const BorderInlineColor = struct { end: CssColor, // TODO: bring this back - // pub usingnamespace css.DefineShorthand(@This(), css.PropertyIdTag.@"border-inline-color"); - pub usingnamespace css.DefineSizeShorthand(@This(), CssColor); - pub usingnamespace ImplFallbacks(@This()); + // (old using name space) css.DefineShorthand(@This(), css.PropertyIdTag.@"border-inline-color"); + const css_impl = css.DefineSizeShorthand(@This(), CssColor); + pub const toCss = css_impl.toCss; + pub const parse = css_impl.parse; + pub const getFallbacks = ImplFallbacks(@This()).getFallbacks; pub const PropertyFieldMap = .{ .start = css.PropertyIdTag.@"border-inline-start-color", @@ -436,8 +455,10 @@ pub const BorderInlineStyle = struct { end: LineStyle, // TODO: bring this back - // pub usingnamespace css.DefineShorthand(@This(), css.PropertyIdTag.@"border-inline-style"); - pub usingnamespace css.DefineSizeShorthand(@This(), LineStyle); + // (old using name space) css.DefineShorthand(@This(), css.PropertyIdTag.@"border-inline-style"); + const css_impl = css.DefineSizeShorthand(@This(), LineStyle); + pub const toCss = css_impl.toCss; + pub const parse = css_impl.parse; pub const PropertyFieldMap = .{ .start = css.PropertyIdTag.@"border-inline-start-style", @@ -461,8 +482,10 @@ pub const BorderInlineWidth = struct { end: BorderSideWidth, // TODO: bring this back - // pub usingnamespace css.DefineShorthand(@This(), css.PropertyIdTag.@"border-inline-width"); - pub usingnamespace css.DefineSizeShorthand(@This(), BorderSideWidth); + // (old using name space) css.DefineShorthand(@This(), css.PropertyIdTag.@"border-inline-width"); + const css_impl = css.DefineSizeShorthand(@This(), BorderSideWidth); + pub const toCss = css_impl.toCss; + pub const parse = css_impl.parse; pub const PropertyFieldMap = .{ .start = css.PropertyIdTag.@"border-inline-start-width", @@ -479,35 +502,36 @@ pub const BorderInlineWidth = struct { }; pub fn ImplFallbacks(comptime T: type) type { - const field_names = std.meta.fieldNames(T); return struct { + const fields = std.meta.fields(T); + pub fn getFallbacks(this: *T, allocator: std.mem.Allocator, targets: css.Targets) css.SmallList(T, 2) { const ColorFallbackKind = css.css_values.color.ColorFallbackKind; - var fallbacks = ColorFallbackKind.empty(); - inline for (field_names) |name| { - fallbacks.insert(@field(this, name).getNecessaryFallbacks(targets)); + var fallbacks = ColorFallbackKind{}; + inline for (fields) |field| { + bun.bits.insert(ColorFallbackKind, &fallbacks, @field(this, field.name).getNecessaryFallbacks(targets)); } var res = css.SmallList(T, 2){}; - if (fallbacks.contains(ColorFallbackKind{ .rgb = true })) { + if (fallbacks.rgb) { var out: T = undefined; - inline for (field_names) |name| { - @field(out, name) = @field(this, name).getFallback(allocator, ColorFallbackKind{ .rgb = true }); + inline for (fields) |field| { + @field(out, field.name) = @field(this, field.name).getFallback(allocator, ColorFallbackKind{ .rgb = true }); } res.append(allocator, out); } - if (fallbacks.contains(ColorFallbackKind{ .p3 = true })) { + if (fallbacks.p3) { var out: T = undefined; - inline for (field_names) |name| { - @field(out, name) = @field(this, name).getFallback(allocator, ColorFallbackKind{ .p3 = true }); + inline for (fields) |field| { + @field(out, field.name) = @field(this, field.name).getFallback(allocator, ColorFallbackKind{ .p3 = true }); } res.append(allocator, out); } - if (fallbacks.contains(ColorFallbackKind{ .lab = true })) { - inline for (field_names) |name| { - @field(this, name) = @field(this, name).getFallback(allocator, ColorFallbackKind{ .lab = true }); + if (fallbacks.lab) { + inline for (fields) |field| { + @field(this, field.name) = @field(this, field.name).getFallback(allocator, ColorFallbackKind{ .lab = true }); } } @@ -577,8 +601,6 @@ const BorderProperty = packed struct(u32) { @"inline-end-style": bool = false, __unused: u8 = 0, - pub usingnamespace css.Bitflags(@This()); - const @"border-top-color" = BorderProperty{ .@"top-color" = true }; const @"border-bottom-color" = BorderProperty{ .@"bottom-color" = true }; const @"border-left-color" = BorderProperty{ .@"left-color" = true }; @@ -855,13 +877,13 @@ pub const BorderHandler = struct { } inline fn push(f: *FlushContext, comptime p: []const u8, val: anytype) void { - f.self.flushed_properties.insert(@field(BorderProperty, p)); + bun.bits.insert(BorderProperty, &f.self.flushed_properties, @field(BorderProperty, p)); f.dest.append(f.ctx.allocator, @unionInit(css.Property, p, val.deepClone(f.ctx.allocator))) catch bun.outOfMemory(); } inline fn fallbacks(f: *FlushContext, comptime p: []const u8, _val: anytype) void { var val = _val; - if (!f.self.flushed_properties.contains(@field(BorderProperty, p))) { + if (!bun.bits.contains(BorderProperty, f.self.flushed_properties, @field(BorderProperty, p))) { const fbs = val.getFallbacks(f.ctx.allocator, f.ctx.targets); for (css.generic.slice(@TypeOf(fbs), &fbs)) |fallback| { f.dest.append(f.ctx.allocator, @unionInit(css.Property, p, fallback)) catch bun.outOfMemory(); @@ -1400,7 +1422,7 @@ pub const BorderHandler = struct { if (logical_supported) { var up = unparsed.deepClone(context.allocator); context.addUnparsedFallbacks(&up); - this.flushed_properties.insert(BorderProperty.tryFromPropertyId(up.property_id).?); + bun.bits.insert(BorderProperty, &this.flushed_properties, BorderProperty.tryFromPropertyId(up.property_id).?); dest.append(context.allocator, .{ .unparsed = up }) catch bun.outOfMemory(); return; } @@ -1410,7 +1432,7 @@ pub const BorderHandler = struct { _ = d; // autofix var upppppppppp = up.withPropertyId(c.allocator, @unionInit(css.PropertyId, id, {})); c.addUnparsedFallbacks(&upppppppppp); - self.flushed_properties.insert(@field(BorderProperty, id)); + bun.bits.insert(BorderProperty, &self.flushed_properties, @field(BorderProperty, id)); } }.prop; @@ -1459,7 +1481,7 @@ pub const BorderHandler = struct { else => { var up = unparsed.deepClone(context.allocator); context.addUnparsedFallbacks(&up); - this.flushed_properties.insert(BorderProperty.tryFromPropertyId(up.property_id).?); + bun.bits.insert(BorderProperty, &this.flushed_properties, BorderProperty.tryFromPropertyId(up.property_id).?); dest.append(context.allocator, .{ .unparsed = up }) catch bun.outOfMemory(); }, } diff --git a/src/css/properties/border_image.zig b/src/css/properties/border_image.zig index e47112e513..e4f3e678e7 100644 --- a/src/css/properties/border_image.zig +++ b/src/css/properties/border_image.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Allocator = std.mem.Allocator; const ArrayList = std.ArrayListUnmanaged; @@ -40,8 +40,6 @@ pub const BorderImage = struct { /// How the border image is scaled and tiled. repeat: BorderImageRepeat, - pub usingnamespace css.DefineShorthand(@This(), css.PropertyIdTag.@"border-image", PropertyFieldMap); - pub const PropertyFieldMap = .{ .source = css.PropertyIdTag.@"border-image-source", .slice = css.PropertyIdTag.@"border-image-slice", @@ -274,8 +272,8 @@ pub const BorderImageSideWidth = union(enum) { /// The `auto` keyword, representing the natural width of the image slice. auto: void, - pub usingnamespace css.DeriveParse(@This()); - pub usingnamespace css.DeriveToCss(@This()); + pub const parse = css.DeriveParse(@This()).parse; + pub const toCss = css.DeriveToCss(@This()).toCss; pub fn deinit(this: *const BorderImageSideWidth, allocator: std.mem.Allocator) void { switch (this.*) { @@ -329,7 +327,12 @@ pub const BorderImageRepeatKeyword = enum { /// The image is repeated so that it fits, and then spaced apart evenly. space, - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; pub fn isCompatible(this: *const @This(), browsers: css.targets.Browsers) bool { return switch (this.*) { @@ -406,8 +409,6 @@ pub const BorderImageProperty = packed struct(u8) { pub const @"border-image-outset" = BorderImageProperty{ .outset = true }; pub const @"border-image-repeat" = BorderImageProperty{ .repeat = true }; - pub usingnamespace css.Bitflags(@This()); - pub const @"border-image" = BorderImageProperty{ .source = true, .slice = true, @@ -416,6 +417,10 @@ pub const BorderImageProperty = packed struct(u8) { .repeat = true, }; + pub fn isEmpty(this: BorderImageProperty) bool { + return @as(u8, @bitCast(this)) == 0; + } + pub fn tryFromPropertyId(property_id: css.PropertyIdTag) ?BorderImageProperty { inline for (std.meta.fields(BorderImageProperty)) |field| { if (comptime std.mem.eql(u8, field.name, "__unused")) continue; @@ -439,8 +444,8 @@ pub const BorderImageHandler = struct { width: ?Rect(BorderImageSideWidth) = null, outset: ?Rect(LengthOrNumber) = null, repeat: ?BorderImageRepeat = null, - vendor_prefix: css.VendorPrefix = css.VendorPrefix.empty(), - flushed_properties: BorderImageProperty = BorderImageProperty.empty(), + vendor_prefix: css.VendorPrefix = .{}, + flushed_properties: BorderImageProperty = .{}, has_any: bool = false, pub fn handleProperty(this: *@This(), property: *const css.Property, dest: *css.DeclarationList, context: *css.PropertyHandlerContext) bool { @@ -462,7 +467,7 @@ pub const BorderImageHandler = struct { const propertyHelper = struct { inline fn propertyHelper(self: *BorderImageHandler, comptime field: []const u8, comptime T: type, val: *const T, d: *css.DeclarationList, ctx: *css.PropertyHandlerContext) void { - if (!self.vendor_prefix.eql(VendorPrefix{ .none = true })) { + if (self.vendor_prefix != VendorPrefix{ .none = true }) { self.flush(d, ctx); } @@ -495,7 +500,7 @@ pub const BorderImageHandler = struct { this.width = val.width.deepClone(allocator); this.outset = val.outset.deepClone(allocator); this.repeat = val.repeat.deepClone(allocator); - this.vendor_prefix = this.vendor_prefix.bitwiseOr(vp); + this.vendor_prefix = bun.bits.@"or"(VendorPrefix, this.vendor_prefix, vp); this.has_any = true; }, .unparsed => |unparsed| { @@ -510,7 +515,7 @@ pub const BorderImageHandler = struct { unparsed.deepClone(allocator); context.addUnparsedFallbacks(&unparsed_clone); - this.flushed_properties.insert(BorderImageProperty.tryFromPropertyId(unparsed_clone.property_id).?); + bun.bits.insert(BorderImageProperty, &this.flushed_properties, BorderImageProperty.tryFromPropertyId(unparsed_clone.property_id).?); dest.append(allocator, Property{ .unparsed = unparsed_clone }) catch bun.outOfMemory(); } else return false; }, @@ -522,7 +527,7 @@ pub const BorderImageHandler = struct { pub fn finalize(this: *@This(), dest: *css.DeclarationList, context: *css.PropertyHandlerContext) void { this.flush(dest, context); - this.flushed_properties = BorderImageProperty.empty(); + this.flushed_properties = BorderImageProperty{}; } pub fn reset(this: *@This(), allocator: std.mem.Allocator) void { @@ -545,7 +550,7 @@ pub const BorderImageHandler = struct { .@"border-image-width", .@"border-image-outset", .@"border-image-repeat", - => !this.vendor_prefix.eql(VendorPrefix{ .none = true }), + => this.vendor_prefix != VendorPrefix{ .none = true }, .unparsed => |val| isBorderImageProperty(val.property_id), else => false, }; @@ -573,15 +578,15 @@ pub const BorderImageHandler = struct { }; var prefix = this.vendor_prefix; - if (prefix.contains(css.VendorPrefix{ .none = true }) and !border_image.slice.fill) { + if (prefix.none and !border_image.slice.fill) { prefix = context.targets.prefixes(this.vendor_prefix, css.prefixes.Feature.border_image); - if (!this.flushed_properties.intersects(BorderImageProperty.@"border-image")) { + if (this.flushed_properties.isEmpty()) { const fallbacks = border_image.getFallbacks(allocator, context.targets).slice(); for (fallbacks) |fallback| { // Match prefix of fallback. e.g. -webkit-linear-gradient // can only be used in -webkit-border-image, not -moz-border-image. // However, if border-image is unprefixed, gradients can still be. - var p = fallback.source.getVendorPrefix().intersect(prefix); + var p = bun.bits.@"and"(VendorPrefix, fallback.source.getVendorPrefix(), prefix); if (p.isEmpty()) { p = prefix; } @@ -590,47 +595,47 @@ pub const BorderImageHandler = struct { } } - const p = border_image.source.getVendorPrefix().intersect(prefix); + const p = bun.bits.@"and"(css.VendorPrefix, border_image.source.getVendorPrefix(), prefix); if (!p.isEmpty()) { prefix = p; } dest.append(allocator, Property{ .@"border-image" = .{ border_image, prefix } }) catch bun.outOfMemory(); - this.flushed_properties.insert(BorderImageProperty.@"border-image"); + bun.bits.insert(BorderImageProperty, &this.flushed_properties, BorderImageProperty.@"border-image"); } else { if (source) |*mut_source| { - if (!this.flushed_properties.contains(BorderImageProperty.@"border-image-source")) { + if (!bun.bits.contains(BorderImageProperty, this.flushed_properties, BorderImageProperty.@"border-image-source")) { for (mut_source.getFallbacks(allocator, context.targets).slice()) |fallback| { dest.append(allocator, Property{ .@"border-image-source" = fallback }) catch bun.outOfMemory(); } } dest.append(allocator, Property{ .@"border-image-source" = mut_source.* }) catch bun.outOfMemory(); - this.flushed_properties.insert(BorderImageProperty.@"border-image-source"); + bun.bits.insert(BorderImageProperty, &this.flushed_properties, BorderImageProperty.@"border-image-source"); } if (slice) |s| { dest.append(allocator, Property{ .@"border-image-slice" = s }) catch bun.outOfMemory(); - this.flushed_properties.insert(BorderImageProperty.@"border-image-slice"); + bun.bits.insert(BorderImageProperty, &this.flushed_properties, BorderImageProperty.@"border-image-slice"); } if (width) |w| { dest.append(allocator, Property{ .@"border-image-width" = w }) catch bun.outOfMemory(); - this.flushed_properties.insert(BorderImageProperty.@"border-image-width"); + bun.bits.insert(BorderImageProperty, &this.flushed_properties, BorderImageProperty.@"border-image-width"); } if (outset) |o| { dest.append(allocator, Property{ .@"border-image-outset" = o }) catch bun.outOfMemory(); - this.flushed_properties.insert(BorderImageProperty.@"border-image-outset"); + bun.bits.insert(BorderImageProperty, &this.flushed_properties, BorderImageProperty.@"border-image-outset"); } if (repeat) |r| { dest.append(allocator, Property{ .@"border-image-repeat" = r }) catch bun.outOfMemory(); - this.flushed_properties.insert(BorderImageProperty.@"border-image-repeat"); + bun.bits.insert(BorderImageProperty, &this.flushed_properties, BorderImageProperty.@"border-image-repeat"); } } - this.vendor_prefix = VendorPrefix.empty(); + this.vendor_prefix = VendorPrefix{}; } }; diff --git a/src/css/properties/border_radius.zig b/src/css/properties/border_radius.zig index ec35e73618..c9694f13f8 100644 --- a/src/css/properties/border_radius.zig +++ b/src/css/properties/border_radius.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Allocator = std.mem.Allocator; const ArrayList = std.ArrayListUnmanaged; @@ -38,7 +38,7 @@ pub const BorderRadius = struct { /// The x and y radius values for the bottom left corner. bottom_left: Size2D(LengthPercentage), - pub usingnamespace css.DefineShorthand(@This(), css.PropertyIdTag.@"border-radius", PropertyFieldMap); + // (old using name space) css.DefineShorthand(@This(), css.PropertyIdTag.@"border-radius", PropertyFieldMap); pub const PropertyFieldMap = .{ .top_left = "border-top-left-radius", @@ -203,10 +203,10 @@ pub const BorderRadiusHandler = struct { }, prefix, } }) catch bun.outOfMemory(); - top_left.?[1].remove(intersection); - top_right.?[1].remove(intersection); - bottom_right.?[1].remove(intersection); - bottom_left.?[1].remove(intersection); + bun.bits.remove(VendorPrefix, &top_left.?[1], intersection); + bun.bits.remove(VendorPrefix, &top_right.?[1], intersection); + bun.bits.remove(VendorPrefix, &bottom_right.?[1], intersection); + bun.bits.remove(VendorPrefix, &bottom_left.?[1], intersection); } } @@ -237,7 +237,7 @@ pub const BorderRadiusHandler = struct { if (logical_supported) { d.append(ctx.allocator, v) catch bun.outOfMemory(); } else { - const prefix = ctx.targets.prefixes(css.VendorPrefix.empty(), css.prefixes.Feature.border_radius); + const prefix = ctx.targets.prefixes(css.VendorPrefix{}, css.prefixes.Feature.border_radius); switch (v) { .@"border-start-start-radius", .@"border-start-end-radius", @@ -267,7 +267,7 @@ pub const BorderRadiusHandler = struct { // If two vendor prefixes for the same property have different // values, we need to flush what we have immediately to preserve order. if (@field(self, prop)) |*existing| { - if (!existing.*[0].eql(val) and !existing.*[1].contains(vp)) { + if (!existing.*[0].eql(val) and !bun.bits.contains(VendorPrefix, existing.*[1], vp)) { self.flush(d, ctx); } } diff --git a/src/css/properties/box_shadow.zig b/src/css/properties/box_shadow.zig index 472ca82ee8..feeb4fe4f3 100644 --- a/src/css/properties/box_shadow.zig +++ b/src/css/properties/box_shadow.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Allocator = std.mem.Allocator; const ArrayList = std.ArrayListUnmanaged; @@ -159,7 +159,7 @@ pub const BoxShadowHandler = struct { if (this.box_shadows) |*bxs| { const val: *SmallList(BoxShadow, 1) = &bxs.*[0]; const prefixes: *VendorPrefix = &bxs.*[1]; - if (!val.eql(box_shadows) and !prefixes.contains(prefix)) { + if (!val.eql(box_shadows) and !bun.bits.contains(VendorPrefix, prefixes.*, prefix)) { this.flush(dest, context); this.box_shadows = .{ box_shadows.deepClone(context.allocator), @@ -167,7 +167,7 @@ pub const BoxShadowHandler = struct { }; } else { val.* = box_shadows.deepClone(context.allocator); - prefixes.insert(prefix); + bun.bits.insert(VendorPrefix, prefixes, prefix); } } else { this.box_shadows = .{ @@ -208,12 +208,12 @@ pub const BoxShadowHandler = struct { if (!this.flushed) { const ColorFallbackKind = css.ColorFallbackKind; var prefixes = context.targets.prefixes(prefixes2, Feature.box_shadow); - var fallbacks = ColorFallbackKind.empty(); + var fallbacks = ColorFallbackKind{}; for (box_shadows.slice()) |*shadow| { - fallbacks.insert(shadow.color.getNecessaryFallbacks(context.targets)); + bun.bits.insert(ColorFallbackKind, &fallbacks, shadow.color.getNecessaryFallbacks(context.targets)); } - if (fallbacks.contains(ColorFallbackKind{ .rgb = true })) { + if (fallbacks.rgb) { var rgb = SmallList(BoxShadow, 1).initCapacity(context.allocator, box_shadows.len()); rgb.setLen(box_shadows.len()); for (box_shadows.slice(), rgb.slice_mut()) |*input, *output| { @@ -226,7 +226,7 @@ pub const BoxShadowHandler = struct { } dest.append(context.allocator, .{ .@"box-shadow" = .{ rgb, prefixes } }) catch bun.outOfMemory(); - if (prefixes.contains(VendorPrefix.NONE)) { + if (prefixes.none) { prefixes = VendorPrefix.NONE; } else { // Only output RGB for prefixed property (e.g. -webkit-box-shadow) @@ -234,7 +234,7 @@ pub const BoxShadowHandler = struct { } } - if (fallbacks.contains(ColorFallbackKind.P3)) { + if (fallbacks.p3) { var p3 = SmallList(BoxShadow, 1).initCapacity(context.allocator, box_shadows.len()); p3.setLen(box_shadows.len()); for (box_shadows.slice(), p3.slice_mut()) |*input, *output| { @@ -248,7 +248,7 @@ pub const BoxShadowHandler = struct { dest.append(context.allocator, .{ .@"box-shadow" = .{ p3, VendorPrefix.NONE } }) catch bun.outOfMemory(); } - if (fallbacks.contains(ColorFallbackKind.LAB)) { + if (fallbacks.lab) { var lab = SmallList(BoxShadow, 1).initCapacity(context.allocator, box_shadows.len()); lab.setLen(box_shadows.len()); for (box_shadows.slice(), lab.slice_mut()) |*input, *output| { diff --git a/src/css/properties/contain.zig b/src/css/properties/contain.zig index a095c5228c..c2b23000cb 100644 --- a/src/css/properties/contain.zig +++ b/src/css/properties/contain.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Allocator = std.mem.Allocator; const ArrayList = std.ArrayListUnmanaged; diff --git a/src/css/properties/css_modules.zig b/src/css/properties/css_modules.zig index bbb09c06d8..e8d731250e 100644 --- a/src/css/properties/css_modules.zig +++ b/src/css/properties/css_modules.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Allocator = std.mem.Allocator; const ArrayList = std.ArrayListUnmanaged; diff --git a/src/css/properties/custom.zig b/src/css/properties/custom.zig index 18b67d2d40..b55ade8a70 100644 --- a/src/css/properties/custom.zig +++ b/src/css/properties/custom.zig @@ -1,6 +1,6 @@ const std = @import("std"); const Allocator = std.mem.Allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const logger = bun.logger; const Log = logger.Log; @@ -625,17 +625,17 @@ pub const TokenList = struct { // the original declaration. The remaining fallbacks need to be added as @supports rules. var fallbacks = this.getNecessaryFallbacks(targets); const lowest_fallback = fallbacks.lowest(); - fallbacks.remove(lowest_fallback); + bun.bits.remove(ColorFallbackKind, &fallbacks, lowest_fallback); var res = css.SmallList(Fallbacks, 2){}; - if (fallbacks.contains(ColorFallbackKind.P3)) { + if (fallbacks.p3) { res.appendAssumeCapacity(.{ ColorFallbackKind.P3.supportsCondition(), this.getFallback(allocator, ColorFallbackKind.P3), }); } - if (fallbacks.contains(ColorFallbackKind.LAB)) { + if (fallbacks.lab) { res.appendAssumeCapacity(.{ ColorFallbackKind.LAB.supportsCondition(), this.getFallback(allocator, ColorFallbackKind.LAB), @@ -670,23 +670,23 @@ pub const TokenList = struct { } pub fn getNecessaryFallbacks(this: *const TokenList, targets: css.targets.Targets) ColorFallbackKind { - var fallbacks = ColorFallbackKind.empty(); + var fallbacks = ColorFallbackKind{}; for (this.v.items) |*token_or_value| { switch (token_or_value.*) { .color => |*color| { - fallbacks.insert(color.getPossibleFallbacks(targets)); + bun.bits.insert(ColorFallbackKind, &fallbacks, color.getPossibleFallbacks(targets)); }, .function => |*f| { - fallbacks.insert(f.arguments.getNecessaryFallbacks(targets)); + bun.bits.insert(ColorFallbackKind, &fallbacks, f.arguments.getNecessaryFallbacks(targets)); }, .@"var" => |*v| { if (v.fallback) |*fallback| { - fallbacks.insert(fallback.getNecessaryFallbacks(targets)); + bun.bits.insert(ColorFallbackKind, &fallbacks, fallback.getNecessaryFallbacks(targets)); } }, .env => |*v| { if (v.fallback) |*fallback| { - fallbacks.insert(fallback.getNecessaryFallbacks(targets)); + bun.bits.insert(ColorFallbackKind, &fallbacks, fallback.getNecessaryFallbacks(targets)); } }, else => {}, @@ -1265,11 +1265,12 @@ pub const UAEnvironmentVariable = enum { /// The viewport segment right position. @"viewport-segment-right", - pub usingnamespace css.DefineEnumProperty(@This()); - - pub fn eql(lhs: *const @This(), rhs: *const @This()) bool { - return css.implementEql(@This(), lhs, rhs); - } + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; }; /// A custom CSS function. diff --git a/src/css/properties/display.zig b/src/css/properties/display.zig index 3671d346fe..475d347463 100644 --- a/src/css/properties/display.zig +++ b/src/css/properties/display.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Allocator = std.mem.Allocator; const ArrayList = std.ArrayListUnmanaged; @@ -34,8 +34,8 @@ pub const Display = union(enum) { /// The inside and outside display values. pair: DisplayPair, - pub usingnamespace css.DeriveParse(@This()); - pub usingnamespace css.DeriveToCss(@This()); + pub const parse = css.DeriveParse(@This()).parse; + pub const toCss = css.DeriveToCss(@This()).toCss; pub fn deepClone(this: *const @This(), allocator: std.mem.Allocator) @This() { return css.implementDeepClone(@This(), this, allocator); @@ -59,7 +59,12 @@ pub const Visibility = enum { /// The element is collapsed. collapse, - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; }; /// A `display` keyword. @@ -81,7 +86,12 @@ pub const DisplayKeyword = enum { @"ruby-base-container", @"ruby-text-container", - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; }; /// A pair of inside and outside display values, as used in the `display` property. @@ -174,7 +184,7 @@ pub const DisplayPair = struct { return dest.writeStr("inline-table"); } else if (this.outside == .@"inline" and this.inside == .flex and !this.is_list_item) { try this.inside.flex.toCss(W, dest); - if (this.inside.flex.eql(css.VendorPrefix{ .ms = true })) { + if (this.inside.flex == css.VendorPrefix{ .ms = true }) { return dest.writeStr("inline-flexbox"); } else { return dest.writeStr("inline-flex"); @@ -224,7 +234,12 @@ pub const DisplayOutside = enum { @"inline", @"run-in", - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; }; /// A [``](https://drafts.csswg.org/css-display-3/#typedef-display-inside) value. @@ -271,7 +286,7 @@ pub const DisplayInside = union(enum) { .table => try dest.writeStr("table"), .flex => |prefix| { try prefix.toCss(W, dest); - if (prefix.eql(css.VendorPrefix{ .ms = true })) { + if (prefix == css.VendorPrefix{ .ms = true }) { try dest.writeStr("flexbox"); } else { try dest.writeStr("flex"); diff --git a/src/css/properties/effects.zig b/src/css/properties/effects.zig index 34da8b7759..50d4a91cac 100644 --- a/src/css/properties/effects.zig +++ b/src/css/properties/effects.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Allocator = std.mem.Allocator; const ArrayList = std.ArrayListUnmanaged; diff --git a/src/css/properties/flex.zig b/src/css/properties/flex.zig index c63f759702..2937f24bbc 100644 --- a/src/css/properties/flex.zig +++ b/src/css/properties/flex.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Allocator = std.mem.Allocator; const ArrayList = std.ArrayListUnmanaged; @@ -50,7 +50,12 @@ pub const FlexDirection = enum { /// Flex items are laid out in a column, and reversed. @"column-reverse", - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; pub fn default() FlexDirection { return .row; @@ -76,7 +81,12 @@ pub const FlexWrap = enum { /// The flex items wrap, in reverse. @"wrap-reverse", - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; pub fn default() FlexWrap { return .nowrap; @@ -94,7 +104,7 @@ pub const FlexFlow = struct { /// How the flex items wrap. wrap: FlexWrap, - pub usingnamespace css.DefineShorthand(@This(), css.PropertyIdTag.@"flex-flow", PropertyFieldMap); + // (old using name space) css.DefineShorthand(@This(), css.PropertyIdTag.@"flex-flow", PropertyFieldMap); pub const PropertyFieldMap = .{ .direction = css.PropertyIdTag.@"flex-direction", @@ -170,7 +180,7 @@ pub const Flex = struct { /// The flex basis. basis: LengthPercentageOrAuto, - pub usingnamespace css.DefineShorthand(@This(), css.PropertyIdTag.flex, PropertyFieldMap); + // (old using name space) css.DefineShorthand(@This(), css.PropertyIdTag.flex, PropertyFieldMap); pub const PropertyFieldMap = .{ .grow = css.PropertyIdTag.@"flex-grow", @@ -289,7 +299,12 @@ pub const BoxOrient = enum { /// Items are laid out along the block axis, according to the writing direction. @"block-axis", - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; }; /// A value for the legacy (prefixed) [box-direction](https://www.w3.org/TR/2009/WD-css3-flexbox-20090723/#displayorder) property. @@ -300,7 +315,12 @@ pub const BoxDirection = enum { /// Items flow in the reverse direction. reverse, - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; }; pub const FlexAlign = BoxAlign; @@ -321,7 +341,12 @@ pub const BoxAlign = enum { /// Items are stretched. stretch, - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; pub fn fromStandard(@"align": *const css.css_properties.@"align".AlignItems) ?BoxAlign { return switch (@"align".*) { @@ -351,7 +376,12 @@ pub const BoxPack = enum { /// Items are justified to the start and end. justify, - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; pub fn fromStandard(justify: *const css.css_properties.@"align".JustifyContent) ?BoxPack { return switch (justify.*) { @@ -379,7 +409,12 @@ pub const BoxLines = enum { /// Items may wrap into multiple lines. multiple, - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; pub fn fromStandard(wrap: *const FlexWrap) ?BoxLines { return switch (wrap.*) { @@ -407,7 +442,12 @@ pub const FlexPack = enum { /// Items are distributed evenly, with half size spaces on either end. distribute, - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; pub fn fromStandard(justify: *const css.css_properties.@"align".JustifyContent) ?FlexPack { return switch (justify.*) { @@ -444,7 +484,12 @@ pub const FlexItemAlign = enum { /// The item is stretched. stretch, - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; pub fn fromStandard(justify: *const css.css_properties.@"align".AlignSelf) ?FlexItemAlign { return switch (justify.*) { @@ -479,7 +524,12 @@ pub const FlexLinePack = enum { /// Content is stretched. stretch, - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; pub fn fromStandard(justify: *const css.css_properties.@"align".AlignContent) ?FlexLinePack { return switch (justify.*) { @@ -554,7 +604,7 @@ pub const FlexHandler = struct { // If two vendor prefixes for the same property have different // values, we need to flush what we have immediately to preserve order. if (@field(self, prop)) |*field| { - if (!std.meta.eql(field[0], val.*) and !field[1].contains(vp.*)) { + if (!std.meta.eql(field[0], val.*) and !bun.bits.contains(css.VendorPrefix, field[1], vp.*)) { self.flush(d, ctx); } } @@ -575,7 +625,7 @@ pub const FlexHandler = struct { // Otherwise, update the value and add the prefix if (@field(self, prop)) |*field| { field[0] = css.generic.deepClone(@TypeOf(val.*), val, ctx.allocator); - field[1].insert(vp.*); + bun.bits.insert(css.VendorPrefix, &field[1], vp.*); } else { @field(self, prop) = .{ css.generic.deepClone(@TypeOf(val.*), val, ctx.allocator), @@ -713,12 +763,12 @@ pub const FlexHandler = struct { const dir = val[0]; if (context.targets.browsers) |targets| { const prefixes = context.targets.prefixes(css.VendorPrefix.NONE, css.prefixes.Feature.flex_direction); - var prefixes_2009 = css.VendorPrefix.empty(); + var prefixes_2009 = css.VendorPrefix{}; if (isFlex2009(targets)) { - prefixes_2009.insert(css.VendorPrefix.WEBKIT); + prefixes_2009.webkit = true; } - if (prefixes.contains(css.VendorPrefix.MOZ)) { - prefixes_2009.insert(css.VendorPrefix.MOZ); + if (prefixes.moz) { + prefixes_2009.moz = true; } if (!prefixes_2009.isEmpty()) { const orient, const newdir = dir.to2009(); @@ -738,7 +788,7 @@ pub const FlexHandler = struct { if (!intersection.isEmpty()) { var prefix = context.targets.prefixes(intersection, css.prefixes.Feature.flex_flow); // Firefox only implemented the 2009 spec prefixed. - prefix.remove(css.VendorPrefix.MOZ); + prefix.moz = false; dest.append(context.allocator, Property{ .@"flex-flow" = .{ FlexFlow{ .direction = dir.*, @@ -746,8 +796,8 @@ pub const FlexHandler = struct { }, prefix, } }) catch bun.outOfMemory(); - dir_prefix.remove(intersection); - wrap_prefix.remove(intersection); + bun.bits.remove(css.VendorPrefix, dir_prefix, intersection); + bun.bits.remove(css.VendorPrefix, wrap_prefix, intersection); } } @@ -758,12 +808,12 @@ pub const FlexHandler = struct { if (grow) |val| { const g = val[0]; const prefixes = context.targets.prefixes(css.VendorPrefix.NONE, css.prefixes.Feature.flex_grow); - var prefixes_2009 = css.VendorPrefix.empty(); + var prefixes_2009 = css.VendorPrefix{}; if (isFlex2009(targets)) { - prefixes_2009.insert(css.VendorPrefix.WEBKIT); + prefixes_2009.webkit = true; } - if (prefixes.contains(css.VendorPrefix.MOZ)) { - prefixes_2009.insert(css.VendorPrefix.MOZ); + if (prefixes.moz) { + prefixes_2009.moz = true; } if (!prefixes_2009.isEmpty()) { dest.append(context.allocator, Property{ .@"box-flex" = .{ g, prefixes_2009 } }) catch bun.outOfMemory(); @@ -783,7 +833,7 @@ pub const FlexHandler = struct { if (!intersection.isEmpty()) { var prefix = context.targets.prefixes(intersection, css.prefixes.Feature.flex); // Firefox only implemented the 2009 spec prefixed. - prefix.remove(css.VendorPrefix.MOZ); + prefix.moz = false; dest.append(context.allocator, Property{ .flex = .{ Flex{ .grow = g, @@ -792,9 +842,9 @@ pub const FlexHandler = struct { }, prefix, } }) catch bun.outOfMemory(); - g_prefix.remove(intersection); - s_prefix.remove(intersection); - b_prefix.remove(intersection); + bun.bits.remove(css.VendorPrefix, g_prefix, intersection); + bun.bits.remove(css.VendorPrefix, s_prefix, intersection); + bun.bits.remove(css.VendorPrefix, b_prefix, intersection); } } @@ -821,15 +871,15 @@ pub const FlexHandler = struct { if (!prefix.isEmpty()) { prefix = ctx.targets.prefixes(prefix, @field(css.prefixes.Feature, feature_name)); if (comptime prop_2009) |p2009| { - if (prefix.contains(css.VendorPrefix.NONE)) { + if (prefix.none) { // 2009 spec, implemented by webkit and firefox if (ctx.targets.browsers) |targets| { - var prefixes_2009 = css.VendorPrefix.empty(); + var prefixes_2009 = css.VendorPrefix{}; if (isFlex2009(targets)) { - prefixes_2009.insert(css.VendorPrefix.WEBKIT); + prefixes_2009.webkit = true; } - if (prefix.contains(css.VendorPrefix.MOZ)) { - prefixes_2009.insert(css.VendorPrefix.MOZ); + if (prefix.moz) { + prefixes_2009.moz = true; } if (!prefixes_2009.isEmpty()) { const s = brk: { @@ -850,7 +900,7 @@ pub const FlexHandler = struct { if (comptime prop_2012) |p2012| { var ms = true; - if (prefix.contains(css.VendorPrefix.MS)) { + if (prefix.ms) { dest.append(ctx.allocator, @unionInit(Property, p2012, .{ val, css.VendorPrefix.MS, @@ -859,12 +909,12 @@ pub const FlexHandler = struct { } if (!ms) { - prefix.remove(css.VendorPrefix.MS); + prefix.ms = false; } } // Firefox only implemented the 2009 spec prefixed. - prefix.remove(css.VendorPrefix.MOZ); + prefix.moz = false; dest.append(ctx.allocator, @unionInit(Property, prop, .{ val, prefix, diff --git a/src/css/properties/font.zig b/src/css/properties/font.zig index 407bba9ff5..0a85eb265b 100644 --- a/src/css/properties/font.zig +++ b/src/css/properties/font.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Allocator = std.mem.Allocator; pub const css = @import("../css_parser.zig"); @@ -48,8 +48,8 @@ pub const FontWeight = union(enum) { lighter, // TODO: implement this - pub usingnamespace css.DeriveParse(@This()); - pub usingnamespace css.DeriveToCss(@This()); + pub const parse = css.DeriveParse(@This()).parse; + pub const toCss = css.DeriveToCss(@This()).toCss; pub inline fn default() FontWeight { return .{ .absolute = AbsoluteFontWeight.default() }; @@ -83,7 +83,7 @@ pub const AbsoluteFontWeight = union(enum) { /// Same as `700`. bold, - pub usingnamespace css.DeriveParse(@This()); + pub const parse = css.DeriveParse(@This()).parse; pub fn toCss(this: *const AbsoluteFontWeight, comptime W: type, dest: *css.Printer(W)) css.PrintErr!void { return switch (this.*) { @@ -122,8 +122,8 @@ pub const FontSize = union(enum) { /// A relative font size keyword. relative: RelativeFontSize, - pub usingnamespace css.DeriveParse(@This()); - pub usingnamespace css.DeriveToCss(@This()); + pub const parse = css.DeriveParse(@This()).parse; + pub const toCss = css.DeriveToCss(@This()).toCss; pub fn isCompatible(this: *const FontSize, browsers: bun.css.targets.Browsers) bool { return switch (this.*) { @@ -170,7 +170,12 @@ pub const AbsoluteFontSize = enum { /// "xxx-large" @"xxx-large", - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; pub fn isCompatible(this: *const AbsoluteFontSize, browsers: bun.css.targets.Browsers) bool { return switch (this.*) { @@ -188,7 +193,12 @@ pub const RelativeFontSize = enum { smaller, larger, - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; }; /// A value for the [font-stretch](https://www.w3.org/TR/css-fonts-4/#font-stretch-prop) property. @@ -199,7 +209,7 @@ pub const FontStretch = union(enum) { percentage: Percentage, // TODO: implement this - pub usingnamespace css.DeriveParse(@This()); + pub const parse = css.DeriveParse(@This()).parse; pub fn toCss(this: *const FontStretch, comptime W: type, dest: *css.Printer(W)) css.PrintErr!void { if (dest.minify) { @@ -264,7 +274,12 @@ pub const FontStretchKeyword = enum { /// 200% @"ultra-expanded", - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; pub inline fn default() FontStretchKeyword { return .normal; @@ -433,7 +448,12 @@ pub const GenericFontFamily = enum { revert, @"revert-layer", - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; pub fn isCompatible(this: *const GenericFontFamily, browsers: bun.css.targets.Browsers) bool { return switch (this.*) { @@ -531,7 +551,12 @@ pub const FontVariantCaps = enum { /// Uses titling capitals. @"titling-caps", - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; pub fn default() FontVariantCaps { return .normal; @@ -569,8 +594,8 @@ pub const LineHeight = union(enum) { /// An explicit height. length: LengthPercentage, - pub usingnamespace @call(.auto, css.DeriveParse, .{@This()}); - pub usingnamespace @call(.auto, css.DeriveToCss, .{@This()}); + pub const parse = css.DeriveParse(@This()).parse; + pub const toCss = css.DeriveToCss(@This()).toCss; pub fn isCompatible(this: *const LineHeight, browsers: bun.css.targets.Browsers) bool { return switch (this.*) { @@ -609,7 +634,7 @@ pub const Font = struct { /// How the text should be capitalized. Only CSS 2.1 values are supported. variant_caps: FontVariantCaps, - pub usingnamespace css.DefineShorthand(@This(), css.PropertyIdTag.font, PropertyFieldMap); + // (old using name space) css.DefineShorthand(@This(), css.PropertyIdTag.font, PropertyFieldMap); pub const PropertyFieldMap = .{ .family = css.PropertyIdTag.@"font-family", @@ -776,7 +801,12 @@ pub const VerticalAlignKeyword = enum { /// Align the bottom of the box with the bottom of the parent’s content area. @"text-bottom", - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; }; pub const FontProperty = packed struct(u8) { @@ -789,8 +819,6 @@ pub const FontProperty = packed struct(u8) { @"font-variant-caps": bool = false, __unused: u1 = 0, - pub usingnamespace css.Bitflags(@This()); - const FONT = FontProperty{ .@"font-family" = true, .@"font-size" = true, @@ -865,7 +893,7 @@ pub const FontHandler = struct { .unparsed => |*val| { if (isFontProperty(val.property_id)) { this.flush(dest, context); - this.flushed_properties.insert(FontProperty.tryFromPropertyId(val.property_id).?); + bun.bits.insert(FontProperty, &this.flushed_properties, FontProperty.tryFromPropertyId(val.property_id).?); dest.append(context.allocator, property.*) catch bun.outOfMemory(); } else { return false; @@ -904,20 +932,18 @@ pub const FontHandler = struct { this.flushed_properties = .{}; } - fn flush(this: *FontHandler, decls: *css.DeclarationList, context: *css.PropertyHandlerContext) void { - const push = struct { - fn push(self: *FontHandler, d: *css.DeclarationList, ctx: *css.PropertyHandlerContext, comptime prop: []const u8, val: anytype) void { - d.append(ctx.allocator, @unionInit(css.Property, prop, val)) catch bun.outOfMemory(); - var insertion: FontProperty = .{}; - if (comptime std.mem.eql(u8, prop, "font")) { - insertion = FontProperty.FONT; - } else { - @field(insertion, prop) = true; - } - self.flushed_properties.insert(insertion); - } - }.push; + fn push(self: *FontHandler, d: *css.DeclarationList, ctx: *css.PropertyHandlerContext, comptime prop: []const u8, val: anytype) void { + d.append(ctx.allocator, @unionInit(css.Property, prop, val)) catch bun.outOfMemory(); + var insertion: FontProperty = .{}; + if (comptime std.mem.eql(u8, prop, "font")) { + insertion = FontProperty.FONT; + } else { + @field(insertion, prop) = true; + } + bun.bits.insert(FontProperty, &self.flushed_properties, insertion); + } + fn flush(this: *FontHandler, decls: *css.DeclarationList, context: *css.PropertyHandlerContext) void { if (!this.has_any) { return; } @@ -925,7 +951,7 @@ pub const FontHandler = struct { this.has_any = false; var family: ?bun.BabyList(FontFamily) = bun.take(&this.family); - if (!this.flushed_properties.contains(FontProperty{ .@"font-family" = true })) { + if (!this.flushed_properties.@"font-family") { family = compatibleFontFamily(context.allocator, family, !context.targets.shouldCompileSame(.font_family_system_ui)); } diff --git a/src/css/properties/generate_properties.ts b/src/css/properties/generate_properties.ts index 27cdf01526..404d26b6a4 100644 --- a/src/css/properties/generate_properties.ts +++ b/src/css/properties/generate_properties.ts @@ -111,7 +111,8 @@ function generatePropertyImpl(property_defs: Record): strin const required_functions = ["deepClone", "parse", "toCss", "eql"]; return ` - pub usingnamespace PropertyImpl(); + // Copy manually implemented functions. + pub const toCss = properties_impl.property_mixin.toCss // Sanity check to make sure all types have the following functions: // - deepClone() @@ -120,7 +121,7 @@ function generatePropertyImpl(property_defs: Record): strin // - toCss() // // We do this string concatenation thing so we get all the errors at once, - // instead of relying on Zig semantic analysis which usualy stops at the first error. + // instead of relying on Zig semantic analysis which usually stops at the first error. comptime { const compile_error: []const u8 = compile_error: { var compile_error: []const u8 = ""; @@ -358,7 +359,11 @@ ${Object.entries(property_defs) unparsed, custom: CustomPropertyName, -pub usingnamespace PropertyIdImpl(); + // Copy manually implemented functions. + pub const toCss = properties_impl.property_id_mixin.toCss; + pub const parse = properties_impl.property_id_mixin.toCss; + pub const fromString = properties_impl.property_id_mixin.toCss; + pub const fromStr = fromString; ${generatePropertyIdImpl(property_defs)} };`; @@ -383,7 +388,7 @@ function generatePropertyIdImpl(property_defs: Record): str pub fn prefix(this: *const PropertyId) VendorPrefix { return switch (this.*) { ${generatePropertyIdImplPrefix(property_defs)} - .all, .custom, .unparsed => VendorPrefix.empty(), + .all, .custom, .unparsed => VendorPrefix{}, }; } @@ -475,7 +480,7 @@ function generatePropertyIdImpl(property_defs: Record): str function generatePropertyIdImplPrefix(property_defs: Record): string { return Object.entries(property_defs) .map(([name, meta]) => { - if (meta.valid_prefixes === undefined) return `.${escapeIdent(name)} => VendorPrefix.empty(),`; + if (meta.valid_prefixes === undefined) return `.${escapeIdent(name)} => VendorPrefix{},`; return `.${escapeIdent(name)} => |p| p,`; }) .join("\n"); @@ -1780,7 +1785,7 @@ generateCode({ function prelude() { return /* zig */ `const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Allocator = std.mem.Allocator; pub const css = @import("../css_parser.zig"); @@ -1789,9 +1794,7 @@ const Printer = css.Printer; const PrintErr = css.PrintErr; const VendorPrefix = css.VendorPrefix; - -const PropertyImpl = @import("./properties_impl.zig").PropertyImpl; -const PropertyIdImpl = @import("./properties_impl.zig").PropertyIdImpl; +const properties_impl = @import("./properties_impl.zig"); const CSSWideKeyword = css.css_properties.CSSWideKeyword; const UnparsedProperty = css.css_properties.custom.UnparsedProperty; diff --git a/src/css/properties/grid.zig b/src/css/properties/grid.zig index a4b2d60773..ee5345b049 100644 --- a/src/css/properties/grid.zig +++ b/src/css/properties/grid.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Allocator = std.mem.Allocator; const ArrayList = std.ArrayListUnmanaged; @@ -47,8 +47,8 @@ pub const TrackSizing = union(enum) { /// A list of grid tracks. tracklist: TrackList, - pub usingnamespace css.DeriveParse(@This()); - pub usingnamespace css.DeriveToCss(@This()); + pub const parse = css.DeriveParse(@This()).parse; + pub const toCss = css.DeriveToCss(@This()).toCss; }; /// A [``](https://drafts.csswg.org/css-grid-2/#typedef-track-list) value, @@ -449,8 +449,8 @@ pub const RepeatCount = union(enum) { /// The `auto-fit` keyword. @"auto-fit", - pub usingnamespace css.DeriveParse(@This()); - pub usingnamespace css.DeriveToCss(@This()); + pub const parse = css.DeriveParse(@This()).parse; + pub const toCss = css.DeriveToCss(@This()).toCss; pub fn eql(this: *const @This(), other: *const @This()) bool { return css.implementEql(@This(), this, other); diff --git a/src/css/properties/list.zig b/src/css/properties/list.zig index 9c6e488a4f..c59884c392 100644 --- a/src/css/properties/list.zig +++ b/src/css/properties/list.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Allocator = std.mem.Allocator; const ArrayList = std.ArrayListUnmanaged; diff --git a/src/css/properties/margin_padding.zig b/src/css/properties/margin_padding.zig index 523a674d17..a8d6473505 100644 --- a/src/css/properties/margin_padding.zig +++ b/src/css/properties/margin_padding.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Allocator = std.mem.Allocator; const ArrayList = std.ArrayListUnmanaged; @@ -41,8 +41,10 @@ pub const Inset = struct { left: LengthPercentageOrAuto, // TODO: bring this back - // pub usingnamespace css.DefineShorthand(@This(), css.PropertyIdTag.inset); - pub usingnamespace css.DefineRectShorthand(@This(), LengthPercentageOrAuto); + // (old using name space) css.DefineShorthand(@This(), css.PropertyIdTag.inset); + const css_impl = css.DefineRectShorthand(@This(), LengthPercentageOrAuto); + pub const toCss = css_impl.toCss; + pub const parse = css_impl.parse; pub const PropertyFieldMap = .{ .top = css.PropertyIdTag.top, @@ -68,8 +70,10 @@ pub const InsetBlock = struct { block_end: LengthPercentageOrAuto, // TODO: bring this back - // pub usingnamespace css.DefineShorthand(@This(), css.PropertyIdTag.@"inset-block"); - pub usingnamespace css.DefineSizeShorthand(@This(), LengthPercentageOrAuto); + // (old using name space) css.DefineShorthand(@This(), css.PropertyIdTag.@"inset-block"); + const css_impl = css.DefineSizeShorthand(@This(), LengthPercentageOrAuto); + pub const toCss = css_impl.toCss; + pub const parse = css_impl.parse; pub const PropertyFieldMap = .{ .block_start = css.PropertyIdTag.@"inset-block-start", @@ -98,8 +102,10 @@ pub const InsetInline = struct { }; // TODO: bring this back - // pub usingnamespace css.DefineShorthand(@This(), css.PropertyIdTag.@"inset-inline"); - pub usingnamespace css.DefineSizeShorthand(@This(), LengthPercentageOrAuto); + // (old using name space) css.DefineShorthand(@This(), css.PropertyIdTag.@"inset-inline"); + const css_impl = css.DefineSizeShorthand(@This(), LengthPercentageOrAuto); + pub const toCss = css_impl.toCss; + pub const parse = css_impl.parse; pub fn deepClone(this: *const @This(), allocator: std.mem.Allocator) @This() { return css.implementDeepClone(@This(), this, allocator); @@ -118,8 +124,10 @@ pub const MarginBlock = struct { block_end: LengthPercentageOrAuto, // TODO: bring this back - // pub usingnamespace css.DefineShorthand(@This(), css.PropertyIdTag.@"margin-block"); - pub usingnamespace css.DefineSizeShorthand(@This(), LengthPercentageOrAuto); + // (old using name space) css.DefineShorthand(@This(), css.PropertyIdTag.@"margin-block"); + const css_impl = css.DefineSizeShorthand(@This(), LengthPercentageOrAuto); + pub const toCss = css_impl.toCss; + pub const parse = css_impl.parse; pub const PropertyFieldMap = .{ .block_start = css.PropertyIdTag.@"margin-block-start", @@ -143,8 +151,10 @@ pub const MarginInline = struct { inline_end: LengthPercentageOrAuto, // TODO: bring this back - // pub usingnamespace css.DefineShorthand(@This(), css.PropertyIdTag.@"margin-inline"); - pub usingnamespace css.DefineSizeShorthand(@This(), LengthPercentageOrAuto); + // (old using name space) css.DefineShorthand(@This(), css.PropertyIdTag.@"margin-inline"); + const css_impl = css.DefineSizeShorthand(@This(), LengthPercentageOrAuto); + pub const toCss = css_impl.toCss; + pub const parse = css_impl.parse; pub const PropertyFieldMap = .{ .inline_start = css.PropertyIdTag.@"margin-inline-start", @@ -168,8 +178,10 @@ pub const Margin = struct { left: LengthPercentageOrAuto, // TODO: bring this back - // pub usingnamespace css.DefineShorthand(@This(), css.PropertyIdTag.margin); - pub usingnamespace css.DefineRectShorthand(@This(), LengthPercentageOrAuto); + // (old using name space) css.DefineShorthand(@This(), css.PropertyIdTag.margin); + const css_impl = css.DefineRectShorthand(@This(), LengthPercentageOrAuto); + pub const toCss = css_impl.toCss; + pub const parse = css_impl.parse; pub const PropertyFieldMap = .{ .top = css.PropertyIdTag.@"margin-top", @@ -195,8 +207,10 @@ pub const PaddingBlock = struct { block_end: LengthPercentageOrAuto, // TODO: bring this back - // pub usingnamespace css.DefineShorthand(@This(), css.PropertyIdTag.@"padding-block"); - pub usingnamespace css.DefineSizeShorthand(@This(), LengthPercentageOrAuto); + // (old using name space) css.DefineShorthand(@This(), css.PropertyIdTag.@"padding-block"); + const css_impl = css.DefineSizeShorthand(@This(), LengthPercentageOrAuto); + pub const toCss = css_impl.toCss; + pub const parse = css_impl.parse; pub const PropertyFieldMap = .{ .block_start = css.PropertyIdTag.@"padding-block-start", @@ -220,8 +234,10 @@ pub const PaddingInline = struct { inline_end: LengthPercentageOrAuto, // TODO: bring this back - // pub usingnamespace css.DefineShorthand(@This(), css.PropertyIdTag.@"padding-inline"); - pub usingnamespace css.DefineSizeShorthand(@This(), LengthPercentageOrAuto); + // (old using name space) css.DefineShorthand(@This(), css.PropertyIdTag.@"padding-inline"); + const css_impl = css.DefineSizeShorthand(@This(), LengthPercentageOrAuto); + pub const toCss = css_impl.toCss; + pub const parse = css_impl.parse; pub const PropertyFieldMap = .{ .inline_start = css.PropertyIdTag.@"padding-inline-start", @@ -245,8 +261,10 @@ pub const Padding = struct { left: LengthPercentageOrAuto, // TODO: bring this back - // pub usingnamespace css.DefineShorthand(@This(), css.PropertyIdTag.padding); - pub usingnamespace css.DefineRectShorthand(@This(), LengthPercentageOrAuto); + // (old using name space) css.DefineShorthand(@This(), css.PropertyIdTag.padding); + const css_impl = css.DefineRectShorthand(@This(), LengthPercentageOrAuto); + pub const toCss = css_impl.toCss; + pub const parse = css_impl.parse; pub const PropertyFieldMap = .{ .top = css.PropertyIdTag.@"padding-top", @@ -272,8 +290,10 @@ pub const ScrollMarginBlock = struct { block_end: LengthPercentageOrAuto, // TODO: bring this back - // pub usingnamespace css.DefineShorthand(@This(), css.PropertyIdTag.@"scroll-margin-block"); - pub usingnamespace css.DefineSizeShorthand(@This(), LengthPercentageOrAuto); + // (old using name space) css.DefineShorthand(@This(), css.PropertyIdTag.@"scroll-margin-block"); + const css_impl = css.DefineSizeShorthand(@This(), LengthPercentageOrAuto); + pub const toCss = css_impl.toCss; + pub const parse = css_impl.parse; pub const PropertyFieldMap = .{ .block_start = css.PropertyIdTag.@"scroll-margin-block-start", @@ -297,8 +317,10 @@ pub const ScrollMarginInline = struct { inline_end: LengthPercentageOrAuto, // TODO: bring this back - // pub usingnamespace css.DefineShorthand(@This(), css.PropertyIdTag.@"scroll-margin-inline"); - pub usingnamespace css.DefineSizeShorthand(@This(), LengthPercentageOrAuto); + // (old using name space) css.DefineShorthand(@This(), css.PropertyIdTag.@"scroll-margin-inline"); + const css_impl = css.DefineSizeShorthand(@This(), LengthPercentageOrAuto); + pub const toCss = css_impl.toCss; + pub const parse = css_impl.parse; pub const PropertyFieldMap = .{ .inline_start = css.PropertyIdTag.@"scroll-margin-inline-start", @@ -322,8 +344,10 @@ pub const ScrollMargin = struct { left: LengthPercentageOrAuto, // TODO: bring this back - // pub usingnamespace css.DefineShorthand(@This(), css.PropertyIdTag.@"scroll-margin"); - pub usingnamespace css.DefineRectShorthand(@This(), LengthPercentageOrAuto); + // (old using name space) css.DefineShorthand(@This(), css.PropertyIdTag.@"scroll-margin"); + const css_impl = css.DefineRectShorthand(@This(), LengthPercentageOrAuto); + pub const toCss = css_impl.toCss; + pub const parse = css_impl.parse; pub const PropertyFieldMap = .{ .top = css.PropertyIdTag.@"scroll-margin-top", @@ -349,8 +373,10 @@ pub const ScrollPaddingBlock = struct { block_end: LengthPercentageOrAuto, // TODO: bring this back - // pub usingnamespace css.DefineShorthand(@This(), css.PropertyIdTag.@"scroll-padding-block"); - pub usingnamespace css.DefineSizeShorthand(@This(), LengthPercentageOrAuto); + // (old using name space) css.DefineShorthand(@This(), css.PropertyIdTag.@"scroll-padding-block"); + const css_impl = css.DefineSizeShorthand(@This(), LengthPercentageOrAuto); + pub const toCss = css_impl.toCss; + pub const parse = css_impl.parse; pub const PropertyFieldMap = .{ .block_start = css.PropertyIdTag.@"scroll-padding-block-start", @@ -374,8 +400,10 @@ pub const ScrollPaddingInline = struct { inline_end: LengthPercentageOrAuto, // TODO: bring this back - // pub usingnamespace css.DefineShorthand(@This(), css.PropertyIdTag.@"scroll-padding-inline"); - pub usingnamespace css.DefineSizeShorthand(@This(), LengthPercentageOrAuto); + // (old using name space) css.DefineShorthand(@This(), css.PropertyIdTag.@"scroll-padding-inline"); + const css_impl = css.DefineSizeShorthand(@This(), LengthPercentageOrAuto); + pub const toCss = css_impl.toCss; + pub const parse = css_impl.parse; pub const PropertyFieldMap = .{ .inline_start = css.PropertyIdTag.@"scroll-padding-inline-start", @@ -399,8 +427,10 @@ pub const ScrollPadding = struct { left: LengthPercentageOrAuto, // TODO: bring this back - // pub usingnamespace css.DefineShorthand(@This(), css.PropertyIdTag.@"scroll-padding"); - pub usingnamespace css.DefineRectShorthand(@This(), LengthPercentageOrAuto); + // (old using name space) css.DefineShorthand(@This(), css.PropertyIdTag.@"scroll-padding"); + const css_impl = css.DefineRectShorthand(@This(), LengthPercentageOrAuto); + pub const toCss = css_impl.toCss; + pub const parse = css_impl.parse; pub const PropertyFieldMap = .{ .top = css.PropertyIdTag.@"scroll-padding-top", diff --git a/src/css/properties/masking.zig b/src/css/properties/masking.zig index 84062e63f9..6e637ffa18 100644 --- a/src/css/properties/masking.zig +++ b/src/css/properties/masking.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Allocator = std.mem.Allocator; const ArrayList = std.ArrayListUnmanaged; @@ -79,7 +79,12 @@ pub const GeometryBox = enum { /// Uses the nearest SVG viewport as reference box. @"view-box", - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; pub fn intoMaskClip(this: *const @This()) MaskClip { return MaskClip{ .@"geometry-box" = this.* }; @@ -166,7 +171,12 @@ pub const MaskMode = enum { /// If an SVG source is used, the value matches the `mask-type` property. Otherwise, the alpha values are used. @"match-source", - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; pub fn default() MaskMode { return .@"match-source"; @@ -180,8 +190,8 @@ pub const MaskClip = union(enum) { /// The painted content is not clipped. @"no-clip", - pub usingnamespace @call(.auto, css.DeriveParse, .{@This()}); - pub usingnamespace @call(.auto, css.DeriveToCss, .{@This()}); + pub const parse = css.DeriveParse(@This()).parse; + pub const toCss = css.DeriveToCss(@This()).toCss; pub fn eql(lhs: *const @This(), rhs: *const @This()) bool { return css.implementEql(@This(), lhs, rhs); @@ -203,7 +213,12 @@ pub const MaskComposite = enum { /// The non-overlapping regions of source and destination are combined. exclude, - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; pub fn default() MaskComposite { return .add; @@ -217,7 +232,12 @@ pub const MaskType = enum { /// The alpha values of the mask is used. alpha, - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; }; /// A value for the [mask](https://www.w3.org/TR/css-masking-1/#the-mask) shorthand property. @@ -239,8 +259,6 @@ pub const Mask = struct { /// How the mask image is interpreted. mode: MaskMode, - pub usingnamespace css.DefineListShorthand(@This()); - pub const PropertyFieldMap = .{ .image = css.PropertyIdTag.@"mask-image", .position = css.PropertyIdTag.@"mask-position", @@ -404,7 +422,12 @@ pub const MaskBorderMode = enum { /// The alpha values of the mask image is used. alpha, - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; pub fn default() @This() { return .alpha; @@ -427,7 +450,7 @@ pub const MaskBorder = struct { /// How the mask image is interpreted. mode: MaskBorderMode, - pub usingnamespace css.DefineShorthand(@This(), css.PropertyIdTag.@"mask-border", PropertyFieldMap); + // (old using name space) css.DefineShorthand(@This(), css.PropertyIdTag.@"mask-border", PropertyFieldMap); pub const PropertyFieldMap = .{ .source = css.PropertyIdTag.@"mask-border-source", @@ -520,7 +543,12 @@ pub const WebKitMaskComposite = enum { /// Equivalent to `exclude` in the standard `mask-composite` syntax. xor, - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; }; /// A value for the [-webkit-mask-source-type](https://github.com/WebKit/WebKit/blob/6eece09a1c31e47489811edd003d1e36910e9fd3/Source/WebCore/css/CSSProperties.json#L6578-L6587) @@ -539,7 +567,12 @@ pub const WebKitMaskSourceType = enum { /// The alpha values of the mask image is used. alpha, - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; }; pub fn getWebkitMaskProperty(property_id: *const css.PropertyId) ?css.PropertyId { diff --git a/src/css/properties/outline.zig b/src/css/properties/outline.zig index cf98f18c6f..c7b3cd2063 100644 --- a/src/css/properties/outline.zig +++ b/src/css/properties/outline.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Allocator = std.mem.Allocator; const ArrayList = std.ArrayListUnmanaged; @@ -42,8 +42,8 @@ pub const OutlineStyle = union(enum) { /// A value equivalent to the `border-style` property. line_style: LineStyle, - pub usingnamespace css.DeriveParse(@This()); - pub usingnamespace css.DeriveToCss(@This()); + pub const parse = css.DeriveParse(@This()).parse; + pub const toCss = css.DeriveToCss(@This()).toCss; pub fn default() @This() { return .{ .line_style = .none }; diff --git a/src/css/properties/overflow.zig b/src/css/properties/overflow.zig index 39b246b9d4..9e969cf1bc 100644 --- a/src/css/properties/overflow.zig +++ b/src/css/properties/overflow.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Allocator = std.mem.Allocator; const ArrayList = std.ArrayListUnmanaged; @@ -82,7 +82,12 @@ pub const OverflowKeyword = enum { /// Overflowing content scrolls if needed. auto, - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; }; /// A value for the [text-overflow](https://www.w3.org/TR/css-overflow-3/#text-overflow) property. @@ -92,5 +97,10 @@ pub const TextOverflow = enum { /// Overflowing text is truncated with an ellipsis. ellipsis, - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; }; diff --git a/src/css/properties/position.zig b/src/css/properties/position.zig index 2eeb39147b..c1270d900b 100644 --- a/src/css/properties/position.zig +++ b/src/css/properties/position.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Allocator = std.mem.Allocator; const ArrayList = std.ArrayListUnmanaged; diff --git a/src/css/properties/prefix_handler.zig b/src/css/properties/prefix_handler.zig index a5ba88ff16..df0ab0dda8 100644 --- a/src/css/properties/prefix_handler.zig +++ b/src/css/properties/prefix_handler.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Allocator = std.mem.Allocator; pub const css = @import("../css_parser.zig"); diff --git a/src/css/properties/properties.zig b/src/css/properties/properties.zig index de4c86c79d..f7c06a5a7c 100644 --- a/src/css/properties/properties.zig +++ b/src/css/properties/properties.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Allocator = std.mem.Allocator; const css = @import("../css_parser.zig"); const Printer = css.Printer; @@ -59,7 +59,12 @@ pub const CSSWideKeyword = enum { /// Rolls back the cascade to the value of the previous cascade layer. @"revert-layer", - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; }; // pub fn DefineProperties(comptime properties: anytype) type { @@ -220,7 +225,7 @@ pub const CSSWideKeyword = enum { // const prop = @field(properties, field.name); // const allowed_prefixes = allowed_prefixes: { // var prefixes: css.VendorPrefix = if (@hasField(@TypeOf(prop), "unprefixed") and !prop.unprefixed) -// css.VendorPrefix.empty() +// css.VendorPrefix{} // else // css.VendorPrefix{ .none = true }; diff --git a/src/css/properties/properties_generated.zig b/src/css/properties/properties_generated.zig index 65a3d3a1e2..957a71c5c9 100644 --- a/src/css/properties/properties_generated.zig +++ b/src/css/properties/properties_generated.zig @@ -1,15 +1,15 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Allocator = std.mem.Allocator; pub const css = @import("../css_parser.zig"); +const bits = bun.bits; const Printer = css.Printer; const PrintErr = css.PrintErr; const VendorPrefix = css.VendorPrefix; -const PropertyImpl = @import("./properties_impl.zig").PropertyImpl; -const PropertyIdImpl = @import("./properties_impl.zig").PropertyIdImpl; +const properties_impl = @import("./properties_impl.zig"); const CSSWideKeyword = css.css_properties.CSSWideKeyword; const UnparsedProperty = css.css_properties.custom.UnparsedProperty; @@ -508,7 +508,7 @@ pub const Property = union(PropertyIdTag) { unparsed: UnparsedProperty, custom: CustomProperty, - pub usingnamespace PropertyImpl(); + pub const toCss = properties_impl.property_mixin.toCss; // Sanity check to make sure all types have the following functions: // - deepClone() @@ -7116,11 +7116,11 @@ pub const Property = union(PropertyIdTag) { .@"inset-inline" => |*v| return v.longhand(property_id), .inset => |*v| return v.longhand(property_id), .@"border-radius" => |*v| { - if (!v[1].eq(property_id.prefix())) return null; + if (!(v[1] == property_id.prefix())) return null; return v[0].longhand(property_id); }, .@"border-image" => |*v| { - if (!v[1].eq(property_id.prefix())) return null; + if (!(v[1] == property_id.prefix())) return null; return v[0].longhand(property_id); }, .@"border-color" => |*v| return v.longhand(property_id), @@ -7145,11 +7145,11 @@ pub const Property = union(PropertyIdTag) { .@"border-inline-end" => |*v| return v.longhand(property_id), .outline => |*v| return v.longhand(property_id), .@"flex-flow" => |*v| { - if (!v[1].eq(property_id.prefix())) return null; + if (!(v[1] == property_id.prefix())) return null; return v[0].longhand(property_id); }, .flex => |*v| { - if (!v[1].eq(property_id.prefix())) return null; + if (!(v[1] == property_id.prefix())) return null; return v[0].longhand(property_id); }, .@"place-content" => |*v| return v.longhand(property_id), @@ -7170,11 +7170,11 @@ pub const Property = union(PropertyIdTag) { .@"scroll-padding" => |*v| return v.longhand(property_id), .font => |*v| return v.longhand(property_id), .transition => |*v| { - if (!v[1].eq(property_id.prefix())) return null; + if (!(v[1] == property_id.prefix())) return null; return v[0].longhand(property_id); }, .mask => |*v| { - if (!v[1].eq(property_id.prefix())) return null; + if (!(v[1] == property_id.prefix())) return null; return v[0].longhand(property_id); }, .@"mask-border" => |*v| return v.longhand(property_id), @@ -7194,10 +7194,10 @@ pub const Property = union(PropertyIdTag) { .@"background-size" => |*v| css.generic.eql(SmallList(background.BackgroundSize, 1), v, &rhs.@"background-size"), .@"background-repeat" => |*v| css.generic.eql(SmallList(background.BackgroundRepeat, 1), v, &rhs.@"background-repeat"), .@"background-attachment" => |*v| css.generic.eql(SmallList(background.BackgroundAttachment, 1), v, &rhs.@"background-attachment"), - .@"background-clip" => |*v| css.generic.eql(SmallList(background.BackgroundClip, 1), &v[0], &rhs.@"background-clip"[0]) and v[1].eq(rhs.@"background-clip"[1]), + .@"background-clip" => |*v| css.generic.eql(SmallList(background.BackgroundClip, 1), &v[0], &rhs.@"background-clip"[0]) and v[1] == rhs.@"background-clip"[1], .@"background-origin" => |*v| css.generic.eql(SmallList(background.BackgroundOrigin, 1), v, &rhs.@"background-origin"), .background => |*v| css.generic.eql(SmallList(background.Background, 1), v, &rhs.background), - .@"box-shadow" => |*v| css.generic.eql(SmallList(box_shadow.BoxShadow, 1), &v[0], &rhs.@"box-shadow"[0]) and v[1].eq(rhs.@"box-shadow"[1]), + .@"box-shadow" => |*v| css.generic.eql(SmallList(box_shadow.BoxShadow, 1), &v[0], &rhs.@"box-shadow"[0]) and v[1] == rhs.@"box-shadow"[1], .opacity => |*v| css.generic.eql(css.css_values.alpha.AlphaValue, v, &rhs.opacity), .color => |*v| css.generic.eql(CssColor, v, &rhs.color), .display => |*v| css.generic.eql(display.Display, v, &rhs.display), @@ -7214,12 +7214,12 @@ pub const Property = union(PropertyIdTag) { .@"min-inline-size" => |*v| css.generic.eql(size.Size, v, &rhs.@"min-inline-size"), .@"max-block-size" => |*v| css.generic.eql(size.MaxSize, v, &rhs.@"max-block-size"), .@"max-inline-size" => |*v| css.generic.eql(size.MaxSize, v, &rhs.@"max-inline-size"), - .@"box-sizing" => |*v| css.generic.eql(size.BoxSizing, &v[0], &rhs.@"box-sizing"[0]) and v[1].eq(rhs.@"box-sizing"[1]), + .@"box-sizing" => |*v| css.generic.eql(size.BoxSizing, &v[0], &rhs.@"box-sizing"[0]) and v[1] == rhs.@"box-sizing"[1], .@"aspect-ratio" => |*v| css.generic.eql(size.AspectRatio, v, &rhs.@"aspect-ratio"), .overflow => |*v| css.generic.eql(overflow.Overflow, v, &rhs.overflow), .@"overflow-x" => |*v| css.generic.eql(overflow.OverflowKeyword, v, &rhs.@"overflow-x"), .@"overflow-y" => |*v| css.generic.eql(overflow.OverflowKeyword, v, &rhs.@"overflow-y"), - .@"text-overflow" => |*v| css.generic.eql(overflow.TextOverflow, &v[0], &rhs.@"text-overflow"[0]) and v[1].eq(rhs.@"text-overflow"[1]), + .@"text-overflow" => |*v| css.generic.eql(overflow.TextOverflow, &v[0], &rhs.@"text-overflow"[0]) and v[1] == rhs.@"text-overflow"[1], .position => |*v| css.generic.eql(position.Position, v, &rhs.position), .top => |*v| css.generic.eql(LengthPercentageOrAuto, v, &rhs.top), .bottom => |*v| css.generic.eql(LengthPercentageOrAuto, v, &rhs.bottom), @@ -7257,21 +7257,21 @@ pub const Property = union(PropertyIdTag) { .@"border-block-end-width" => |*v| css.generic.eql(BorderSideWidth, v, &rhs.@"border-block-end-width"), .@"border-inline-start-width" => |*v| css.generic.eql(BorderSideWidth, v, &rhs.@"border-inline-start-width"), .@"border-inline-end-width" => |*v| css.generic.eql(BorderSideWidth, v, &rhs.@"border-inline-end-width"), - .@"border-top-left-radius" => |*v| css.generic.eql(Size2D(LengthPercentage), &v[0], &rhs.@"border-top-left-radius"[0]) and v[1].eq(rhs.@"border-top-left-radius"[1]), - .@"border-top-right-radius" => |*v| css.generic.eql(Size2D(LengthPercentage), &v[0], &rhs.@"border-top-right-radius"[0]) and v[1].eq(rhs.@"border-top-right-radius"[1]), - .@"border-bottom-left-radius" => |*v| css.generic.eql(Size2D(LengthPercentage), &v[0], &rhs.@"border-bottom-left-radius"[0]) and v[1].eq(rhs.@"border-bottom-left-radius"[1]), - .@"border-bottom-right-radius" => |*v| css.generic.eql(Size2D(LengthPercentage), &v[0], &rhs.@"border-bottom-right-radius"[0]) and v[1].eq(rhs.@"border-bottom-right-radius"[1]), + .@"border-top-left-radius" => |*v| css.generic.eql(Size2D(LengthPercentage), &v[0], &rhs.@"border-top-left-radius"[0]) and (v[1] == rhs.@"border-top-left-radius"[1]), + .@"border-top-right-radius" => |*v| css.generic.eql(Size2D(LengthPercentage), &v[0], &rhs.@"border-top-right-radius"[0]) and (v[1] == rhs.@"border-top-right-radius"[1]), + .@"border-bottom-left-radius" => |*v| css.generic.eql(Size2D(LengthPercentage), &v[0], &rhs.@"border-bottom-left-radius"[0]) and (v[1] == rhs.@"border-bottom-left-radius"[1]), + .@"border-bottom-right-radius" => |*v| css.generic.eql(Size2D(LengthPercentage), &v[0], &rhs.@"border-bottom-right-radius"[0]) and (v[1] == rhs.@"border-bottom-right-radius"[1]), .@"border-start-start-radius" => |*v| css.generic.eql(Size2D(LengthPercentage), v, &rhs.@"border-start-start-radius"), .@"border-start-end-radius" => |*v| css.generic.eql(Size2D(LengthPercentage), v, &rhs.@"border-start-end-radius"), .@"border-end-start-radius" => |*v| css.generic.eql(Size2D(LengthPercentage), v, &rhs.@"border-end-start-radius"), .@"border-end-end-radius" => |*v| css.generic.eql(Size2D(LengthPercentage), v, &rhs.@"border-end-end-radius"), - .@"border-radius" => |*v| css.generic.eql(BorderRadius, &v[0], &rhs.@"border-radius"[0]) and v[1].eq(rhs.@"border-radius"[1]), + .@"border-radius" => |*v| css.generic.eql(BorderRadius, &v[0], &rhs.@"border-radius"[0]) and (v[1] == rhs.@"border-radius"[1]), .@"border-image-source" => |*v| css.generic.eql(Image, v, &rhs.@"border-image-source"), .@"border-image-outset" => |*v| css.generic.eql(Rect(LengthOrNumber), v, &rhs.@"border-image-outset"), .@"border-image-repeat" => |*v| css.generic.eql(BorderImageRepeat, v, &rhs.@"border-image-repeat"), .@"border-image-width" => |*v| css.generic.eql(Rect(BorderImageSideWidth), v, &rhs.@"border-image-width"), .@"border-image-slice" => |*v| css.generic.eql(BorderImageSlice, v, &rhs.@"border-image-slice"), - .@"border-image" => |*v| css.generic.eql(BorderImage, &v[0], &rhs.@"border-image"[0]) and v[1].eq(rhs.@"border-image"[1]), + .@"border-image" => |*v| css.generic.eql(BorderImage, &v[0], &rhs.@"border-image"[0]) and (v[1] == rhs.@"border-image"[1]), .@"border-color" => |*v| css.generic.eql(BorderColor, v, &rhs.@"border-color"), .@"border-style" => |*v| css.generic.eql(BorderStyle, v, &rhs.@"border-style"), .@"border-width" => |*v| css.generic.eql(BorderWidth, v, &rhs.@"border-width"), @@ -7296,42 +7296,42 @@ pub const Property = union(PropertyIdTag) { .@"outline-color" => |*v| css.generic.eql(CssColor, v, &rhs.@"outline-color"), .@"outline-style" => |*v| css.generic.eql(OutlineStyle, v, &rhs.@"outline-style"), .@"outline-width" => |*v| css.generic.eql(BorderSideWidth, v, &rhs.@"outline-width"), - .@"flex-direction" => |*v| css.generic.eql(FlexDirection, &v[0], &rhs.@"flex-direction"[0]) and v[1].eq(rhs.@"flex-direction"[1]), - .@"flex-wrap" => |*v| css.generic.eql(FlexWrap, &v[0], &rhs.@"flex-wrap"[0]) and v[1].eq(rhs.@"flex-wrap"[1]), - .@"flex-flow" => |*v| css.generic.eql(FlexFlow, &v[0], &rhs.@"flex-flow"[0]) and v[1].eq(rhs.@"flex-flow"[1]), - .@"flex-grow" => |*v| css.generic.eql(CSSNumber, &v[0], &rhs.@"flex-grow"[0]) and v[1].eq(rhs.@"flex-grow"[1]), - .@"flex-shrink" => |*v| css.generic.eql(CSSNumber, &v[0], &rhs.@"flex-shrink"[0]) and v[1].eq(rhs.@"flex-shrink"[1]), - .@"flex-basis" => |*v| css.generic.eql(LengthPercentageOrAuto, &v[0], &rhs.@"flex-basis"[0]) and v[1].eq(rhs.@"flex-basis"[1]), - .flex => |*v| css.generic.eql(Flex, &v[0], &rhs.flex[0]) and v[1].eq(rhs.flex[1]), - .order => |*v| css.generic.eql(CSSInteger, &v[0], &rhs.order[0]) and v[1].eq(rhs.order[1]), - .@"align-content" => |*v| css.generic.eql(AlignContent, &v[0], &rhs.@"align-content"[0]) and v[1].eq(rhs.@"align-content"[1]), - .@"justify-content" => |*v| css.generic.eql(JustifyContent, &v[0], &rhs.@"justify-content"[0]) and v[1].eq(rhs.@"justify-content"[1]), + .@"flex-direction" => |*v| css.generic.eql(FlexDirection, &v[0], &rhs.@"flex-direction"[0]) and (v[1] == rhs.@"flex-direction"[1]), + .@"flex-wrap" => |*v| css.generic.eql(FlexWrap, &v[0], &rhs.@"flex-wrap"[0]) and (v[1] == rhs.@"flex-wrap"[1]), + .@"flex-flow" => |*v| css.generic.eql(FlexFlow, &v[0], &rhs.@"flex-flow"[0]) and (v[1] == rhs.@"flex-flow"[1]), + .@"flex-grow" => |*v| css.generic.eql(CSSNumber, &v[0], &rhs.@"flex-grow"[0]) and (v[1] == rhs.@"flex-grow"[1]), + .@"flex-shrink" => |*v| css.generic.eql(CSSNumber, &v[0], &rhs.@"flex-shrink"[0]) and (v[1] == rhs.@"flex-shrink"[1]), + .@"flex-basis" => |*v| css.generic.eql(LengthPercentageOrAuto, &v[0], &rhs.@"flex-basis"[0]) and (v[1] == rhs.@"flex-basis"[1]), + .flex => |*v| css.generic.eql(Flex, &v[0], &rhs.flex[0]) and (v[1] == rhs.flex[1]), + .order => |*v| css.generic.eql(CSSInteger, &v[0], &rhs.order[0]) and (v[1] == rhs.order[1]), + .@"align-content" => |*v| css.generic.eql(AlignContent, &v[0], &rhs.@"align-content"[0]) and (v[1] == rhs.@"align-content"[1]), + .@"justify-content" => |*v| css.generic.eql(JustifyContent, &v[0], &rhs.@"justify-content"[0]) and (v[1] == rhs.@"justify-content"[1]), .@"place-content" => |*v| css.generic.eql(PlaceContent, v, &rhs.@"place-content"), - .@"align-self" => |*v| css.generic.eql(AlignSelf, &v[0], &rhs.@"align-self"[0]) and v[1].eq(rhs.@"align-self"[1]), + .@"align-self" => |*v| css.generic.eql(AlignSelf, &v[0], &rhs.@"align-self"[0]) and (v[1] == rhs.@"align-self"[1]), .@"justify-self" => |*v| css.generic.eql(JustifySelf, v, &rhs.@"justify-self"), .@"place-self" => |*v| css.generic.eql(PlaceSelf, v, &rhs.@"place-self"), - .@"align-items" => |*v| css.generic.eql(AlignItems, &v[0], &rhs.@"align-items"[0]) and v[1].eq(rhs.@"align-items"[1]), + .@"align-items" => |*v| css.generic.eql(AlignItems, &v[0], &rhs.@"align-items"[0]) and (v[1] == rhs.@"align-items"[1]), .@"justify-items" => |*v| css.generic.eql(JustifyItems, v, &rhs.@"justify-items"), .@"place-items" => |*v| css.generic.eql(PlaceItems, v, &rhs.@"place-items"), .@"row-gap" => |*v| css.generic.eql(GapValue, v, &rhs.@"row-gap"), .@"column-gap" => |*v| css.generic.eql(GapValue, v, &rhs.@"column-gap"), .gap => |*v| css.generic.eql(Gap, v, &rhs.gap), - .@"box-orient" => |*v| css.generic.eql(BoxOrient, &v[0], &rhs.@"box-orient"[0]) and v[1].eq(rhs.@"box-orient"[1]), - .@"box-direction" => |*v| css.generic.eql(BoxDirection, &v[0], &rhs.@"box-direction"[0]) and v[1].eq(rhs.@"box-direction"[1]), - .@"box-ordinal-group" => |*v| css.generic.eql(CSSInteger, &v[0], &rhs.@"box-ordinal-group"[0]) and v[1].eq(rhs.@"box-ordinal-group"[1]), - .@"box-align" => |*v| css.generic.eql(BoxAlign, &v[0], &rhs.@"box-align"[0]) and v[1].eq(rhs.@"box-align"[1]), - .@"box-flex" => |*v| css.generic.eql(CSSNumber, &v[0], &rhs.@"box-flex"[0]) and v[1].eq(rhs.@"box-flex"[1]), - .@"box-flex-group" => |*v| css.generic.eql(CSSInteger, &v[0], &rhs.@"box-flex-group"[0]) and v[1].eq(rhs.@"box-flex-group"[1]), - .@"box-pack" => |*v| css.generic.eql(BoxPack, &v[0], &rhs.@"box-pack"[0]) and v[1].eq(rhs.@"box-pack"[1]), - .@"box-lines" => |*v| css.generic.eql(BoxLines, &v[0], &rhs.@"box-lines"[0]) and v[1].eq(rhs.@"box-lines"[1]), - .@"flex-pack" => |*v| css.generic.eql(FlexPack, &v[0], &rhs.@"flex-pack"[0]) and v[1].eq(rhs.@"flex-pack"[1]), - .@"flex-order" => |*v| css.generic.eql(CSSInteger, &v[0], &rhs.@"flex-order"[0]) and v[1].eq(rhs.@"flex-order"[1]), - .@"flex-align" => |*v| css.generic.eql(BoxAlign, &v[0], &rhs.@"flex-align"[0]) and v[1].eq(rhs.@"flex-align"[1]), - .@"flex-item-align" => |*v| css.generic.eql(FlexItemAlign, &v[0], &rhs.@"flex-item-align"[0]) and v[1].eq(rhs.@"flex-item-align"[1]), - .@"flex-line-pack" => |*v| css.generic.eql(FlexLinePack, &v[0], &rhs.@"flex-line-pack"[0]) and v[1].eq(rhs.@"flex-line-pack"[1]), - .@"flex-positive" => |*v| css.generic.eql(CSSNumber, &v[0], &rhs.@"flex-positive"[0]) and v[1].eq(rhs.@"flex-positive"[1]), - .@"flex-negative" => |*v| css.generic.eql(CSSNumber, &v[0], &rhs.@"flex-negative"[0]) and v[1].eq(rhs.@"flex-negative"[1]), - .@"flex-preferred-size" => |*v| css.generic.eql(LengthPercentageOrAuto, &v[0], &rhs.@"flex-preferred-size"[0]) and v[1].eq(rhs.@"flex-preferred-size"[1]), + .@"box-orient" => |*v| css.generic.eql(BoxOrient, &v[0], &rhs.@"box-orient"[0]) and (v[1] == rhs.@"box-orient"[1]), + .@"box-direction" => |*v| css.generic.eql(BoxDirection, &v[0], &rhs.@"box-direction"[0]) and (v[1] == rhs.@"box-direction"[1]), + .@"box-ordinal-group" => |*v| css.generic.eql(CSSInteger, &v[0], &rhs.@"box-ordinal-group"[0]) and (v[1] == rhs.@"box-ordinal-group"[1]), + .@"box-align" => |*v| css.generic.eql(BoxAlign, &v[0], &rhs.@"box-align"[0]) and (v[1] == rhs.@"box-align"[1]), + .@"box-flex" => |*v| css.generic.eql(CSSNumber, &v[0], &rhs.@"box-flex"[0]) and (v[1] == rhs.@"box-flex"[1]), + .@"box-flex-group" => |*v| css.generic.eql(CSSInteger, &v[0], &rhs.@"box-flex-group"[0]) and (v[1] == rhs.@"box-flex-group"[1]), + .@"box-pack" => |*v| css.generic.eql(BoxPack, &v[0], &rhs.@"box-pack"[0]) and (v[1] == rhs.@"box-pack"[1]), + .@"box-lines" => |*v| css.generic.eql(BoxLines, &v[0], &rhs.@"box-lines"[0]) and (v[1] == rhs.@"box-lines"[1]), + .@"flex-pack" => |*v| css.generic.eql(FlexPack, &v[0], &rhs.@"flex-pack"[0]) and (v[1] == rhs.@"flex-pack"[1]), + .@"flex-order" => |*v| css.generic.eql(CSSInteger, &v[0], &rhs.@"flex-order"[0]) and (v[1] == rhs.@"flex-order"[1]), + .@"flex-align" => |*v| css.generic.eql(BoxAlign, &v[0], &rhs.@"flex-align"[0]) and (v[1] == rhs.@"flex-align"[1]), + .@"flex-item-align" => |*v| css.generic.eql(FlexItemAlign, &v[0], &rhs.@"flex-item-align"[0]) and (v[1] == rhs.@"flex-item-align"[1]), + .@"flex-line-pack" => |*v| css.generic.eql(FlexLinePack, &v[0], &rhs.@"flex-line-pack"[0]) and (v[1] == rhs.@"flex-line-pack"[1]), + .@"flex-positive" => |*v| css.generic.eql(CSSNumber, &v[0], &rhs.@"flex-positive"[0]) and (v[1] == rhs.@"flex-positive"[1]), + .@"flex-negative" => |*v| css.generic.eql(CSSNumber, &v[0], &rhs.@"flex-negative"[0]) and (v[1] == rhs.@"flex-negative"[1]), + .@"flex-preferred-size" => |*v| css.generic.eql(LengthPercentageOrAuto, &v[0], &rhs.@"flex-preferred-size"[0]) and (v[1] == rhs.@"flex-preferred-size"[1]), .@"margin-top" => |*v| css.generic.eql(LengthPercentageOrAuto, v, &rhs.@"margin-top"), .@"margin-bottom" => |*v| css.generic.eql(LengthPercentageOrAuto, v, &rhs.@"margin-bottom"), .@"margin-left" => |*v| css.generic.eql(LengthPercentageOrAuto, v, &rhs.@"margin-left"), @@ -7384,38 +7384,38 @@ pub const Property = union(PropertyIdTag) { .@"font-variant-caps" => |*v| css.generic.eql(FontVariantCaps, v, &rhs.@"font-variant-caps"), .@"line-height" => |*v| css.generic.eql(LineHeight, v, &rhs.@"line-height"), .font => |*v| css.generic.eql(Font, v, &rhs.font), - .@"transition-property" => |*v| css.generic.eql(SmallList(PropertyId, 1), &v[0], &rhs.@"transition-property"[0]) and v[1].eq(rhs.@"transition-property"[1]), - .@"transition-duration" => |*v| css.generic.eql(SmallList(Time, 1), &v[0], &rhs.@"transition-duration"[0]) and v[1].eq(rhs.@"transition-duration"[1]), - .@"transition-delay" => |*v| css.generic.eql(SmallList(Time, 1), &v[0], &rhs.@"transition-delay"[0]) and v[1].eq(rhs.@"transition-delay"[1]), - .@"transition-timing-function" => |*v| css.generic.eql(SmallList(EasingFunction, 1), &v[0], &rhs.@"transition-timing-function"[0]) and v[1].eq(rhs.@"transition-timing-function"[1]), - .transition => |*v| css.generic.eql(SmallList(Transition, 1), &v[0], &rhs.transition[0]) and v[1].eq(rhs.transition[1]), - .transform => |*v| css.generic.eql(TransformList, &v[0], &rhs.transform[0]) and v[1].eq(rhs.transform[1]), - .@"transform-origin" => |*v| css.generic.eql(Position, &v[0], &rhs.@"transform-origin"[0]) and v[1].eq(rhs.@"transform-origin"[1]), - .@"transform-style" => |*v| css.generic.eql(TransformStyle, &v[0], &rhs.@"transform-style"[0]) and v[1].eq(rhs.@"transform-style"[1]), + .@"transition-property" => |*v| css.generic.eql(SmallList(PropertyId, 1), &v[0], &rhs.@"transition-property"[0]) and (v[1] == rhs.@"transition-property"[1]), + .@"transition-duration" => |*v| css.generic.eql(SmallList(Time, 1), &v[0], &rhs.@"transition-duration"[0]) and (v[1] == rhs.@"transition-duration"[1]), + .@"transition-delay" => |*v| css.generic.eql(SmallList(Time, 1), &v[0], &rhs.@"transition-delay"[0]) and (v[1] == rhs.@"transition-delay"[1]), + .@"transition-timing-function" => |*v| css.generic.eql(SmallList(EasingFunction, 1), &v[0], &rhs.@"transition-timing-function"[0]) and (v[1] == rhs.@"transition-timing-function"[1]), + .transition => |*v| css.generic.eql(SmallList(Transition, 1), &v[0], &rhs.transition[0]) and (v[1] == rhs.transition[1]), + .transform => |*v| css.generic.eql(TransformList, &v[0], &rhs.transform[0]) and (v[1] == rhs.transform[1]), + .@"transform-origin" => |*v| css.generic.eql(Position, &v[0], &rhs.@"transform-origin"[0]) and (v[1] == rhs.@"transform-origin"[1]), + .@"transform-style" => |*v| css.generic.eql(TransformStyle, &v[0], &rhs.@"transform-style"[0]) and (v[1] == rhs.@"transform-style"[1]), .@"transform-box" => |*v| css.generic.eql(TransformBox, v, &rhs.@"transform-box"), - .@"backface-visibility" => |*v| css.generic.eql(BackfaceVisibility, &v[0], &rhs.@"backface-visibility"[0]) and v[1].eq(rhs.@"backface-visibility"[1]), - .perspective => |*v| css.generic.eql(Perspective, &v[0], &rhs.perspective[0]) and v[1].eq(rhs.perspective[1]), - .@"perspective-origin" => |*v| css.generic.eql(Position, &v[0], &rhs.@"perspective-origin"[0]) and v[1].eq(rhs.@"perspective-origin"[1]), + .@"backface-visibility" => |*v| css.generic.eql(BackfaceVisibility, &v[0], &rhs.@"backface-visibility"[0]) and (v[1] == rhs.@"backface-visibility"[1]), + .perspective => |*v| css.generic.eql(Perspective, &v[0], &rhs.perspective[0]) and (v[1] == rhs.perspective[1]), + .@"perspective-origin" => |*v| css.generic.eql(Position, &v[0], &rhs.@"perspective-origin"[0]) and (v[1] == rhs.@"perspective-origin"[1]), .translate => |*v| css.generic.eql(Translate, v, &rhs.translate), .rotate => |*v| css.generic.eql(Rotate, v, &rhs.rotate), .scale => |*v| css.generic.eql(Scale, v, &rhs.scale), - .@"text-decoration-color" => |*v| css.generic.eql(CssColor, &v[0], &rhs.@"text-decoration-color"[0]) and v[1].eq(rhs.@"text-decoration-color"[1]), - .@"text-emphasis-color" => |*v| css.generic.eql(CssColor, &v[0], &rhs.@"text-emphasis-color"[0]) and v[1].eq(rhs.@"text-emphasis-color"[1]), + .@"text-decoration-color" => |*v| css.generic.eql(CssColor, &v[0], &rhs.@"text-decoration-color"[0]) and (v[1] == rhs.@"text-decoration-color"[1]), + .@"text-emphasis-color" => |*v| css.generic.eql(CssColor, &v[0], &rhs.@"text-emphasis-color"[0]) and (v[1] == rhs.@"text-emphasis-color"[1]), .@"text-shadow" => |*v| css.generic.eql(SmallList(TextShadow, 1), v, &rhs.@"text-shadow"), .direction => |*v| css.generic.eql(Direction, v, &rhs.direction), .composes => |*v| css.generic.eql(Composes, v, &rhs.composes), - .@"mask-image" => |*v| css.generic.eql(SmallList(Image, 1), &v[0], &rhs.@"mask-image"[0]) and v[1].eq(rhs.@"mask-image"[1]), + .@"mask-image" => |*v| css.generic.eql(SmallList(Image, 1), &v[0], &rhs.@"mask-image"[0]) and (v[1] == rhs.@"mask-image"[1]), .@"mask-mode" => |*v| css.generic.eql(SmallList(MaskMode, 1), v, &rhs.@"mask-mode"), - .@"mask-repeat" => |*v| css.generic.eql(SmallList(BackgroundRepeat, 1), &v[0], &rhs.@"mask-repeat"[0]) and v[1].eq(rhs.@"mask-repeat"[1]), + .@"mask-repeat" => |*v| css.generic.eql(SmallList(BackgroundRepeat, 1), &v[0], &rhs.@"mask-repeat"[0]) and (v[1] == rhs.@"mask-repeat"[1]), .@"mask-position-x" => |*v| css.generic.eql(SmallList(HorizontalPosition, 1), v, &rhs.@"mask-position-x"), .@"mask-position-y" => |*v| css.generic.eql(SmallList(VerticalPosition, 1), v, &rhs.@"mask-position-y"), - .@"mask-position" => |*v| css.generic.eql(SmallList(Position, 1), &v[0], &rhs.@"mask-position"[0]) and v[1].eq(rhs.@"mask-position"[1]), - .@"mask-clip" => |*v| css.generic.eql(SmallList(MaskClip, 1), &v[0], &rhs.@"mask-clip"[0]) and v[1].eq(rhs.@"mask-clip"[1]), - .@"mask-origin" => |*v| css.generic.eql(SmallList(GeometryBox, 1), &v[0], &rhs.@"mask-origin"[0]) and v[1].eq(rhs.@"mask-origin"[1]), - .@"mask-size" => |*v| css.generic.eql(SmallList(BackgroundSize, 1), &v[0], &rhs.@"mask-size"[0]) and v[1].eq(rhs.@"mask-size"[1]), + .@"mask-position" => |*v| css.generic.eql(SmallList(Position, 1), &v[0], &rhs.@"mask-position"[0]) and (v[1] == rhs.@"mask-position"[1]), + .@"mask-clip" => |*v| css.generic.eql(SmallList(MaskClip, 1), &v[0], &rhs.@"mask-clip"[0]) and (v[1] == rhs.@"mask-clip"[1]), + .@"mask-origin" => |*v| css.generic.eql(SmallList(GeometryBox, 1), &v[0], &rhs.@"mask-origin"[0]) and (v[1] == rhs.@"mask-origin"[1]), + .@"mask-size" => |*v| css.generic.eql(SmallList(BackgroundSize, 1), &v[0], &rhs.@"mask-size"[0]) and (v[1] == rhs.@"mask-size"[1]), .@"mask-composite" => |*v| css.generic.eql(SmallList(MaskComposite, 1), v, &rhs.@"mask-composite"), .@"mask-type" => |*v| css.generic.eql(MaskType, v, &rhs.@"mask-type"), - .mask => |*v| css.generic.eql(SmallList(Mask, 1), &v[0], &rhs.mask[0]) and v[1].eq(rhs.mask[1]), + .mask => |*v| css.generic.eql(SmallList(Mask, 1), &v[0], &rhs.mask[0]) and (v[1] == rhs.mask[1]), .@"mask-border-source" => |*v| css.generic.eql(Image, v, &rhs.@"mask-border-source"), .@"mask-border-mode" => |*v| css.generic.eql(MaskBorderMode, v, &rhs.@"mask-border-mode"), .@"mask-border-slice" => |*v| css.generic.eql(BorderImageSlice, v, &rhs.@"mask-border-slice"), @@ -7424,13 +7424,13 @@ pub const Property = union(PropertyIdTag) { .@"mask-border-repeat" => |*v| css.generic.eql(BorderImageRepeat, v, &rhs.@"mask-border-repeat"), .@"mask-border" => |*v| css.generic.eql(MaskBorder, v, &rhs.@"mask-border"), .@"-webkit-mask-composite" => |*v| css.generic.eql(SmallList(WebKitMaskComposite, 1), v, &rhs.@"-webkit-mask-composite"), - .@"mask-source-type" => |*v| css.generic.eql(SmallList(WebKitMaskSourceType, 1), &v[0], &rhs.@"mask-source-type"[0]) and v[1].eq(rhs.@"mask-source-type"[1]), - .@"mask-box-image" => |*v| css.generic.eql(BorderImage, &v[0], &rhs.@"mask-box-image"[0]) and v[1].eq(rhs.@"mask-box-image"[1]), - .@"mask-box-image-source" => |*v| css.generic.eql(Image, &v[0], &rhs.@"mask-box-image-source"[0]) and v[1].eq(rhs.@"mask-box-image-source"[1]), - .@"mask-box-image-slice" => |*v| css.generic.eql(BorderImageSlice, &v[0], &rhs.@"mask-box-image-slice"[0]) and v[1].eq(rhs.@"mask-box-image-slice"[1]), - .@"mask-box-image-width" => |*v| css.generic.eql(Rect(BorderImageSideWidth), &v[0], &rhs.@"mask-box-image-width"[0]) and v[1].eq(rhs.@"mask-box-image-width"[1]), - .@"mask-box-image-outset" => |*v| css.generic.eql(Rect(LengthOrNumber), &v[0], &rhs.@"mask-box-image-outset"[0]) and v[1].eq(rhs.@"mask-box-image-outset"[1]), - .@"mask-box-image-repeat" => |*v| css.generic.eql(BorderImageRepeat, &v[0], &rhs.@"mask-box-image-repeat"[0]) and v[1].eq(rhs.@"mask-box-image-repeat"[1]), + .@"mask-source-type" => |*v| css.generic.eql(SmallList(WebKitMaskSourceType, 1), &v[0], &rhs.@"mask-source-type"[0]) and (v[1] == rhs.@"mask-source-type"[1]), + .@"mask-box-image" => |*v| css.generic.eql(BorderImage, &v[0], &rhs.@"mask-box-image"[0]) and (v[1] == rhs.@"mask-box-image"[1]), + .@"mask-box-image-source" => |*v| css.generic.eql(Image, &v[0], &rhs.@"mask-box-image-source"[0]) and (v[1] == rhs.@"mask-box-image-source"[1]), + .@"mask-box-image-slice" => |*v| css.generic.eql(BorderImageSlice, &v[0], &rhs.@"mask-box-image-slice"[0]) and (v[1] == rhs.@"mask-box-image-slice"[1]), + .@"mask-box-image-width" => |*v| css.generic.eql(Rect(BorderImageSideWidth), &v[0], &rhs.@"mask-box-image-width"[0]) and (v[1] == rhs.@"mask-box-image-width"[1]), + .@"mask-box-image-outset" => |*v| css.generic.eql(Rect(LengthOrNumber), &v[0], &rhs.@"mask-box-image-outset"[0]) and (v[1] == rhs.@"mask-box-image-outset"[1]), + .@"mask-box-image-repeat" => |*v| css.generic.eql(BorderImageRepeat, &v[0], &rhs.@"mask-box-image-repeat"[0]) and (v[1] == rhs.@"mask-box-image-repeat"[1]), .@"color-scheme" => |*v| css.generic.eql(ColorScheme, v, &rhs.@"color-scheme"), .unparsed => |*u| u.eql(&rhs.unparsed), .all => true, @@ -7689,7 +7689,10 @@ pub const PropertyId = union(PropertyIdTag) { unparsed, custom: CustomPropertyName, - pub usingnamespace PropertyIdImpl(); + pub const toCss = properties_impl.property_id_mixin.toCss; + pub const parse = properties_impl.property_id_mixin.parse; + pub const fromString = properties_impl.property_id_mixin.fromString; + pub const fromStr = fromString; /// Returns the property name, without any vendor prefixes. pub inline fn name(this: *const PropertyId) []const u8 { @@ -7700,116 +7703,116 @@ pub const PropertyId = union(PropertyIdTag) { /// Returns the vendor prefix for this property id. pub fn prefix(this: *const PropertyId) VendorPrefix { return switch (this.*) { - .@"background-color" => VendorPrefix.empty(), - .@"background-image" => VendorPrefix.empty(), - .@"background-position-x" => VendorPrefix.empty(), - .@"background-position-y" => VendorPrefix.empty(), - .@"background-position" => VendorPrefix.empty(), - .@"background-size" => VendorPrefix.empty(), - .@"background-repeat" => VendorPrefix.empty(), - .@"background-attachment" => VendorPrefix.empty(), + .@"background-color" => .empty, + .@"background-image" => .empty, + .@"background-position-x" => .empty, + .@"background-position-y" => .empty, + .@"background-position" => .empty, + .@"background-size" => .empty, + .@"background-repeat" => .empty, + .@"background-attachment" => .empty, .@"background-clip" => |p| p, - .@"background-origin" => VendorPrefix.empty(), - .background => VendorPrefix.empty(), + .@"background-origin" => .empty, + .background => .empty, .@"box-shadow" => |p| p, - .opacity => VendorPrefix.empty(), - .color => VendorPrefix.empty(), - .display => VendorPrefix.empty(), - .visibility => VendorPrefix.empty(), - .width => VendorPrefix.empty(), - .height => VendorPrefix.empty(), - .@"min-width" => VendorPrefix.empty(), - .@"min-height" => VendorPrefix.empty(), - .@"max-width" => VendorPrefix.empty(), - .@"max-height" => VendorPrefix.empty(), - .@"block-size" => VendorPrefix.empty(), - .@"inline-size" => VendorPrefix.empty(), - .@"min-block-size" => VendorPrefix.empty(), - .@"min-inline-size" => VendorPrefix.empty(), - .@"max-block-size" => VendorPrefix.empty(), - .@"max-inline-size" => VendorPrefix.empty(), + .opacity => .empty, + .color => .empty, + .display => .empty, + .visibility => .empty, + .width => .empty, + .height => .empty, + .@"min-width" => .empty, + .@"min-height" => .empty, + .@"max-width" => .empty, + .@"max-height" => .empty, + .@"block-size" => .empty, + .@"inline-size" => .empty, + .@"min-block-size" => .empty, + .@"min-inline-size" => .empty, + .@"max-block-size" => .empty, + .@"max-inline-size" => .empty, .@"box-sizing" => |p| p, - .@"aspect-ratio" => VendorPrefix.empty(), - .overflow => VendorPrefix.empty(), - .@"overflow-x" => VendorPrefix.empty(), - .@"overflow-y" => VendorPrefix.empty(), + .@"aspect-ratio" => .empty, + .overflow => .empty, + .@"overflow-x" => .empty, + .@"overflow-y" => .empty, .@"text-overflow" => |p| p, - .position => VendorPrefix.empty(), - .top => VendorPrefix.empty(), - .bottom => VendorPrefix.empty(), - .left => VendorPrefix.empty(), - .right => VendorPrefix.empty(), - .@"inset-block-start" => VendorPrefix.empty(), - .@"inset-block-end" => VendorPrefix.empty(), - .@"inset-inline-start" => VendorPrefix.empty(), - .@"inset-inline-end" => VendorPrefix.empty(), - .@"inset-block" => VendorPrefix.empty(), - .@"inset-inline" => VendorPrefix.empty(), - .inset => VendorPrefix.empty(), - .@"border-spacing" => VendorPrefix.empty(), - .@"border-top-color" => VendorPrefix.empty(), - .@"border-bottom-color" => VendorPrefix.empty(), - .@"border-left-color" => VendorPrefix.empty(), - .@"border-right-color" => VendorPrefix.empty(), - .@"border-block-start-color" => VendorPrefix.empty(), - .@"border-block-end-color" => VendorPrefix.empty(), - .@"border-inline-start-color" => VendorPrefix.empty(), - .@"border-inline-end-color" => VendorPrefix.empty(), - .@"border-top-style" => VendorPrefix.empty(), - .@"border-bottom-style" => VendorPrefix.empty(), - .@"border-left-style" => VendorPrefix.empty(), - .@"border-right-style" => VendorPrefix.empty(), - .@"border-block-start-style" => VendorPrefix.empty(), - .@"border-block-end-style" => VendorPrefix.empty(), - .@"border-inline-start-style" => VendorPrefix.empty(), - .@"border-inline-end-style" => VendorPrefix.empty(), - .@"border-top-width" => VendorPrefix.empty(), - .@"border-bottom-width" => VendorPrefix.empty(), - .@"border-left-width" => VendorPrefix.empty(), - .@"border-right-width" => VendorPrefix.empty(), - .@"border-block-start-width" => VendorPrefix.empty(), - .@"border-block-end-width" => VendorPrefix.empty(), - .@"border-inline-start-width" => VendorPrefix.empty(), - .@"border-inline-end-width" => VendorPrefix.empty(), + .position => .empty, + .top => .empty, + .bottom => .empty, + .left => .empty, + .right => .empty, + .@"inset-block-start" => .empty, + .@"inset-block-end" => .empty, + .@"inset-inline-start" => .empty, + .@"inset-inline-end" => .empty, + .@"inset-block" => .empty, + .@"inset-inline" => .empty, + .inset => .empty, + .@"border-spacing" => .empty, + .@"border-top-color" => .empty, + .@"border-bottom-color" => .empty, + .@"border-left-color" => .empty, + .@"border-right-color" => .empty, + .@"border-block-start-color" => .empty, + .@"border-block-end-color" => .empty, + .@"border-inline-start-color" => .empty, + .@"border-inline-end-color" => .empty, + .@"border-top-style" => .empty, + .@"border-bottom-style" => .empty, + .@"border-left-style" => .empty, + .@"border-right-style" => .empty, + .@"border-block-start-style" => .empty, + .@"border-block-end-style" => .empty, + .@"border-inline-start-style" => .empty, + .@"border-inline-end-style" => .empty, + .@"border-top-width" => .empty, + .@"border-bottom-width" => .empty, + .@"border-left-width" => .empty, + .@"border-right-width" => .empty, + .@"border-block-start-width" => .empty, + .@"border-block-end-width" => .empty, + .@"border-inline-start-width" => .empty, + .@"border-inline-end-width" => .empty, .@"border-top-left-radius" => |p| p, .@"border-top-right-radius" => |p| p, .@"border-bottom-left-radius" => |p| p, .@"border-bottom-right-radius" => |p| p, - .@"border-start-start-radius" => VendorPrefix.empty(), - .@"border-start-end-radius" => VendorPrefix.empty(), - .@"border-end-start-radius" => VendorPrefix.empty(), - .@"border-end-end-radius" => VendorPrefix.empty(), + .@"border-start-start-radius" => .empty, + .@"border-start-end-radius" => .empty, + .@"border-end-start-radius" => .empty, + .@"border-end-end-radius" => .empty, .@"border-radius" => |p| p, - .@"border-image-source" => VendorPrefix.empty(), - .@"border-image-outset" => VendorPrefix.empty(), - .@"border-image-repeat" => VendorPrefix.empty(), - .@"border-image-width" => VendorPrefix.empty(), - .@"border-image-slice" => VendorPrefix.empty(), + .@"border-image-source" => .empty, + .@"border-image-outset" => .empty, + .@"border-image-repeat" => .empty, + .@"border-image-width" => .empty, + .@"border-image-slice" => .empty, .@"border-image" => |p| p, - .@"border-color" => VendorPrefix.empty(), - .@"border-style" => VendorPrefix.empty(), - .@"border-width" => VendorPrefix.empty(), - .@"border-block-color" => VendorPrefix.empty(), - .@"border-block-style" => VendorPrefix.empty(), - .@"border-block-width" => VendorPrefix.empty(), - .@"border-inline-color" => VendorPrefix.empty(), - .@"border-inline-style" => VendorPrefix.empty(), - .@"border-inline-width" => VendorPrefix.empty(), - .border => VendorPrefix.empty(), - .@"border-top" => VendorPrefix.empty(), - .@"border-bottom" => VendorPrefix.empty(), - .@"border-left" => VendorPrefix.empty(), - .@"border-right" => VendorPrefix.empty(), - .@"border-block" => VendorPrefix.empty(), - .@"border-block-start" => VendorPrefix.empty(), - .@"border-block-end" => VendorPrefix.empty(), - .@"border-inline" => VendorPrefix.empty(), - .@"border-inline-start" => VendorPrefix.empty(), - .@"border-inline-end" => VendorPrefix.empty(), - .outline => VendorPrefix.empty(), - .@"outline-color" => VendorPrefix.empty(), - .@"outline-style" => VendorPrefix.empty(), - .@"outline-width" => VendorPrefix.empty(), + .@"border-color" => .empty, + .@"border-style" => .empty, + .@"border-width" => .empty, + .@"border-block-color" => .empty, + .@"border-block-style" => .empty, + .@"border-block-width" => .empty, + .@"border-inline-color" => .empty, + .@"border-inline-style" => .empty, + .@"border-inline-width" => .empty, + .border => .empty, + .@"border-top" => .empty, + .@"border-bottom" => .empty, + .@"border-left" => .empty, + .@"border-right" => .empty, + .@"border-block" => .empty, + .@"border-block-start" => .empty, + .@"border-block-end" => .empty, + .@"border-inline" => .empty, + .@"border-inline-start" => .empty, + .@"border-inline-end" => .empty, + .outline => .empty, + .@"outline-color" => .empty, + .@"outline-style" => .empty, + .@"outline-width" => .empty, .@"flex-direction" => |p| p, .@"flex-wrap" => |p| p, .@"flex-flow" => |p| p, @@ -7820,16 +7823,16 @@ pub const PropertyId = union(PropertyIdTag) { .order => |p| p, .@"align-content" => |p| p, .@"justify-content" => |p| p, - .@"place-content" => VendorPrefix.empty(), + .@"place-content" => .empty, .@"align-self" => |p| p, - .@"justify-self" => VendorPrefix.empty(), - .@"place-self" => VendorPrefix.empty(), + .@"justify-self" => .empty, + .@"place-self" => .empty, .@"align-items" => |p| p, - .@"justify-items" => VendorPrefix.empty(), - .@"place-items" => VendorPrefix.empty(), - .@"row-gap" => VendorPrefix.empty(), - .@"column-gap" => VendorPrefix.empty(), - .gap => VendorPrefix.empty(), + .@"justify-items" => .empty, + .@"place-items" => .empty, + .@"row-gap" => .empty, + .@"column-gap" => .empty, + .gap => .empty, .@"box-orient" => |p| p, .@"box-direction" => |p| p, .@"box-ordinal-group" => |p| p, @@ -7846,58 +7849,58 @@ pub const PropertyId = union(PropertyIdTag) { .@"flex-positive" => |p| p, .@"flex-negative" => |p| p, .@"flex-preferred-size" => |p| p, - .@"margin-top" => VendorPrefix.empty(), - .@"margin-bottom" => VendorPrefix.empty(), - .@"margin-left" => VendorPrefix.empty(), - .@"margin-right" => VendorPrefix.empty(), - .@"margin-block-start" => VendorPrefix.empty(), - .@"margin-block-end" => VendorPrefix.empty(), - .@"margin-inline-start" => VendorPrefix.empty(), - .@"margin-inline-end" => VendorPrefix.empty(), - .@"margin-block" => VendorPrefix.empty(), - .@"margin-inline" => VendorPrefix.empty(), - .margin => VendorPrefix.empty(), - .@"padding-top" => VendorPrefix.empty(), - .@"padding-bottom" => VendorPrefix.empty(), - .@"padding-left" => VendorPrefix.empty(), - .@"padding-right" => VendorPrefix.empty(), - .@"padding-block-start" => VendorPrefix.empty(), - .@"padding-block-end" => VendorPrefix.empty(), - .@"padding-inline-start" => VendorPrefix.empty(), - .@"padding-inline-end" => VendorPrefix.empty(), - .@"padding-block" => VendorPrefix.empty(), - .@"padding-inline" => VendorPrefix.empty(), - .padding => VendorPrefix.empty(), - .@"scroll-margin-top" => VendorPrefix.empty(), - .@"scroll-margin-bottom" => VendorPrefix.empty(), - .@"scroll-margin-left" => VendorPrefix.empty(), - .@"scroll-margin-right" => VendorPrefix.empty(), - .@"scroll-margin-block-start" => VendorPrefix.empty(), - .@"scroll-margin-block-end" => VendorPrefix.empty(), - .@"scroll-margin-inline-start" => VendorPrefix.empty(), - .@"scroll-margin-inline-end" => VendorPrefix.empty(), - .@"scroll-margin-block" => VendorPrefix.empty(), - .@"scroll-margin-inline" => VendorPrefix.empty(), - .@"scroll-margin" => VendorPrefix.empty(), - .@"scroll-padding-top" => VendorPrefix.empty(), - .@"scroll-padding-bottom" => VendorPrefix.empty(), - .@"scroll-padding-left" => VendorPrefix.empty(), - .@"scroll-padding-right" => VendorPrefix.empty(), - .@"scroll-padding-block-start" => VendorPrefix.empty(), - .@"scroll-padding-block-end" => VendorPrefix.empty(), - .@"scroll-padding-inline-start" => VendorPrefix.empty(), - .@"scroll-padding-inline-end" => VendorPrefix.empty(), - .@"scroll-padding-block" => VendorPrefix.empty(), - .@"scroll-padding-inline" => VendorPrefix.empty(), - .@"scroll-padding" => VendorPrefix.empty(), - .@"font-weight" => VendorPrefix.empty(), - .@"font-size" => VendorPrefix.empty(), - .@"font-stretch" => VendorPrefix.empty(), - .@"font-family" => VendorPrefix.empty(), - .@"font-style" => VendorPrefix.empty(), - .@"font-variant-caps" => VendorPrefix.empty(), - .@"line-height" => VendorPrefix.empty(), - .font => VendorPrefix.empty(), + .@"margin-top" => .empty, + .@"margin-bottom" => .empty, + .@"margin-left" => .empty, + .@"margin-right" => .empty, + .@"margin-block-start" => .empty, + .@"margin-block-end" => .empty, + .@"margin-inline-start" => .empty, + .@"margin-inline-end" => .empty, + .@"margin-block" => .empty, + .@"margin-inline" => .empty, + .margin => .empty, + .@"padding-top" => .empty, + .@"padding-bottom" => .empty, + .@"padding-left" => .empty, + .@"padding-right" => .empty, + .@"padding-block-start" => .empty, + .@"padding-block-end" => .empty, + .@"padding-inline-start" => .empty, + .@"padding-inline-end" => .empty, + .@"padding-block" => .empty, + .@"padding-inline" => .empty, + .padding => .empty, + .@"scroll-margin-top" => .empty, + .@"scroll-margin-bottom" => .empty, + .@"scroll-margin-left" => .empty, + .@"scroll-margin-right" => .empty, + .@"scroll-margin-block-start" => .empty, + .@"scroll-margin-block-end" => .empty, + .@"scroll-margin-inline-start" => .empty, + .@"scroll-margin-inline-end" => .empty, + .@"scroll-margin-block" => .empty, + .@"scroll-margin-inline" => .empty, + .@"scroll-margin" => .empty, + .@"scroll-padding-top" => .empty, + .@"scroll-padding-bottom" => .empty, + .@"scroll-padding-left" => .empty, + .@"scroll-padding-right" => .empty, + .@"scroll-padding-block-start" => .empty, + .@"scroll-padding-block-end" => .empty, + .@"scroll-padding-inline-start" => .empty, + .@"scroll-padding-inline-end" => .empty, + .@"scroll-padding-block" => .empty, + .@"scroll-padding-inline" => .empty, + .@"scroll-padding" => .empty, + .@"font-weight" => .empty, + .@"font-size" => .empty, + .@"font-stretch" => .empty, + .@"font-family" => .empty, + .@"font-style" => .empty, + .@"font-variant-caps" => .empty, + .@"line-height" => .empty, + .font => .empty, .@"transition-property" => |p| p, .@"transition-duration" => |p| p, .@"transition-delay" => |p| p, @@ -7906,38 +7909,38 @@ pub const PropertyId = union(PropertyIdTag) { .transform => |p| p, .@"transform-origin" => |p| p, .@"transform-style" => |p| p, - .@"transform-box" => VendorPrefix.empty(), + .@"transform-box" => .empty, .@"backface-visibility" => |p| p, .perspective => |p| p, .@"perspective-origin" => |p| p, - .translate => VendorPrefix.empty(), - .rotate => VendorPrefix.empty(), - .scale => VendorPrefix.empty(), + .translate => .empty, + .rotate => .empty, + .scale => .empty, .@"text-decoration-color" => |p| p, .@"text-emphasis-color" => |p| p, - .@"text-shadow" => VendorPrefix.empty(), - .direction => VendorPrefix.empty(), - .composes => VendorPrefix.empty(), + .@"text-shadow" => .empty, + .direction => .empty, + .composes => .empty, .@"mask-image" => |p| p, - .@"mask-mode" => VendorPrefix.empty(), + .@"mask-mode" => .empty, .@"mask-repeat" => |p| p, - .@"mask-position-x" => VendorPrefix.empty(), - .@"mask-position-y" => VendorPrefix.empty(), + .@"mask-position-x" => .empty, + .@"mask-position-y" => .empty, .@"mask-position" => |p| p, .@"mask-clip" => |p| p, .@"mask-origin" => |p| p, .@"mask-size" => |p| p, - .@"mask-composite" => VendorPrefix.empty(), - .@"mask-type" => VendorPrefix.empty(), + .@"mask-composite" => .empty, + .@"mask-type" => .empty, .mask => |p| p, - .@"mask-border-source" => VendorPrefix.empty(), - .@"mask-border-mode" => VendorPrefix.empty(), - .@"mask-border-slice" => VendorPrefix.empty(), - .@"mask-border-width" => VendorPrefix.empty(), - .@"mask-border-outset" => VendorPrefix.empty(), - .@"mask-border-repeat" => VendorPrefix.empty(), - .@"mask-border" => VendorPrefix.empty(), - .@"-webkit-mask-composite" => VendorPrefix.empty(), + .@"mask-border-source" => .empty, + .@"mask-border-mode" => .empty, + .@"mask-border-slice" => .empty, + .@"mask-border-width" => .empty, + .@"mask-border-outset" => .empty, + .@"mask-border-repeat" => .empty, + .@"mask-border" => .empty, + .@"-webkit-mask-composite" => .empty, .@"mask-source-type" => |p| p, .@"mask-box-image" => |p| p, .@"mask-box-image-source" => |p| p, @@ -7945,8 +7948,8 @@ pub const PropertyId = union(PropertyIdTag) { .@"mask-box-image-width" => |p| p, .@"mask-box-image-outset" => |p| p, .@"mask-box-image-repeat" => |p| p, - .@"color-scheme" => VendorPrefix.empty(), - .all, .custom, .unparsed => VendorPrefix.empty(), + .@"color-scheme" => .empty, + .all, .custom, .unparsed => .empty, }; } @@ -7957,987 +7960,987 @@ pub const PropertyId = union(PropertyIdTag) { switch (prop) { .@"background-color" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"background-color"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"background-color"; }, .@"background-image" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"background-image"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"background-image"; }, .@"background-position-x" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"background-position-x"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"background-position-x"; }, .@"background-position-y" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"background-position-y"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"background-position-y"; }, .@"background-position" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"background-position"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"background-position"; }, .@"background-size" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"background-size"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"background-size"; }, .@"background-repeat" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"background-repeat"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"background-repeat"; }, .@"background-attachment" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"background-attachment"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"background-attachment"; }, .@"background-clip" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true, .moz = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"background-clip" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"background-clip" = pre }; }, .@"background-origin" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"background-origin"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"background-origin"; }, .background => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .background; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .background; }, .@"box-shadow" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true, .moz = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"box-shadow" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"box-shadow" = pre }; }, .opacity => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .opacity; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .opacity; }, .color => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .color; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .color; }, .display => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .display; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .display; }, .visibility => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .visibility; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .visibility; }, .width => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .width; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .width; }, .height => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .height; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .height; }, .@"min-width" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"min-width"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"min-width"; }, .@"min-height" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"min-height"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"min-height"; }, .@"max-width" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"max-width"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"max-width"; }, .@"max-height" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"max-height"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"max-height"; }, .@"block-size" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"block-size"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"block-size"; }, .@"inline-size" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"inline-size"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"inline-size"; }, .@"min-block-size" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"min-block-size"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"min-block-size"; }, .@"min-inline-size" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"min-inline-size"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"min-inline-size"; }, .@"max-block-size" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"max-block-size"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"max-block-size"; }, .@"max-inline-size" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"max-inline-size"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"max-inline-size"; }, .@"box-sizing" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true, .moz = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"box-sizing" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"box-sizing" = pre }; }, .@"aspect-ratio" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"aspect-ratio"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"aspect-ratio"; }, .overflow => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .overflow; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .overflow; }, .@"overflow-x" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"overflow-x"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"overflow-x"; }, .@"overflow-y" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"overflow-y"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"overflow-y"; }, .@"text-overflow" => { const allowed_prefixes = VendorPrefix{ .none = true, .o = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"text-overflow" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"text-overflow" = pre }; }, .position => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .position; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .position; }, .top => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .top; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .top; }, .bottom => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .bottom; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .bottom; }, .left => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .left; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .left; }, .right => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .right; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .right; }, .@"inset-block-start" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"inset-block-start"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"inset-block-start"; }, .@"inset-block-end" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"inset-block-end"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"inset-block-end"; }, .@"inset-inline-start" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"inset-inline-start"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"inset-inline-start"; }, .@"inset-inline-end" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"inset-inline-end"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"inset-inline-end"; }, .@"inset-block" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"inset-block"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"inset-block"; }, .@"inset-inline" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"inset-inline"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"inset-inline"; }, .inset => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .inset; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .inset; }, .@"border-spacing" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-spacing"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-spacing"; }, .@"border-top-color" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-top-color"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-top-color"; }, .@"border-bottom-color" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-bottom-color"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-bottom-color"; }, .@"border-left-color" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-left-color"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-left-color"; }, .@"border-right-color" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-right-color"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-right-color"; }, .@"border-block-start-color" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-block-start-color"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-block-start-color"; }, .@"border-block-end-color" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-block-end-color"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-block-end-color"; }, .@"border-inline-start-color" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-inline-start-color"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-inline-start-color"; }, .@"border-inline-end-color" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-inline-end-color"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-inline-end-color"; }, .@"border-top-style" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-top-style"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-top-style"; }, .@"border-bottom-style" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-bottom-style"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-bottom-style"; }, .@"border-left-style" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-left-style"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-left-style"; }, .@"border-right-style" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-right-style"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-right-style"; }, .@"border-block-start-style" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-block-start-style"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-block-start-style"; }, .@"border-block-end-style" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-block-end-style"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-block-end-style"; }, .@"border-inline-start-style" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-inline-start-style"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-inline-start-style"; }, .@"border-inline-end-style" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-inline-end-style"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-inline-end-style"; }, .@"border-top-width" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-top-width"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-top-width"; }, .@"border-bottom-width" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-bottom-width"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-bottom-width"; }, .@"border-left-width" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-left-width"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-left-width"; }, .@"border-right-width" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-right-width"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-right-width"; }, .@"border-block-start-width" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-block-start-width"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-block-start-width"; }, .@"border-block-end-width" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-block-end-width"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-block-end-width"; }, .@"border-inline-start-width" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-inline-start-width"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-inline-start-width"; }, .@"border-inline-end-width" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-inline-end-width"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-inline-end-width"; }, .@"border-top-left-radius" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true, .moz = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"border-top-left-radius" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"border-top-left-radius" = pre }; }, .@"border-top-right-radius" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true, .moz = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"border-top-right-radius" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"border-top-right-radius" = pre }; }, .@"border-bottom-left-radius" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true, .moz = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"border-bottom-left-radius" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"border-bottom-left-radius" = pre }; }, .@"border-bottom-right-radius" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true, .moz = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"border-bottom-right-radius" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"border-bottom-right-radius" = pre }; }, .@"border-start-start-radius" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-start-start-radius"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-start-start-radius"; }, .@"border-start-end-radius" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-start-end-radius"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-start-end-radius"; }, .@"border-end-start-radius" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-end-start-radius"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-end-start-radius"; }, .@"border-end-end-radius" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-end-end-radius"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-end-end-radius"; }, .@"border-radius" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true, .moz = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"border-radius" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"border-radius" = pre }; }, .@"border-image-source" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-image-source"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-image-source"; }, .@"border-image-outset" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-image-outset"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-image-outset"; }, .@"border-image-repeat" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-image-repeat"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-image-repeat"; }, .@"border-image-width" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-image-width"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-image-width"; }, .@"border-image-slice" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-image-slice"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-image-slice"; }, .@"border-image" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true, .moz = true, .o = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"border-image" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"border-image" = pre }; }, .@"border-color" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-color"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-color"; }, .@"border-style" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-style"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-style"; }, .@"border-width" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-width"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-width"; }, .@"border-block-color" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-block-color"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-block-color"; }, .@"border-block-style" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-block-style"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-block-style"; }, .@"border-block-width" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-block-width"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-block-width"; }, .@"border-inline-color" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-inline-color"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-inline-color"; }, .@"border-inline-style" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-inline-style"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-inline-style"; }, .@"border-inline-width" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-inline-width"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-inline-width"; }, .border => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .border; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .border; }, .@"border-top" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-top"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-top"; }, .@"border-bottom" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-bottom"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-bottom"; }, .@"border-left" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-left"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-left"; }, .@"border-right" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-right"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-right"; }, .@"border-block" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-block"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-block"; }, .@"border-block-start" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-block-start"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-block-start"; }, .@"border-block-end" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-block-end"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-block-end"; }, .@"border-inline" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-inline"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-inline"; }, .@"border-inline-start" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-inline-start"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-inline-start"; }, .@"border-inline-end" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"border-inline-end"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"border-inline-end"; }, .outline => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .outline; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .outline; }, .@"outline-color" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"outline-color"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"outline-color"; }, .@"outline-style" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"outline-style"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"outline-style"; }, .@"outline-width" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"outline-width"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"outline-width"; }, .@"flex-direction" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true, .ms = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"flex-direction" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"flex-direction" = pre }; }, .@"flex-wrap" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true, .ms = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"flex-wrap" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"flex-wrap" = pre }; }, .@"flex-flow" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true, .ms = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"flex-flow" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"flex-flow" = pre }; }, .@"flex-grow" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"flex-grow" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"flex-grow" = pre }; }, .@"flex-shrink" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"flex-shrink" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"flex-shrink" = pre }; }, .@"flex-basis" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"flex-basis" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"flex-basis" = pre }; }, .flex => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true, .ms = true }; - if (allowed_prefixes.contains(pre)) return .{ .flex = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .flex = pre }; }, .order => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true }; - if (allowed_prefixes.contains(pre)) return .{ .order = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .order = pre }; }, .@"align-content" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"align-content" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"align-content" = pre }; }, .@"justify-content" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"justify-content" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"justify-content" = pre }; }, .@"place-content" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"place-content"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"place-content"; }, .@"align-self" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"align-self" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"align-self" = pre }; }, .@"justify-self" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"justify-self"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"justify-self"; }, .@"place-self" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"place-self"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"place-self"; }, .@"align-items" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"align-items" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"align-items" = pre }; }, .@"justify-items" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"justify-items"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"justify-items"; }, .@"place-items" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"place-items"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"place-items"; }, .@"row-gap" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"row-gap"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"row-gap"; }, .@"column-gap" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"column-gap"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"column-gap"; }, .gap => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .gap; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .gap; }, .@"box-orient" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true, .moz = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"box-orient" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"box-orient" = pre }; }, .@"box-direction" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true, .moz = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"box-direction" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"box-direction" = pre }; }, .@"box-ordinal-group" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true, .moz = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"box-ordinal-group" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"box-ordinal-group" = pre }; }, .@"box-align" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true, .moz = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"box-align" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"box-align" = pre }; }, .@"box-flex" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true, .moz = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"box-flex" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"box-flex" = pre }; }, .@"box-flex-group" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"box-flex-group" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"box-flex-group" = pre }; }, .@"box-pack" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true, .moz = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"box-pack" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"box-pack" = pre }; }, .@"box-lines" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true, .moz = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"box-lines" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"box-lines" = pre }; }, .@"flex-pack" => { const allowed_prefixes = VendorPrefix{ .none = true, .ms = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"flex-pack" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"flex-pack" = pre }; }, .@"flex-order" => { const allowed_prefixes = VendorPrefix{ .none = true, .ms = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"flex-order" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"flex-order" = pre }; }, .@"flex-align" => { const allowed_prefixes = VendorPrefix{ .none = true, .ms = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"flex-align" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"flex-align" = pre }; }, .@"flex-item-align" => { const allowed_prefixes = VendorPrefix{ .none = true, .ms = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"flex-item-align" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"flex-item-align" = pre }; }, .@"flex-line-pack" => { const allowed_prefixes = VendorPrefix{ .none = true, .ms = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"flex-line-pack" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"flex-line-pack" = pre }; }, .@"flex-positive" => { const allowed_prefixes = VendorPrefix{ .none = true, .ms = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"flex-positive" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"flex-positive" = pre }; }, .@"flex-negative" => { const allowed_prefixes = VendorPrefix{ .none = true, .ms = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"flex-negative" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"flex-negative" = pre }; }, .@"flex-preferred-size" => { const allowed_prefixes = VendorPrefix{ .none = true, .ms = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"flex-preferred-size" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"flex-preferred-size" = pre }; }, .@"margin-top" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"margin-top"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"margin-top"; }, .@"margin-bottom" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"margin-bottom"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"margin-bottom"; }, .@"margin-left" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"margin-left"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"margin-left"; }, .@"margin-right" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"margin-right"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"margin-right"; }, .@"margin-block-start" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"margin-block-start"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"margin-block-start"; }, .@"margin-block-end" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"margin-block-end"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"margin-block-end"; }, .@"margin-inline-start" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"margin-inline-start"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"margin-inline-start"; }, .@"margin-inline-end" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"margin-inline-end"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"margin-inline-end"; }, .@"margin-block" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"margin-block"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"margin-block"; }, .@"margin-inline" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"margin-inline"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"margin-inline"; }, .margin => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .margin; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .margin; }, .@"padding-top" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"padding-top"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"padding-top"; }, .@"padding-bottom" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"padding-bottom"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"padding-bottom"; }, .@"padding-left" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"padding-left"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"padding-left"; }, .@"padding-right" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"padding-right"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"padding-right"; }, .@"padding-block-start" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"padding-block-start"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"padding-block-start"; }, .@"padding-block-end" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"padding-block-end"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"padding-block-end"; }, .@"padding-inline-start" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"padding-inline-start"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"padding-inline-start"; }, .@"padding-inline-end" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"padding-inline-end"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"padding-inline-end"; }, .@"padding-block" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"padding-block"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"padding-block"; }, .@"padding-inline" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"padding-inline"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"padding-inline"; }, .padding => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .padding; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .padding; }, .@"scroll-margin-top" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"scroll-margin-top"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"scroll-margin-top"; }, .@"scroll-margin-bottom" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"scroll-margin-bottom"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"scroll-margin-bottom"; }, .@"scroll-margin-left" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"scroll-margin-left"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"scroll-margin-left"; }, .@"scroll-margin-right" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"scroll-margin-right"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"scroll-margin-right"; }, .@"scroll-margin-block-start" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"scroll-margin-block-start"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"scroll-margin-block-start"; }, .@"scroll-margin-block-end" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"scroll-margin-block-end"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"scroll-margin-block-end"; }, .@"scroll-margin-inline-start" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"scroll-margin-inline-start"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"scroll-margin-inline-start"; }, .@"scroll-margin-inline-end" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"scroll-margin-inline-end"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"scroll-margin-inline-end"; }, .@"scroll-margin-block" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"scroll-margin-block"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"scroll-margin-block"; }, .@"scroll-margin-inline" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"scroll-margin-inline"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"scroll-margin-inline"; }, .@"scroll-margin" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"scroll-margin"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"scroll-margin"; }, .@"scroll-padding-top" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"scroll-padding-top"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"scroll-padding-top"; }, .@"scroll-padding-bottom" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"scroll-padding-bottom"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"scroll-padding-bottom"; }, .@"scroll-padding-left" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"scroll-padding-left"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"scroll-padding-left"; }, .@"scroll-padding-right" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"scroll-padding-right"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"scroll-padding-right"; }, .@"scroll-padding-block-start" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"scroll-padding-block-start"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"scroll-padding-block-start"; }, .@"scroll-padding-block-end" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"scroll-padding-block-end"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"scroll-padding-block-end"; }, .@"scroll-padding-inline-start" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"scroll-padding-inline-start"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"scroll-padding-inline-start"; }, .@"scroll-padding-inline-end" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"scroll-padding-inline-end"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"scroll-padding-inline-end"; }, .@"scroll-padding-block" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"scroll-padding-block"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"scroll-padding-block"; }, .@"scroll-padding-inline" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"scroll-padding-inline"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"scroll-padding-inline"; }, .@"scroll-padding" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"scroll-padding"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"scroll-padding"; }, .@"font-weight" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"font-weight"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"font-weight"; }, .@"font-size" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"font-size"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"font-size"; }, .@"font-stretch" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"font-stretch"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"font-stretch"; }, .@"font-family" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"font-family"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"font-family"; }, .@"font-style" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"font-style"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"font-style"; }, .@"font-variant-caps" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"font-variant-caps"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"font-variant-caps"; }, .@"line-height" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"line-height"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"line-height"; }, .font => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .font; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .font; }, .@"transition-property" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true, .moz = true, .ms = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"transition-property" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"transition-property" = pre }; }, .@"transition-duration" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true, .moz = true, .ms = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"transition-duration" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"transition-duration" = pre }; }, .@"transition-delay" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true, .moz = true, .ms = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"transition-delay" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"transition-delay" = pre }; }, .@"transition-timing-function" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true, .moz = true, .ms = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"transition-timing-function" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"transition-timing-function" = pre }; }, .transition => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true, .moz = true, .ms = true }; - if (allowed_prefixes.contains(pre)) return .{ .transition = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .transition = pre }; }, .transform => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true, .moz = true, .ms = true, .o = true }; - if (allowed_prefixes.contains(pre)) return .{ .transform = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .transform = pre }; }, .@"transform-origin" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true, .moz = true, .ms = true, .o = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"transform-origin" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"transform-origin" = pre }; }, .@"transform-style" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true, .moz = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"transform-style" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"transform-style" = pre }; }, .@"transform-box" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"transform-box"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"transform-box"; }, .@"backface-visibility" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true, .moz = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"backface-visibility" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"backface-visibility" = pre }; }, .perspective => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true, .moz = true }; - if (allowed_prefixes.contains(pre)) return .{ .perspective = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .perspective = pre }; }, .@"perspective-origin" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true, .moz = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"perspective-origin" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"perspective-origin" = pre }; }, .translate => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .translate; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .translate; }, .rotate => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .rotate; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .rotate; }, .scale => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .scale; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .scale; }, .@"text-decoration-color" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true, .moz = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"text-decoration-color" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"text-decoration-color" = pre }; }, .@"text-emphasis-color" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"text-emphasis-color" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"text-emphasis-color" = pre }; }, .@"text-shadow" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"text-shadow"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"text-shadow"; }, .direction => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .direction; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .direction; }, .composes => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .composes; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .composes; }, .@"mask-image" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"mask-image" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"mask-image" = pre }; }, .@"mask-mode" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"mask-mode"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"mask-mode"; }, .@"mask-repeat" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"mask-repeat" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"mask-repeat" = pre }; }, .@"mask-position-x" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"mask-position-x"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"mask-position-x"; }, .@"mask-position-y" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"mask-position-y"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"mask-position-y"; }, .@"mask-position" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"mask-position" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"mask-position" = pre }; }, .@"mask-clip" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"mask-clip" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"mask-clip" = pre }; }, .@"mask-origin" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"mask-origin" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"mask-origin" = pre }; }, .@"mask-size" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"mask-size" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"mask-size" = pre }; }, .@"mask-composite" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"mask-composite"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"mask-composite"; }, .@"mask-type" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"mask-type"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"mask-type"; }, .mask => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true }; - if (allowed_prefixes.contains(pre)) return .{ .mask = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .mask = pre }; }, .@"mask-border-source" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"mask-border-source"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"mask-border-source"; }, .@"mask-border-mode" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"mask-border-mode"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"mask-border-mode"; }, .@"mask-border-slice" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"mask-border-slice"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"mask-border-slice"; }, .@"mask-border-width" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"mask-border-width"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"mask-border-width"; }, .@"mask-border-outset" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"mask-border-outset"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"mask-border-outset"; }, .@"mask-border-repeat" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"mask-border-repeat"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"mask-border-repeat"; }, .@"mask-border" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"mask-border"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"mask-border"; }, .@"-webkit-mask-composite" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"-webkit-mask-composite"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"-webkit-mask-composite"; }, .@"mask-source-type" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"mask-source-type" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"mask-source-type" = pre }; }, .@"mask-box-image" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"mask-box-image" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"mask-box-image" = pre }; }, .@"mask-box-image-source" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"mask-box-image-source" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"mask-box-image-source" = pre }; }, .@"mask-box-image-slice" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"mask-box-image-slice" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"mask-box-image-slice" = pre }; }, .@"mask-box-image-width" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"mask-box-image-width" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"mask-box-image-width" = pre }; }, .@"mask-box-image-outset" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"mask-box-image-outset" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"mask-box-image-outset" = pre }; }, .@"mask-box-image-repeat" => { const allowed_prefixes = VendorPrefix{ .none = true, .webkit = true }; - if (allowed_prefixes.contains(pre)) return .{ .@"mask-box-image-repeat" = pre }; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .{ .@"mask-box-image-repeat" = pre }; }, .@"color-scheme" => { const allowed_prefixes = VendorPrefix{ .none = true }; - if (allowed_prefixes.contains(pre)) return .@"color-scheme"; + if (bits.contains(VendorPrefix, allowed_prefixes, pre)) return .@"color-scheme"; }, } } @@ -9199,383 +9202,13 @@ pub const PropertyId = union(PropertyIdTag) { pub fn addPrefix(this: *PropertyId, pre: VendorPrefix) void { return switch (this.*) { - .@"background-color" => {}, - .@"background-image" => {}, - .@"background-position-x" => {}, - .@"background-position-y" => {}, - .@"background-position" => {}, - .@"background-size" => {}, - .@"background-repeat" => {}, - .@"background-attachment" => {}, - .@"background-clip" => |*p| { - p.insert(pre); + inline else => |*p| { + switch (@TypeOf(p)) { + *void, *CustomPropertyName => {}, + *VendorPrefix => bits.insert(VendorPrefix, p, pre), + else => |T| @compileError("unexpected " ++ @typeName(T)), + } }, - .@"background-origin" => {}, - .background => {}, - .@"box-shadow" => |*p| { - p.insert(pre); - }, - .opacity => {}, - .color => {}, - .display => {}, - .visibility => {}, - .width => {}, - .height => {}, - .@"min-width" => {}, - .@"min-height" => {}, - .@"max-width" => {}, - .@"max-height" => {}, - .@"block-size" => {}, - .@"inline-size" => {}, - .@"min-block-size" => {}, - .@"min-inline-size" => {}, - .@"max-block-size" => {}, - .@"max-inline-size" => {}, - .@"box-sizing" => |*p| { - p.insert(pre); - }, - .@"aspect-ratio" => {}, - .overflow => {}, - .@"overflow-x" => {}, - .@"overflow-y" => {}, - .@"text-overflow" => |*p| { - p.insert(pre); - }, - .position => {}, - .top => {}, - .bottom => {}, - .left => {}, - .right => {}, - .@"inset-block-start" => {}, - .@"inset-block-end" => {}, - .@"inset-inline-start" => {}, - .@"inset-inline-end" => {}, - .@"inset-block" => {}, - .@"inset-inline" => {}, - .inset => {}, - .@"border-spacing" => {}, - .@"border-top-color" => {}, - .@"border-bottom-color" => {}, - .@"border-left-color" => {}, - .@"border-right-color" => {}, - .@"border-block-start-color" => {}, - .@"border-block-end-color" => {}, - .@"border-inline-start-color" => {}, - .@"border-inline-end-color" => {}, - .@"border-top-style" => {}, - .@"border-bottom-style" => {}, - .@"border-left-style" => {}, - .@"border-right-style" => {}, - .@"border-block-start-style" => {}, - .@"border-block-end-style" => {}, - .@"border-inline-start-style" => {}, - .@"border-inline-end-style" => {}, - .@"border-top-width" => {}, - .@"border-bottom-width" => {}, - .@"border-left-width" => {}, - .@"border-right-width" => {}, - .@"border-block-start-width" => {}, - .@"border-block-end-width" => {}, - .@"border-inline-start-width" => {}, - .@"border-inline-end-width" => {}, - .@"border-top-left-radius" => |*p| { - p.insert(pre); - }, - .@"border-top-right-radius" => |*p| { - p.insert(pre); - }, - .@"border-bottom-left-radius" => |*p| { - p.insert(pre); - }, - .@"border-bottom-right-radius" => |*p| { - p.insert(pre); - }, - .@"border-start-start-radius" => {}, - .@"border-start-end-radius" => {}, - .@"border-end-start-radius" => {}, - .@"border-end-end-radius" => {}, - .@"border-radius" => |*p| { - p.insert(pre); - }, - .@"border-image-source" => {}, - .@"border-image-outset" => {}, - .@"border-image-repeat" => {}, - .@"border-image-width" => {}, - .@"border-image-slice" => {}, - .@"border-image" => |*p| { - p.insert(pre); - }, - .@"border-color" => {}, - .@"border-style" => {}, - .@"border-width" => {}, - .@"border-block-color" => {}, - .@"border-block-style" => {}, - .@"border-block-width" => {}, - .@"border-inline-color" => {}, - .@"border-inline-style" => {}, - .@"border-inline-width" => {}, - .border => {}, - .@"border-top" => {}, - .@"border-bottom" => {}, - .@"border-left" => {}, - .@"border-right" => {}, - .@"border-block" => {}, - .@"border-block-start" => {}, - .@"border-block-end" => {}, - .@"border-inline" => {}, - .@"border-inline-start" => {}, - .@"border-inline-end" => {}, - .outline => {}, - .@"outline-color" => {}, - .@"outline-style" => {}, - .@"outline-width" => {}, - .@"flex-direction" => |*p| { - p.insert(pre); - }, - .@"flex-wrap" => |*p| { - p.insert(pre); - }, - .@"flex-flow" => |*p| { - p.insert(pre); - }, - .@"flex-grow" => |*p| { - p.insert(pre); - }, - .@"flex-shrink" => |*p| { - p.insert(pre); - }, - .@"flex-basis" => |*p| { - p.insert(pre); - }, - .flex => |*p| { - p.insert(pre); - }, - .order => |*p| { - p.insert(pre); - }, - .@"align-content" => |*p| { - p.insert(pre); - }, - .@"justify-content" => |*p| { - p.insert(pre); - }, - .@"place-content" => {}, - .@"align-self" => |*p| { - p.insert(pre); - }, - .@"justify-self" => {}, - .@"place-self" => {}, - .@"align-items" => |*p| { - p.insert(pre); - }, - .@"justify-items" => {}, - .@"place-items" => {}, - .@"row-gap" => {}, - .@"column-gap" => {}, - .gap => {}, - .@"box-orient" => |*p| { - p.insert(pre); - }, - .@"box-direction" => |*p| { - p.insert(pre); - }, - .@"box-ordinal-group" => |*p| { - p.insert(pre); - }, - .@"box-align" => |*p| { - p.insert(pre); - }, - .@"box-flex" => |*p| { - p.insert(pre); - }, - .@"box-flex-group" => |*p| { - p.insert(pre); - }, - .@"box-pack" => |*p| { - p.insert(pre); - }, - .@"box-lines" => |*p| { - p.insert(pre); - }, - .@"flex-pack" => |*p| { - p.insert(pre); - }, - .@"flex-order" => |*p| { - p.insert(pre); - }, - .@"flex-align" => |*p| { - p.insert(pre); - }, - .@"flex-item-align" => |*p| { - p.insert(pre); - }, - .@"flex-line-pack" => |*p| { - p.insert(pre); - }, - .@"flex-positive" => |*p| { - p.insert(pre); - }, - .@"flex-negative" => |*p| { - p.insert(pre); - }, - .@"flex-preferred-size" => |*p| { - p.insert(pre); - }, - .@"margin-top" => {}, - .@"margin-bottom" => {}, - .@"margin-left" => {}, - .@"margin-right" => {}, - .@"margin-block-start" => {}, - .@"margin-block-end" => {}, - .@"margin-inline-start" => {}, - .@"margin-inline-end" => {}, - .@"margin-block" => {}, - .@"margin-inline" => {}, - .margin => {}, - .@"padding-top" => {}, - .@"padding-bottom" => {}, - .@"padding-left" => {}, - .@"padding-right" => {}, - .@"padding-block-start" => {}, - .@"padding-block-end" => {}, - .@"padding-inline-start" => {}, - .@"padding-inline-end" => {}, - .@"padding-block" => {}, - .@"padding-inline" => {}, - .padding => {}, - .@"scroll-margin-top" => {}, - .@"scroll-margin-bottom" => {}, - .@"scroll-margin-left" => {}, - .@"scroll-margin-right" => {}, - .@"scroll-margin-block-start" => {}, - .@"scroll-margin-block-end" => {}, - .@"scroll-margin-inline-start" => {}, - .@"scroll-margin-inline-end" => {}, - .@"scroll-margin-block" => {}, - .@"scroll-margin-inline" => {}, - .@"scroll-margin" => {}, - .@"scroll-padding-top" => {}, - .@"scroll-padding-bottom" => {}, - .@"scroll-padding-left" => {}, - .@"scroll-padding-right" => {}, - .@"scroll-padding-block-start" => {}, - .@"scroll-padding-block-end" => {}, - .@"scroll-padding-inline-start" => {}, - .@"scroll-padding-inline-end" => {}, - .@"scroll-padding-block" => {}, - .@"scroll-padding-inline" => {}, - .@"scroll-padding" => {}, - .@"font-weight" => {}, - .@"font-size" => {}, - .@"font-stretch" => {}, - .@"font-family" => {}, - .@"font-style" => {}, - .@"font-variant-caps" => {}, - .@"line-height" => {}, - .font => {}, - .@"transition-property" => |*p| { - p.insert(pre); - }, - .@"transition-duration" => |*p| { - p.insert(pre); - }, - .@"transition-delay" => |*p| { - p.insert(pre); - }, - .@"transition-timing-function" => |*p| { - p.insert(pre); - }, - .transition => |*p| { - p.insert(pre); - }, - .transform => |*p| { - p.insert(pre); - }, - .@"transform-origin" => |*p| { - p.insert(pre); - }, - .@"transform-style" => |*p| { - p.insert(pre); - }, - .@"transform-box" => {}, - .@"backface-visibility" => |*p| { - p.insert(pre); - }, - .perspective => |*p| { - p.insert(pre); - }, - .@"perspective-origin" => |*p| { - p.insert(pre); - }, - .translate => {}, - .rotate => {}, - .scale => {}, - .@"text-decoration-color" => |*p| { - p.insert(pre); - }, - .@"text-emphasis-color" => |*p| { - p.insert(pre); - }, - .@"text-shadow" => {}, - .direction => {}, - .composes => {}, - .@"mask-image" => |*p| { - p.insert(pre); - }, - .@"mask-mode" => {}, - .@"mask-repeat" => |*p| { - p.insert(pre); - }, - .@"mask-position-x" => {}, - .@"mask-position-y" => {}, - .@"mask-position" => |*p| { - p.insert(pre); - }, - .@"mask-clip" => |*p| { - p.insert(pre); - }, - .@"mask-origin" => |*p| { - p.insert(pre); - }, - .@"mask-size" => |*p| { - p.insert(pre); - }, - .@"mask-composite" => {}, - .@"mask-type" => {}, - .mask => |*p| { - p.insert(pre); - }, - .@"mask-border-source" => {}, - .@"mask-border-mode" => {}, - .@"mask-border-slice" => {}, - .@"mask-border-width" => {}, - .@"mask-border-outset" => {}, - .@"mask-border-repeat" => {}, - .@"mask-border" => {}, - .@"-webkit-mask-composite" => {}, - .@"mask-source-type" => |*p| { - p.insert(pre); - }, - .@"mask-box-image" => |*p| { - p.insert(pre); - }, - .@"mask-box-image-source" => |*p| { - p.insert(pre); - }, - .@"mask-box-image-slice" => |*p| { - p.insert(pre); - }, - .@"mask-box-image-width" => |*p| { - p.insert(pre); - }, - .@"mask-box-image-outset" => |*p| { - p.insert(pre); - }, - .@"mask-box-image-repeat" => |*p| { - p.insert(pre); - }, - .@"color-scheme" => {}, - else => {}, }; } @@ -9588,7 +9221,7 @@ pub const PropertyId = union(PropertyIdTag) { inline for (bun.meta.EnumFields(PropertyId), std.meta.fields(PropertyId)) |enum_field, union_field| { if (enum_field.value == @intFromEnum(lhs.*)) { if (comptime union_field.type == css.VendorPrefix) { - return @field(lhs, union_field.name).eql(@field(rhs, union_field.name)); + return @field(lhs, union_field.name) == @field(rhs, union_field.name); } else { return true; } diff --git a/src/css/properties/properties_impl.zig b/src/css/properties/properties_impl.zig index 514578d6ec..4f420f16a1 100644 --- a/src/css/properties/properties_impl.zig +++ b/src/css/properties/properties_impl.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Allocator = std.mem.Allocator; pub const css = @import("../css_parser.zig"); @@ -14,107 +14,99 @@ const Error = css.Error; const PropertyId = css.PropertyId; const Property = css.Property; -pub fn PropertyIdImpl() type { - return struct { - pub fn toCss(this: *const PropertyId, comptime W: type, dest: *Printer(W)) PrintErr!void { - var first = true; - const name = this.name(); - const prefix_value = this.prefix().orNone(); +pub const property_id_mixin = struct { + pub fn toCss(this: *const PropertyId, comptime W: type, dest: *Printer(W)) PrintErr!void { + var first = true; + const name = this.name(); + const prefix_value = this.prefix().orNone(); - inline for (VendorPrefix.FIELDS) |field| { - if (@field(prefix_value, field)) { - var prefix: VendorPrefix = .{}; - @field(prefix, field) = true; + inline for (VendorPrefix.FIELDS) |field| { + if (@field(prefix_value, field)) { + var prefix: VendorPrefix = .{}; + @field(prefix, field) = true; - if (first) { - first = false; - } else { - try dest.delim(',', false); - } - try prefix.toCss(W, dest); - try dest.writeStr(name); + if (first) { + first = false; + } else { + try dest.delim(',', false); } + try prefix.toCss(W, dest); + try dest.writeStr(name); } } + } - pub fn parse(input: *css.Parser) css.Result(PropertyId) { - const name = switch (input.expectIdent()) { - .result => |v| v, - .err => |e| return .{ .err = e }, - }; - return .{ .result = fromString(name) }; + pub fn parse(input: *css.Parser) css.Result(PropertyId) { + const name = switch (input.expectIdent()) { + .result => |v| v, + .err => |e| return .{ .err = e }, + }; + return .{ .result = fromString(name) }; + } + + pub fn fromString(name_: []const u8) PropertyId { + const name_ref = name_; + var prefix: VendorPrefix = undefined; + var trimmed_name: []const u8 = undefined; + + // TODO: todo_stuff.match_ignore_ascii_case + if (bun.strings.startsWithCaseInsensitiveAscii(name_ref, "-webkit-")) { + prefix = VendorPrefix{ .webkit = true }; + trimmed_name = name_ref[8..]; + } else if (bun.strings.startsWithCaseInsensitiveAscii(name_ref, "-moz-")) { + prefix = VendorPrefix{ .moz = true }; + trimmed_name = name_ref[5..]; + } else if (bun.strings.startsWithCaseInsensitiveAscii(name_ref, "-o-")) { + prefix = VendorPrefix{ .o = true }; + trimmed_name = name_ref[3..]; + } else if (bun.strings.startsWithCaseInsensitiveAscii(name_ref, "-ms-")) { + prefix = VendorPrefix{ .ms = true }; + trimmed_name = name_ref[4..]; + } else { + prefix = VendorPrefix{ .none = true }; + trimmed_name = name_ref; } - pub fn fromStr(name: []const u8) PropertyId { - return fromString(name); - } + return PropertyId.fromNameAndPrefix(trimmed_name, prefix) orelse .{ .custom = CustomPropertyName.fromStr(name_) }; + } +}; - pub fn fromString(name_: []const u8) PropertyId { - const name_ref = name_; - var prefix: VendorPrefix = undefined; - var trimmed_name: []const u8 = undefined; - - // TODO: todo_stuff.match_ignore_ascii_case - if (bun.strings.startsWithCaseInsensitiveAscii(name_ref, "-webkit-")) { - prefix = VendorPrefix{ .webkit = true }; - trimmed_name = name_ref[8..]; - } else if (bun.strings.startsWithCaseInsensitiveAscii(name_ref, "-moz-")) { - prefix = VendorPrefix{ .moz = true }; - trimmed_name = name_ref[5..]; - } else if (bun.strings.startsWithCaseInsensitiveAscii(name_ref, "-o-")) { - prefix = VendorPrefix{ .o = true }; - trimmed_name = name_ref[3..]; - } else if (bun.strings.startsWithCaseInsensitiveAscii(name_ref, "-ms-")) { - prefix = VendorPrefix{ .ms = true }; - trimmed_name = name_ref[4..]; - } else { - prefix = VendorPrefix{ .none = true }; - trimmed_name = name_ref; +pub const property_mixin = struct { + /// Serializes the CSS property, with an optional `!important` flag. + pub fn toCss(this: *const Property, comptime W: type, dest: *Printer(W), important: bool) PrintErr!void { + if (this.* == .custom) { + try this.custom.name.toCss(W, dest); + try dest.delim(':', false); + try this.valueToCss(W, dest); + if (important) { + try dest.whitespace(); + try dest.writeStr("!important"); } - - return PropertyId.fromNameAndPrefix(trimmed_name, prefix) orelse .{ .custom = CustomPropertyName.fromStr(name_) }; + return; } - }; -} + const name, const prefix = this.__toCssHelper(); + var first = true; -pub fn PropertyImpl() type { - return struct { - /// Serializes the CSS property, with an optional `!important` flag. - pub fn toCss(this: *const Property, comptime W: type, dest: *Printer(W), important: bool) PrintErr!void { - if (this.* == .custom) { - try this.custom.name.toCss(W, dest); + inline for (VendorPrefix.FIELDS) |field| { + if (@field(prefix, field)) { + var p: VendorPrefix = .{}; + @field(p, field) = true; + + if (first) { + first = false; + } else { + try dest.writeChar(';'); + try dest.newline(); + } + try p.toCss(W, dest); + try dest.writeStr(name); try dest.delim(':', false); try this.valueToCss(W, dest); if (important) { try dest.whitespace(); try dest.writeStr("!important"); } - return; - } - const name, const prefix = this.__toCssHelper(); - var first = true; - - inline for (VendorPrefix.FIELDS) |field| { - if (@field(prefix, field)) { - var p: VendorPrefix = .{}; - @field(p, field) = true; - - if (first) { - first = false; - } else { - try dest.writeChar(';'); - try dest.newline(); - } - try p.toCss(W, dest); - try dest.writeStr(name); - try dest.delim(':', false); - try this.valueToCss(W, dest); - if (important) { - try dest.whitespace(); - try dest.writeStr("!important"); - } - } } } - }; -} + } +}; diff --git a/src/css/properties/shape.zig b/src/css/properties/shape.zig index 5d815259dc..f1047524ed 100644 --- a/src/css/properties/shape.zig +++ b/src/css/properties/shape.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Allocator = std.mem.Allocator; const ArrayList = std.ArrayListUnmanaged; diff --git a/src/css/properties/size.zig b/src/css/properties/size.zig index c0f48f137e..74974a3e87 100644 --- a/src/css/properties/size.zig +++ b/src/css/properties/size.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Allocator = std.mem.Allocator; const ArrayList = std.ArrayListUnmanaged; @@ -44,7 +44,12 @@ pub const BoxSizing = enum { @"content-box", /// Include the padding and border (but not the margin) in the width and height. @"border-box", - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; }; pub const Size = union(enum) { @@ -141,11 +146,11 @@ pub const Size = union(enum) { try dest.writeStr("fit-content"); }, .stretch => |vp| { - if (vp.eql(css.VendorPrefix{ .none = true })) { + if (vp == css.VendorPrefix{ .none = true }) { try dest.writeStr("stretch"); - } else if (vp.eql(css.VendorPrefix{ .webkit = true })) { + } else if (vp == css.VendorPrefix{ .webkit = true }) { try dest.writeStr("-webkit-fill-available"); - } else if (vp.eql(css.VendorPrefix{ .moz = true })) { + } else if (vp == css.VendorPrefix{ .moz = true }) { try dest.writeStr("-moz-available"); } else { bun.unreachablePanic("Unexpected vendor prefixes", .{}); @@ -301,11 +306,11 @@ pub const MaxSize = union(enum) { try dest.writeStr("fit-content"); }, .stretch => |vp| { - if (css.VendorPrefix.eql(vp, css.VendorPrefix{ .none = true })) { + if (vp == css.VendorPrefix{ .none = true }) { try dest.writeStr("stretch"); - } else if (css.VendorPrefix.eql(vp, css.VendorPrefix{ .webkit = true })) { + } else if (vp == css.VendorPrefix{ .webkit = true }) { try dest.writeStr("-webkit-fill-available"); - } else if (css.VendorPrefix.eql(vp, css.VendorPrefix{ .moz = true })) { + } else if (vp == css.VendorPrefix{ .moz = true }) { try dest.writeStr("-moz-available"); } else { bun.unreachablePanic("Unexpected vendor prefixes", .{}); @@ -418,8 +423,6 @@ pub const SizeProperty = packed struct(u16) { @"max-inline-size": bool = false, __unused: u4 = 0, - pub usingnamespace css.Bitflags(@This()); - pub fn tryFromPropertyIdTag(property_id: PropertyIdTag) ?SizeProperty { inline for (std.meta.fields(@This())) |field| { if (comptime std.mem.eql(u8, field.name, "__unused")) continue; @@ -471,7 +474,7 @@ pub const SizeHandler = struct { .unparsed => |*unparsed| { switch (unparsed.property_id) { .width, .height, .@"min-width", .@"max-width", .@"min-height", .@"max-height" => { - this.flushed_properties.insert(SizeProperty.tryFromPropertyIdTag(@as(PropertyIdTag, unparsed.property_id)).?); + bun.bits.insert(SizeProperty, &this.flushed_properties, SizeProperty.tryFromPropertyIdTag(@as(PropertyIdTag, unparsed.property_id)).?); dest.append(context.allocator, property.deepClone(context.allocator)) catch unreachable; }, .@"block-size" => this.logicalUnparsedHelper(property, unparsed, .height, logical_supported, dest, context), @@ -491,7 +494,7 @@ pub const SizeHandler = struct { inline fn logicalUnparsedHelper(this: *@This(), property: *const Property, unparsed: *const UnparsedProperty, comptime physical: PropertyIdTag, logical_supported: bool, dest: *css.DeclarationList, context: *css.PropertyHandlerContext) void { if (logical_supported) { - this.flushed_properties.insert(SizeProperty.tryFromPropertyIdTag(@as(PropertyIdTag, unparsed.property_id)).?); + bun.bits.insert(SizeProperty, &this.flushed_properties, SizeProperty.tryFromPropertyIdTag(@as(PropertyIdTag, unparsed.property_id)).?); dest.append(context.allocator, property.deepClone(context.allocator)) catch bun.outOfMemory(); } else { dest.append(context.allocator, Property{ @@ -500,7 +503,7 @@ pub const SizeHandler = struct { @unionInit(PropertyId, @tagName(physical), {}), ), }) catch bun.outOfMemory(); - this.flushed_properties.insert(SizeProperty.fromName(@tagName(physical))); + @field(this.flushed_properties, @tagName(physical)) = true; } } @@ -548,7 +551,7 @@ pub const SizeHandler = struct { pub fn finalize(this: *@This(), dest: *css.DeclarationList, context: *css.PropertyHandlerContext) void { this.flush(dest, context); - this.flushed_properties = SizeProperty.empty(); + this.flushed_properties = SizeProperty{}; } inline fn flushPrefixHelper( @@ -559,7 +562,7 @@ pub const SizeHandler = struct { dest: *css.DeclarationList, context: *css.PropertyHandlerContext, ) void { - if (!this.flushed_properties.contains(comptime SizeProperty.fromName(@tagName(property)))) { + if (!@field(this.flushed_properties, @tagName(property))) { const prefixes = context.targets.prefixes(css.VendorPrefix{ .none = true }, feature).difference(css.VendorPrefix{ .none = true }); inline for (css.VendorPrefix.FIELDS) |field| { if (@field(prefixes, field)) { @@ -588,22 +591,22 @@ pub const SizeHandler = struct { ) void { if (bun.take(&@field(this, field))) |val| { switch (val) { - .stretch => |vp| if (vp.eql(css.VendorPrefix{ .none = true })) { + .stretch => |vp| if (vp == css.VendorPrefix{ .none = true }) { this.flushPrefixHelper(property, SizeType, .stretch, dest, context); }, - .min_content => |vp| if (vp.eql(css.VendorPrefix{ .none = true })) { + .min_content => |vp| if (vp == css.VendorPrefix{ .none = true }) { this.flushPrefixHelper(property, SizeType, .min_content, dest, context); }, - .max_content => |vp| if (vp.eql(css.VendorPrefix{ .none = true })) { + .max_content => |vp| if (vp == css.VendorPrefix{ .none = true }) { this.flushPrefixHelper(property, SizeType, .max_content, dest, context); }, - .fit_content => |vp| if (vp.eql(css.VendorPrefix{ .none = true })) { + .fit_content => |vp| if (vp == css.VendorPrefix{ .none = true }) { this.flushPrefixHelper(property, SizeType, .fit_content, dest, context); }, else => {}, } dest.append(context.allocator, @unionInit(Property, @tagName(property), val.deepClone(context.allocator))) catch bun.outOfMemory(); - this.flushed_properties.insert(comptime SizeProperty.fromName(@tagName(property))); + @field(this.flushed_properties, @tagName(property)) = true; } } diff --git a/src/css/properties/svg.zig b/src/css/properties/svg.zig index b46734d7cb..13be40d882 100644 --- a/src/css/properties/svg.zig +++ b/src/css/properties/svg.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Allocator = std.mem.Allocator; const ArrayList = std.ArrayListUnmanaged; diff --git a/src/css/properties/text.zig b/src/css/properties/text.zig index 7ad11f9a05..d572f299fc 100644 --- a/src/css/properties/text.zig +++ b/src/css/properties/text.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Allocator = std.mem.Allocator; const ArrayList = std.ArrayListUnmanaged; @@ -279,7 +279,12 @@ pub const Direction = enum { /// This value sets inline base direction (bidi directionality) to line-right-to-line-left. rtl, - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; }; /// A value for the [unicode-bidi](https://drafts.csswg.org/css-writing-modes-3/#unicode-bidi) property. diff --git a/src/css/properties/transform.zig b/src/css/properties/transform.zig index 9be9dacb6e..e9410aef22 100644 --- a/src/css/properties/transform.zig +++ b/src/css/properties/transform.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Allocator = std.mem.Allocator; const ArrayList = std.ArrayListUnmanaged; @@ -864,7 +864,12 @@ pub fn Matrix3d(comptime T: type) type { pub const TransformStyle = enum { flat, @"preserve-3d", - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; }; /// A value for the [transform-box](https://drafts.csswg.org/css-transforms-1/#transform-box) property. @@ -880,7 +885,12 @@ pub const TransformBox = enum { /// Uses the nearest SVG viewport as reference box. @"view-box", - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; }; /// A value for the [backface-visibility](https://drafts.csswg.org/css-transforms-2/#backface-visibility-property) property. @@ -888,7 +898,12 @@ pub const BackfaceVisibility = enum { visible, hidden, - pub usingnamespace css.DefineEnumProperty(@This()); + const css_impl = css.DefineEnumProperty(@This()); + pub const eql = css_impl.eql; + pub const hash = css_impl.hash; + pub const parse = css_impl.parse; + pub const toCss = css_impl.toCss; + pub const deepClone = css_impl.deepClone; }; /// A value for the perspective property. @@ -898,8 +913,8 @@ pub const Perspective = union(enum) { /// Distance to the center of projection. length: Length, - pub usingnamespace css.DeriveParse(@This()); - pub usingnamespace css.DeriveToCss(@This()); + pub const parse = css.DeriveParse(@This()).parse; + pub const toCss = css.DeriveToCss(@This()).toCss; pub fn eql(this: *const @This(), other: *const @This()) bool { return css.implementEql(@This(), this, other); @@ -1230,14 +1245,14 @@ pub const TransformHandler = struct { // If two vendor prefixes for the same property have different // values, we need to flush what we have immediately to preserve order. if (this.transform) |current| { - if (!current[0].eql(&transform_val) and !current[1].contains(vp)) { + if (!current[0].eql(&transform_val) and !bun.bits.contains(css.VendorPrefix, current[1], vp)) { this.flush(allocator, dest, context); } } // Otherwise, update the value and add the prefix. if (this.transform) |*transform| { - transform.* = .{ transform_val.deepClone(allocator), transform.*[1].bitwiseOr(vp) }; + transform.* = .{ transform_val.deepClone(allocator), bun.bits.@"or"(css.VendorPrefix, transform.*[1], vp) }; } else { this.transform = .{ transform_val.deepClone(allocator), vp }; this.has_any = true; diff --git a/src/css/properties/transition.zig b/src/css/properties/transition.zig index c2acd1a3fd..d8a68ca122 100644 --- a/src/css/properties/transition.zig +++ b/src/css/properties/transition.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Allocator = std.mem.Allocator; const ArrayList = std.ArrayListUnmanaged; @@ -52,9 +52,6 @@ pub const Transition = struct { /// The easing function for the transition. timing_function: EasingFunction, - pub usingnamespace css.DefineShorthand(@This(), css.PropertyIdTag.transition, PropertyFieldMap); - pub usingnamespace css.DefineListShorthand(@This()); - pub const PropertyFieldMap = .{ .property = css.PropertyIdTag.@"transition-property", .duration = css.PropertyIdTag.@"transition-duration", @@ -211,7 +208,7 @@ pub const TransitionHandler = struct { const v = &p.*[0]; const prefixes = &p.*[1]; v.* = val.deepClone(context.allocator); - prefixes.insert(vp); + bun.bits.insert(VendorPrefix, prefixes, vp); prefixes.* = context.targets.prefixes(prefixes.*, feature); } else { const prefixes = context.targets.prefixes(vp, feature); @@ -227,7 +224,7 @@ pub const TransitionHandler = struct { if (@field(this, prop)) |*p| { const v = &p.*[0]; const prefixes = &p.*[1]; - if (!val.eql(v) and !prefixes.contains(vp)) { + if (!val.eql(v) and !bun.bits.contains(VendorPrefix, prefixes.*, vp)) { this.flush(dest, context); } } @@ -279,10 +276,10 @@ pub const TransitionHandler = struct { ) catch bun.outOfMemory(); } - property_prefixes.remove(intersection); - duration_prefixes.remove(intersection); - delay_prefixes.remove(intersection); - timing_prefixes.remove(intersection); + bun.bits.remove(VendorPrefix, property_prefixes, intersection); + bun.bits.remove(VendorPrefix, duration_prefixes, intersection); + bun.bits.remove(VendorPrefix, timing_prefixes, intersection); + bun.bits.remove(VendorPrefix, delay_prefixes, intersection); } } @@ -435,7 +432,7 @@ fn expandProperties(properties: *css.SmallList(PropertyId, 1), context: *css.Pro // Expand mask properties, which use different vendor-prefixed names. if (css.css_properties.masking.getWebkitMaskProperty(properties.at(i))) |property_id| { - if (context.targets.prefixes(VendorPrefix.NONE, Feature.mask_border).contains(VendorPrefix.WEBKIT)) { + if (context.targets.prefixes(VendorPrefix.NONE, Feature.mask_border).webkit) { properties.insert(context.allocator, i, property_id); i += 1; } @@ -445,7 +442,7 @@ fn expandProperties(properties: *css.SmallList(PropertyId, 1), context: *css.Pro rtl_props.mut(i).setPrefixesForTargets(context.targets); if (css.css_properties.masking.getWebkitMaskProperty(rtl_props.at(i))) |property_id| { - if (context.targets.prefixes(VendorPrefix.NONE, Feature.mask_border).contains(VendorPrefix.WEBKIT)) { + if (context.targets.prefixes(VendorPrefix.NONE, Feature.mask_border).webkit) { rtl_props.insert(context.allocator, i, property_id); i += 1; } diff --git a/src/css/properties/ui.zig b/src/css/properties/ui.zig index 3740c9418e..47c03afdf8 100644 --- a/src/css/properties/ui.zig +++ b/src/css/properties/ui.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Allocator = std.mem.Allocator; const ArrayList = std.ArrayListUnmanaged; @@ -43,12 +43,14 @@ pub const ColorScheme = packed struct(u8) { only: bool = false, __unused: u5 = 0, - pub usingnamespace css.Bitflags(@This()); + pub fn eql(a: ColorScheme, b: ColorScheme) bool { + return a == b; + } const Map = bun.ComptimeEnumMap(enum { normal, only, light, dark }); pub fn parse(input: *css.Parser) css.Result(ColorScheme) { - var res = ColorScheme.empty(); + var res = ColorScheme{}; const ident = switch (input.expectIdent()) { .result => |ident| ident, .err => |e| return .{ .err = e }, @@ -56,9 +58,9 @@ pub const ColorScheme = packed struct(u8) { if (Map.get(ident)) |value| switch (value) { .normal => return .{ .result = res }, - .only => res.insert(ColorScheme{ .only = true }), - .light => res.insert(ColorScheme{ .light = true }), - .dark => res.insert(ColorScheme{ .dark = true }), + .only => res.only = true, + .light => res.light = true, + .dark => res.dark = true, }; while (input.tryParse(css.Parser.expectIdent, .{}).asValue()) |i| { @@ -66,14 +68,14 @@ pub const ColorScheme = packed struct(u8) { .normal => return .{ .err = input.newCustomError(css.ParserError.invalid_value) }, .only => { // Only must be at the start or the end, not in the middle - if (res.contains(ColorScheme{ .only = true })) { + if (res.only) { return .{ .err = input.newCustomError(css.ParserError.invalid_value) }; } - res.insert(ColorScheme{ .only = true }); + res.only = true; return .{ .result = res }; }, - .light => res.insert(ColorScheme{ .light = true }), - .dark => res.insert(ColorScheme{ .dark = true }), + .light => res.light = true, + .dark => res.dark = true, }; } @@ -81,22 +83,22 @@ pub const ColorScheme = packed struct(u8) { } pub fn toCss(this: *const ColorScheme, comptime W: type, dest: *Printer(W)) css.PrintErr!void { - if (this.isEmpty()) { + if (this.* == ColorScheme{}) { return dest.writeStr("normal"); } - if (this.contains(ColorScheme{ .light = true })) { + if (this.light) { try dest.writeStr("light"); - if (this.contains(ColorScheme{ .dark = true })) { + if (this.dark) { try dest.writeChar(' '); } } - if (this.contains(ColorScheme{ .dark = true })) { + if (this.dark) { try dest.writeStr("dark"); } - if (this.contains(ColorScheme{ .only = true })) { + if (this.only) { try dest.writeStr(" only"); } } @@ -177,7 +179,7 @@ pub const ColorSchemeHandler = struct { .@"color-scheme" => |*color_scheme_| { const color_scheme: *const ColorScheme = color_scheme_; if (!context.targets.isCompatible(css.compat.Feature.light_dark)) { - if (color_scheme.contains(ColorScheme{ .light = true })) { + if (color_scheme.light) { dest.append( context.allocator, defineVar(context.allocator, "--buncss-light", .{ .ident = "initial" }), @@ -187,7 +189,7 @@ pub const ColorSchemeHandler = struct { defineVar(context.allocator, "--buncss-dark", .{ .whitespace = " " }), ) catch bun.outOfMemory(); - if (color_scheme.contains(ColorScheme{ .dark = true })) { + if (color_scheme.dark) { context.addDarkRule( context.allocator, defineVar(context.allocator, "--buncss-light", .{ .whitespace = " " }), @@ -197,7 +199,7 @@ pub const ColorSchemeHandler = struct { defineVar(context.allocator, "--buncss-dark", .{ .ident = "initial" }), ); } - } else if (color_scheme.contains(ColorScheme{ .dark = true })) { + } else if (color_scheme.dark) { dest.append(context.allocator, defineVar(context.allocator, "--buncss-light", .{ .whitespace = " " })) catch bun.outOfMemory(); dest.append(context.allocator, defineVar(context.allocator, "--buncss-dark", .{ .ident = "initial" })) catch bun.outOfMemory(); } diff --git a/src/css/rules/container.zig b/src/css/rules/container.zig index 13d7203b26..53f8a801fc 100644 --- a/src/css/rules/container.zig +++ b/src/css/rules/container.zig @@ -1,6 +1,6 @@ const std = @import("std"); pub const css = @import("../css_parser.zig"); -const bun = @import("root").bun; +const bun = @import("bun"); const Result = css.Result; const ArrayList = std.ArrayListUnmanaged; const MediaList = css.MediaList; @@ -62,7 +62,7 @@ pub const ContainerSizeFeatureId = enum { /// The [orientation](https://w3c.github.io/csswg-drafts/css-contain-3/#orientation) size container feature. orientation, - pub usingnamespace css.DeriveValueType(@This(), ValueTypeMap); + pub const valueType = css.DeriveValueType(@This(), ValueTypeMap).valueType; pub const ValueTypeMap = .{ .width = css.MediaFeatureType.length, @@ -334,7 +334,7 @@ pub fn ContainerRule(comptime R: type) type { // Don't downlevel range syntax in container queries. const exclude = dest.targets.exclude; - dest.targets.exclude.insert(css.targets.Features.media_queries); + bun.bits.insert(css.targets.Features, &dest.targets.exclude, .media_queries); try this.condition.toCss(W, dest); dest.targets.exclude = exclude; diff --git a/src/css/rules/counter_style.zig b/src/css/rules/counter_style.zig index 568aae137e..3fe3e6f77d 100644 --- a/src/css/rules/counter_style.zig +++ b/src/css/rules/counter_style.zig @@ -1,6 +1,6 @@ const std = @import("std"); pub const css = @import("../css_parser.zig"); -const bun = @import("root").bun; +const bun = @import("bun"); const Error = css.Error; const ArrayList = std.ArrayListUnmanaged; const MediaList = css.MediaList; diff --git a/src/css/rules/custom_media.zig b/src/css/rules/custom_media.zig index cc0d7d363e..bfaab11a39 100644 --- a/src/css/rules/custom_media.zig +++ b/src/css/rules/custom_media.zig @@ -1,6 +1,6 @@ const std = @import("std"); const Allocator = std.mem.Allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const logger = bun.logger; const Log = logger.Log; diff --git a/src/css/rules/document.zig b/src/css/rules/document.zig index 485aef4464..ad3131b331 100644 --- a/src/css/rules/document.zig +++ b/src/css/rules/document.zig @@ -1,6 +1,6 @@ const std = @import("std"); pub const css = @import("../css_parser.zig"); -const bun = @import("root").bun; +const bun = @import("bun"); const Error = css.Error; const ArrayList = std.ArrayListUnmanaged; const MediaList = css.MediaList; diff --git a/src/css/rules/font_face.zig b/src/css/rules/font_face.zig index 21b5cf3138..f3c82fcc44 100644 --- a/src/css/rules/font_face.zig +++ b/src/css/rules/font_face.zig @@ -1,6 +1,6 @@ const std = @import("std"); pub const css = @import("../css_parser.zig"); -const bun = @import("root").bun; +const bun = @import("bun"); const ArrayList = std.ArrayListUnmanaged; const MediaList = css.MediaList; const CustomMedia = css.CustomMedia; diff --git a/src/css/rules/font_palette_values.zig b/src/css/rules/font_palette_values.zig index fe59e11632..e93837aded 100644 --- a/src/css/rules/font_palette_values.zig +++ b/src/css/rules/font_palette_values.zig @@ -1,6 +1,6 @@ const std = @import("std"); pub const css = @import("../css_parser.zig"); -const bun = @import("root").bun; +const bun = @import("bun"); const Result = css.Result; const ArrayList = std.ArrayListUnmanaged; const MediaList = css.MediaList; diff --git a/src/css/rules/import.zig b/src/css/rules/import.zig index 5186bb7864..ad9b99d620 100644 --- a/src/css/rules/import.zig +++ b/src/css/rules/import.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); pub const css = @import("../css_parser.zig"); const Error = css.Error; const ArrayList = std.ArrayListUnmanaged; diff --git a/src/css/rules/keyframes.zig b/src/css/rules/keyframes.zig index d79eca6a7a..b93ae93522 100644 --- a/src/css/rules/keyframes.zig +++ b/src/css/rules/keyframes.zig @@ -1,6 +1,6 @@ const std = @import("std"); pub const css = @import("../css_parser.zig"); -const bun = @import("root").bun; +const bun = @import("bun"); const ArrayList = std.ArrayListUnmanaged; const MediaList = css.MediaList; const CustomMedia = css.CustomMedia; @@ -181,7 +181,7 @@ pub const KeyframeSelector = union(enum) { to, // TODO: implement this - pub usingnamespace css.DeriveParse(@This()); + pub const parse = css.DeriveParse(@This()).parse; // pub fn parse(input: *css.Parser) Result(KeyframeSelector) { // _ = input; // autofix @@ -263,12 +263,8 @@ pub const KeyframesRule = struct { var first_rule = true; - const PREFIXES = .{ "webkit", "moz", "ms", "o", "none" }; - - inline for (PREFIXES) |prefix_name| { - const prefix = css.VendorPrefix.fromName(prefix_name); - - if (this.vendor_prefix.contains(prefix)) { + inline for (.{ "webkit", "moz", "ms", "o", "none" }) |prefix_name| { + if (@field(this.vendor_prefix, prefix_name)) { if (first_rule) { first_rule = false; } else { @@ -279,7 +275,7 @@ pub const KeyframesRule = struct { } try dest.writeChar('@'); - try prefix.toCss(W, dest); + try css.VendorPrefix.fromName(prefix_name).toCss(W, dest); try dest.writeStr("keyframes "); try this.name.toCss(W, dest); try dest.whitespace(); diff --git a/src/css/rules/layer.zig b/src/css/rules/layer.zig index 657d4da8d8..7f591c8762 100644 --- a/src/css/rules/layer.zig +++ b/src/css/rules/layer.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); pub const css = @import("../css_parser.zig"); const ArrayList = std.ArrayListUnmanaged; const MediaList = css.MediaList; diff --git a/src/css/rules/media.zig b/src/css/rules/media.zig index d48d9a0938..f025b42977 100644 --- a/src/css/rules/media.zig +++ b/src/css/rules/media.zig @@ -1,6 +1,6 @@ const std = @import("std"); pub const css = @import("../css_parser.zig"); -const bun = @import("root").bun; +const bun = @import("bun"); const Error = css.Error; const ArrayList = std.ArrayListUnmanaged; const MediaList = css.MediaList; diff --git a/src/css/rules/namespace.zig b/src/css/rules/namespace.zig index 4f68a38371..7dd29a01e6 100644 --- a/src/css/rules/namespace.zig +++ b/src/css/rules/namespace.zig @@ -1,6 +1,6 @@ const std = @import("std"); const Allocator = std.mem.Allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const logger = bun.logger; const Log = logger.Log; diff --git a/src/css/rules/nesting.zig b/src/css/rules/nesting.zig index 9aceb97b51..9a24dac56e 100644 --- a/src/css/rules/nesting.zig +++ b/src/css/rules/nesting.zig @@ -1,6 +1,6 @@ const std = @import("std"); pub const css = @import("../css_parser.zig"); -const bun = @import("root").bun; +const bun = @import("bun"); const Error = css.Error; const ArrayList = std.ArrayListUnmanaged; const MediaList = css.MediaList; diff --git a/src/css/rules/page.zig b/src/css/rules/page.zig index 267c49f8c5..fa840d67ed 100644 --- a/src/css/rules/page.zig +++ b/src/css/rules/page.zig @@ -1,6 +1,6 @@ const std = @import("std"); pub const css = @import("../css_parser.zig"); -const bun = @import("root").bun; +const bun = @import("bun"); const Result = css.Result; const ArrayList = std.ArrayListUnmanaged; const MediaList = css.MediaList; diff --git a/src/css/rules/property.zig b/src/css/rules/property.zig index 0e965f747d..b59a5cde2e 100644 --- a/src/css/rules/property.zig +++ b/src/css/rules/property.zig @@ -1,6 +1,6 @@ const std = @import("std"); pub const css = @import("../css_parser.zig"); -const bun = @import("root").bun; +const bun = @import("bun"); const Result = css.Result; const ArrayList = std.ArrayListUnmanaged; const MediaList = css.MediaList; diff --git a/src/css/rules/rules.zig b/src/css/rules/rules.zig index a775832064..f174b7967a 100644 --- a/src/css/rules/rules.zig +++ b/src/css/rules/rules.zig @@ -1,6 +1,6 @@ const std = @import("std"); pub const css = @import("../css_parser.zig"); -const bun = @import("root").bun; +const bun = @import("bun"); const Error = css.Error; const ArrayList = std.ArrayListUnmanaged; @@ -651,10 +651,10 @@ fn mergeStyleRules( { // If the new rule is unprefixed, replace the prefixes of the last rule. // Otherwise, add the new prefix. - if (sty.vendor_prefix.contains(css.VendorPrefix{ .none = true }) and context.targets.shouldCompileSelectors()) { + if (sty.vendor_prefix.none and context.targets.shouldCompileSelectors()) { last_style_rule.vendor_prefix = sty.vendor_prefix; } else { - last_style_rule.vendor_prefix.insert(sty.vendor_prefix); + bun.bits.insert(css.VendorPrefix, &last_style_rule.vendor_prefix, sty.vendor_prefix); } return true; } @@ -666,10 +666,10 @@ fn mergeStyleRules( sty.selectors.v.slice(), ); sty.selectors.v.clearRetainingCapacity(); - if (sty.vendor_prefix.contains(css.VendorPrefix{ .none = true }) and context.targets.shouldCompileSelectors()) { + if (sty.vendor_prefix.none and context.targets.shouldCompileSelectors()) { last_style_rule.vendor_prefix = sty.vendor_prefix; } else { - last_style_rule.vendor_prefix.insert(sty.vendor_prefix); + bun.bits.insert(css.VendorPrefix, &last_style_rule.vendor_prefix, sty.vendor_prefix); } return true; } diff --git a/src/css/rules/scope.zig b/src/css/rules/scope.zig index 51436f416a..05931344bc 100644 --- a/src/css/rules/scope.zig +++ b/src/css/rules/scope.zig @@ -1,6 +1,6 @@ const std = @import("std"); pub const css = @import("../css_parser.zig"); -const bun = @import("root").bun; +const bun = @import("bun"); const Error = css.Error; const ArrayList = std.ArrayListUnmanaged; const MediaList = css.MediaList; diff --git a/src/css/rules/starting_style.zig b/src/css/rules/starting_style.zig index f86a656931..9f0cd1d614 100644 --- a/src/css/rules/starting_style.zig +++ b/src/css/rules/starting_style.zig @@ -1,6 +1,6 @@ const std = @import("std"); pub const css = @import("../css_parser.zig"); -const bun = @import("root").bun; +const bun = @import("bun"); const Error = css.Error; const ArrayList = std.ArrayListUnmanaged; const MediaList = css.MediaList; diff --git a/src/css/rules/style.zig b/src/css/rules/style.zig index 618d808dbb..13cb4a3fec 100644 --- a/src/css/rules/style.zig +++ b/src/css/rules/style.zig @@ -1,6 +1,6 @@ const std = @import("std"); pub const css = @import("../css_parser.zig"); -const bun = @import("root").bun; +const bun = @import("bun"); const ArrayList = std.ArrayListUnmanaged; const MediaList = css.MediaList; const CustomMedia = css.CustomMedia; @@ -58,7 +58,7 @@ pub fn StyleRule(comptime R: type) type { pub fn updatePrefix(this: *This, context: *css.MinifyContext) void { this.vendor_prefix = css.selector.getPrefix(&this.selectors); - if (this.vendor_prefix.contains(css.VendorPrefix{ .none = true }) and + if (this.vendor_prefix.none and context.targets.shouldCompileSelectors()) { this.vendor_prefix = css.selector.downlevelSelectors(context.allocator, this.selectors.v.slice_mut(), context.targets.*); @@ -91,7 +91,7 @@ pub fn StyleRule(comptime R: type) type { } } - dest.vendor_prefix = css.VendorPrefix.empty(); + dest.vendor_prefix = .{}; } } diff --git a/src/css/rules/supports.zig b/src/css/rules/supports.zig index dd58eb2c35..81d2fdde0f 100644 --- a/src/css/rules/supports.zig +++ b/src/css/rules/supports.zig @@ -1,6 +1,6 @@ const std = @import("std"); pub const css = @import("../css_parser.zig"); -const bun = @import("root").bun; +const bun = @import("bun"); const Result = css.Result; const ArrayList = std.ArrayListUnmanaged; const MediaList = css.MediaList; @@ -343,7 +343,7 @@ pub const SupportsCondition = union(enum) { try dest.writeChar('('); const prefix: css.VendorPrefix = property_id.prefix().orNone(); - if (!prefix.eq(css.VendorPrefix{ .none = true })) { + if (prefix != css.VendorPrefix{ .none = true }) { try dest.writeChar('('); } @@ -365,7 +365,7 @@ pub const SupportsCondition = union(enum) { } } - if (!prefix.eq(css.VendorPrefix{ .none = true })) { + if (prefix != css.VendorPrefix{ .none = true }) { try dest.writeChar(')'); } try dest.writeChar(')'); diff --git a/src/css/rules/tailwind.zig b/src/css/rules/tailwind.zig index b3e15e3e1b..136f4b0c72 100644 --- a/src/css/rules/tailwind.zig +++ b/src/css/rules/tailwind.zig @@ -1,6 +1,6 @@ const std = @import("std"); const Allocator = std.mem.Allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const logger = bun.logger; const Log = logger.Log; diff --git a/src/css/rules/unknown.zig b/src/css/rules/unknown.zig index a1ab9408ff..74a551b257 100644 --- a/src/css/rules/unknown.zig +++ b/src/css/rules/unknown.zig @@ -1,6 +1,6 @@ const std = @import("std"); const Allocator = std.mem.Allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const logger = bun.logger; const Log = logger.Log; diff --git a/src/css/rules/viewport.zig b/src/css/rules/viewport.zig index 03f88aa8c5..c8e998d769 100644 --- a/src/css/rules/viewport.zig +++ b/src/css/rules/viewport.zig @@ -1,6 +1,6 @@ const std = @import("std"); pub const css = @import("../css_parser.zig"); -const bun = @import("root").bun; +const bun = @import("bun"); const Error = css.Error; const ArrayList = std.ArrayListUnmanaged; const MediaList = css.MediaList; diff --git a/src/css/selectors/builder.zig b/src/css/selectors/builder.zig index e07aef3eb7..cd6db25722 100644 --- a/src/css/selectors/builder.zig +++ b/src/css/selectors/builder.zig @@ -18,7 +18,7 @@ //! easy-to-use API for the parser. const std = @import("std"); const Allocator = std.mem.Allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const logger = bun.logger; const Log = logger.Log; @@ -39,8 +39,8 @@ const parser = css.selector.parser; const ValidSelectorImpl = parser.ValidSelectorImpl; const GenericComponent = parser.GenericComponent; const Combinator = parser.Combinator; -const SpecifityAndFlags = parser.SpecifityAndFlags; -const compute_specifity = parser.compute_specifity; +const SpecificityAndFlags = parser.SpecificityAndFlags; +const compute_specificity = parser.compute_specificity; const SelectorFlags = parser.SelectorFlags; /// Top-level SelectorBuilder struct. This should be stack-allocated by the @@ -77,7 +77,7 @@ pub fn SelectorBuilder(comptime Impl: type) type { const This = @This(); const BuildResult = struct { - specifity_and_flags: SpecifityAndFlags, + specificity_and_flags: SpecificityAndFlags, components: ArrayList(GenericComponent(Impl)), }; @@ -125,24 +125,18 @@ pub fn SelectorBuilder(comptime Impl: type) type { parsed_slotted: bool, parsed_part: bool, ) BuildResult { - const specifity = compute_specifity(Impl, this.simple_selectors.slice()); - var flags = SelectorFlags.empty(); - // PERF: is it faster to do these ORs all at once - if (parsed_pseudo) { - flags.has_pseudo = true; - } - if (parsed_slotted) { - flags.has_slotted = true; - } - if (parsed_part) { - flags.has_part = true; - } + const specificity = compute_specificity(Impl, this.simple_selectors.slice()); + const flags: SelectorFlags = .{ + .has_pseudo = parsed_pseudo, + .has_slotted = parsed_slotted, + .has_part = parsed_part, + }; // `buildWithSpecificityAndFlags()` will defer this.deinit(); - return this.buildWithSpecificityAndFlags(SpecifityAndFlags{ .specificity = specifity, .flags = flags }); + return this.buildWithSpecificityAndFlags(SpecificityAndFlags{ .specificity = specificity, .flags = flags }); } - /// Builds a selector with the given specifity and flags. + /// Builds a selector with the given specificity and flags. /// /// PERF: /// Recall that this code is ported from servo, which optimizes for matching speed, so @@ -153,7 +147,7 @@ pub fn SelectorBuilder(comptime Impl: type) type { /// order requires additional allocations, and undoing the reversal when serializing the /// selector. So we could just change this code to store the components in the same order /// as the source. - pub fn buildWithSpecificityAndFlags(this: *This, spec: SpecifityAndFlags) BuildResult { + pub fn buildWithSpecificityAndFlags(this: *This, spec: SpecificityAndFlags) BuildResult { const T = GenericComponent(Impl); const rest: []const T, const current: []const T = splitFromEnd(T, this.simple_selectors.slice(), this.current_len); const combinators = this.combinators.slice(); @@ -201,7 +195,7 @@ pub fn SelectorBuilder(comptime Impl: type) type { } } - return .{ .specifity_and_flags = spec, .components = components }; + return .{ .specificity_and_flags = spec, .components = components }; } pub fn splitFromEnd(comptime T: type, s: []const T, at: usize) struct { []const T, []const T } { diff --git a/src/css/selectors/parser.zig b/src/css/selectors/parser.zig index b23962d730..50a997b192 100644 --- a/src/css/selectors/parser.zig +++ b/src/css/selectors/parser.zig @@ -1,6 +1,6 @@ const std = @import("std"); const Allocator = std.mem.Allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const logger = bun.logger; const Log = logger.Log; @@ -218,81 +218,81 @@ pub const attrs = struct { }; }; -pub const Specifity = struct { +pub const Specificity = struct { id_selectors: u32 = 0, class_like_selectors: u32 = 0, element_selectors: u32 = 0, const MAX_10BIT: u32 = (1 << 10) - 1; - pub fn toU32(this: Specifity) u32 { + pub fn toU32(this: Specificity) u32 { return @as(u32, @as(u32, @min(this.id_selectors, MAX_10BIT)) << @as(u32, 20)) | @as(u32, @as(u32, @min(this.class_like_selectors, MAX_10BIT)) << @as(u32, 10)) | @min(this.element_selectors, MAX_10BIT); } - pub fn fromU32(value: u32) Specifity { + pub fn fromU32(value: u32) Specificity { bun.assert(value <= MAX_10BIT << 20 | MAX_10BIT << 10 | MAX_10BIT); - return Specifity{ + return Specificity{ .id_selectors = value >> 20, .class_like_selectors = (value >> 10) & MAX_10BIT, .element_selectors = value & MAX_10BIT, }; } - pub fn add(lhs: *Specifity, rhs: Specifity) void { + pub fn add(lhs: *Specificity, rhs: Specificity) void { lhs.id_selectors += rhs.id_selectors; lhs.element_selectors += rhs.element_selectors; lhs.class_like_selectors += rhs.class_like_selectors; } }; -pub fn compute_specifity(comptime Impl: type, iter: []const GenericComponent(Impl)) u32 { - const spec = compute_complex_selector_specifity(Impl, iter); +pub fn compute_specificity(comptime Impl: type, iter: []const GenericComponent(Impl)) u32 { + const spec = compute_complex_selector_specificity(Impl, iter); return spec.toU32(); } -fn compute_complex_selector_specifity(comptime Impl: type, iter: []const GenericComponent(Impl)) Specifity { - var specifity: Specifity = .{}; +fn compute_complex_selector_specificity(comptime Impl: type, iter: []const GenericComponent(Impl)) Specificity { + var specificity: Specificity = .{}; for (iter) |*simple_selector| { - compute_simple_selector_specifity(Impl, simple_selector, &specifity); + compute_simple_selector_specificity(Impl, simple_selector, &specificity); } - return specifity; + return specificity; } -fn compute_simple_selector_specifity( +fn compute_simple_selector_specificity( comptime Impl: type, simple_selector: *const GenericComponent(Impl), - specifity: *Specifity, + specificity: *Specificity, ) void { switch (simple_selector.*) { .combinator => { bun.unreachablePanic("Found combinator in simple selectors vector?", .{}); }, .part, .pseudo_element, .local_name => { - specifity.element_selectors += 1; + specificity.element_selectors += 1; }, .slotted => |selector| { - specifity.element_selectors += 1; + specificity.element_selectors += 1; // Note that due to the way ::slotted works we only compete with // other ::slotted rules, so the above rule doesn't really // matter, but we do it still for consistency with other // pseudo-elements. // // See: https://github.com/w3c/csswg-drafts/issues/1915 - specifity.add(Specifity.fromU32(selector.specifity())); + specificity.add(Specificity.fromU32(selector.specificity())); }, .host => |maybe_selector| { - specifity.class_like_selectors += 1; + specificity.class_like_selectors += 1; if (maybe_selector) |*selector| { // See: https://github.com/w3c/csswg-drafts/issues/1915 - specifity.add(Specifity.fromU32(selector.specifity())); + specificity.add(Specificity.fromU32(selector.specificity())); } }, .id => { - specifity.id_selectors += 1; + specificity.id_selectors += 1; }, .class, .attribute_in_no_namespace, @@ -304,7 +304,7 @@ fn compute_simple_selector_specifity( .nth, .non_ts_pseudo_class, => { - specifity.class_like_selectors += 1; + specificity.class_like_selectors += 1; }, .nth_of => |nth_of_data| { // https://drafts.csswg.org/selectors/#specificity-rules: @@ -313,12 +313,12 @@ fn compute_simple_selector_specifity( // like the :nth-child() pseudo-class, combines the // specificity of a regular pseudo-class with that of its // selector argument S. - specifity.class_like_selectors += 1; + specificity.class_like_selectors += 1; var max: u32 = 0; for (nth_of_data.selectors) |*selector| { - max = @max(selector.specifity(), max); + max = @max(selector.specificity(), max); } - specifity.add(Specifity.fromU32(max)); + specificity.add(Specificity.fromU32(max)); }, .negation, .is, .any => { // https://drafts.csswg.org/selectors/#specificity-rules: @@ -334,9 +334,9 @@ fn compute_simple_selector_specifity( }; var max: u32 = 0; for (list) |*selector| { - max = @max(selector.specifity(), max); + max = @max(selector.specificity(), max); } - specifity.add(Specifity.fromU32(max)); + specificity.add(Specificity.fromU32(max)); }, .where, .has, @@ -346,7 +346,7 @@ fn compute_simple_selector_specifity( .default_namespace, .namespace, => { - // Does not affect specifity + // Does not affect specificity }, .nesting => { // TODO @@ -395,7 +395,7 @@ fn parse_selector( return .{ .err = input.newCustomError(kind.intoDefaultParserError()) }; } - if (state.intersects(SelectorParsingState.AFTER_PSEUDO)) { + if (state.afterAnyPseudo()) { const source_location = input.currentSourceLocation(); if (input.next().asValue()) |next| { return .{ .err = source_location.newCustomError(SelectorParseErrorKind.intoDefaultParserError(.{ .unexpected_selector_after_pseudo_element = next.* })) }; @@ -478,7 +478,7 @@ fn parse_selector( builder.pushCombinator(combinator); } - if (!state.contains(SelectorParsingState{ .after_nesting = true })) { + if (!state.after_nesting) { switch (nesting_requirement) { .implicit => { builder.addNestingPrefix(); @@ -490,15 +490,12 @@ fn parse_selector( } } - const has_pseudo_element = state.intersects(SelectorParsingState{ - .after_pseudo_element = true, - .after_unknown_pseudo_element = true, - }); - const slotted = state.intersects(SelectorParsingState{ .after_slotted = true }); - const part = state.intersects(SelectorParsingState{ .after_part = true }); + const has_pseudo_element = state.after_pseudo_element or state.after_unknown_pseudo_element; + const slotted = state.after_slotted; + const part = state.after_part; const result = builder.build(has_pseudo_element, slotted, part); return .{ .result = Selector{ - .specifity_and_flags = result.specifity_and_flags, + .specificity_and_flags = result.specificity_and_flags, .components = result.components, } }; } @@ -520,7 +517,7 @@ fn parse_compound_selector( var empty: bool = true; if (parser.isNestingAllowed() and if (input.tryParse(css.Parser.expectDelim, .{'&'}).isOk()) true else false) { - state.insert(SelectorParsingState{ .after_nesting = true }); + state.after_nesting = true; builder.pushSimpleSelector(.nesting); empty = false; } @@ -570,7 +567,7 @@ fn parse_compound_selector( // // (Similar quotes for :where() / :not()) // - const ignore_default_ns = state.intersects(SelectorParsingState{ .skip_default_namespace = true }) or + const ignore_default_ns = state.skip_default_namespace or (result == .simple_selector and result.simple_selector == .host); if (!ignore_default_ns) { builder.pushSimpleSelector(.{ .default_namespace = url }); @@ -586,33 +583,33 @@ fn parse_compound_selector( }, .part_pseudo => { const selector = result.part_pseudo; - state.insert(SelectorParsingState{ .after_part = true }); + state.after_part = true; builder.pushCombinator(.part); builder.pushSimpleSelector(.{ .part = selector }); }, .slotted_pseudo => |selector| { - state.insert(.{ .after_slotted = true }); + state.after_slotted = true; builder.pushCombinator(.slot_assignment); builder.pushSimpleSelector(.{ .slotted = selector }); }, .pseudo_element => |p| { if (!p.isUnknown()) { - state.insert(SelectorParsingState{ .after_pseudo_element = true }); + state.after_pseudo_element = true; builder.pushCombinator(.pseudo_element); } else { - state.insert(.{ .after_unknown_pseudo_element = true }); + state.after_unknown_pseudo_element = true; } if (!p.acceptsStatePseudoClasses()) { - state.insert(.{ .after_non_stateful_pseudo_element = true }); + state.after_non_stateful_pseudo_element = true; } if (p.isWebkitScrollbar()) { - state.insert(.{ .after_webkit_scrollbar = true }); + state.after_webkit_scrollbar = true; } if (p.isViewTransition()) { - state.insert(.{ .after_view_transition = true }); + state.after_view_transition = true; } builder.pushSimpleSelector(.{ .pseudo_element = p }); @@ -947,7 +944,7 @@ pub const PseudoClass = union(enum) { pub fn getPrefix(this: *const PseudoClass) css.VendorPrefix { return switch (this.*) { inline .fullscreen, .any_link, .read_only, .read_write, .placeholder_shown, .autofill => |p| p, - else => css.VendorPrefix.empty(), + else => css.VendorPrefix{}, }; } @@ -960,7 +957,7 @@ pub const PseudoClass = union(enum) { .read_write => |*p| .{ p, F.pseudo_class_read_write }, .placeholder_shown => |*p| .{ p, F.pseudo_class_placeholder_shown }, .autofill => |*p| .{ p, F.pseudo_class_autofill }, - else => return css.VendorPrefix.empty(), + else => return css.VendorPrefix{}, }; p.* = targets.prefixes(p.*, feature); return p.*; @@ -1322,7 +1319,7 @@ pub const SelectorParser = struct { } pub fn deepCombinatorEnabled(this: *SelectorParser) bool { - return this.options.flags.contains(css.ParserFlags{ .deep_selector_combinator = true }); + return this.options.flags.deep_selector_combinator; } pub fn defaultNamespace(this: *SelectorParser) ?impl.Selectors.SelectorImpl.NamespaceUrl { @@ -1432,9 +1429,9 @@ pub fn GenericSelectorList(comptime Impl: type) type { if (this.v.len() == 0) return true; if (this.v.len() == 1) return true; - const value = this.v.at(0).specifity(); + const value = this.v.at(0).specificity(); for (this.v.slice()[1..]) |*sel| { - if (sel.specifity() != value) return false; + if (sel.specificity() != value) return false; } return true; } @@ -1459,7 +1456,7 @@ pub fn GenericSelectorList(comptime Impl: type) type { error_recovery: ParseErrorRecovery, nesting_requirement: NestingRequirement, ) Result(This) { - var state = SelectorParsingState.empty(); + var state = SelectorParsingState{}; return parseWithState(parser, input, &state, error_recovery, nesting_requirement); } @@ -1469,7 +1466,7 @@ pub fn GenericSelectorList(comptime Impl: type) type { error_recovery: ParseErrorRecovery, nesting_requirement: NestingRequirement, ) Result(This) { - var state = SelectorParsingState.empty(); + var state = SelectorParsingState{}; return parseRelativeWithState(parser, input, &state, error_recovery, nesting_requirement); } @@ -1631,7 +1628,7 @@ pub fn GenericSelector(comptime Impl: type) type { ValidSelectorImpl(Impl); return struct { - specifity_and_flags: SpecifityAndFlags, + specificity_and_flags: SpecificityAndFlags, components: ArrayList(GenericComponent(Impl)), const This = @This(); @@ -1665,7 +1662,7 @@ pub fn GenericSelector(comptime Impl: type) type { /// Parse a selector, without any pseudo-element. pub fn parse(parser: *SelectorParser, input: *css.Parser) Result(This) { - var state = SelectorParsingState.empty(); + var state = SelectorParsingState{}; return parse_selector(Impl, parser, input, &state, .none); } @@ -1704,7 +1701,7 @@ pub fn GenericSelector(comptime Impl: type) type { } pub fn hasPseudoElement(this: *const This) bool { - return this.specifity_and_flags.hasPseudoElement(); + return this.specificity_and_flags.hasPseudoElement(); } /// Returns count of simple selectors and combinators in the Selector. @@ -1721,13 +1718,13 @@ pub fn GenericSelector(comptime Impl: type) type { } const result = builder.build(false, false, false); return This{ - .specifity_and_flags = result.specifity_and_flags, + .specificity_and_flags = result.specificity_and_flags, .components = result.components, }; } - pub fn specifity(this: *const This) u32 { - return this.specifity_and_flags.specificity; + pub fn specificity(this: *const This) u32 { + return this.specificity_and_flags.specificity; } pub fn parseWithOptions(input: *css.Parser, options: *const css.ParserOptions) Result(This) { @@ -2123,55 +2120,52 @@ pub const SelectorParsingState = packed struct(u16) { __unused: u5 = 0, /// Whether we are after any of the pseudo-like things. - pub const AFTER_PSEUDO = SelectorParsingState{ .after_part = true, .after_slotted = true, .after_pseudo_element = true }; - - pub usingnamespace css.Bitflags(@This()); + pub fn afterAnyPseudo(state: SelectorParsingState) bool { + return state.after_part or state.after_slotted or state.after_pseudo_element; + } pub fn allowsPseudos(this: SelectorParsingState) bool { - return !this.intersects(SelectorParsingState{ - .after_pseudo_element = true, - .disallow_pseudos = true, - }); + return !this.after_pseudo_element and !this.disallow_pseudos; } pub fn allowsPart(this: SelectorParsingState) bool { - return !this.intersects(SelectorParsingState.AFTER_PSEUDO.bitwiseOr(SelectorParsingState{ .disallow_pseudos = true })); + return !this.disallow_pseudos and !this.afterAnyPseudo(); } pub fn allowsSlotted(this: SelectorParsingState) bool { - return !this.intersects(SelectorParsingState.AFTER_PSEUDO.bitwiseOr(.{ .disallow_pseudos = true })); + return this.allowsPart(); } pub fn allowsTreeStructuralPseudoClasses(this: SelectorParsingState) bool { - return !this.intersects(SelectorParsingState.AFTER_PSEUDO); + return !this.afterAnyPseudo(); } pub fn allowsNonFunctionalPseudoClasses(this: SelectorParsingState) bool { - return !this.intersects(SelectorParsingState{ .after_slotted = true, .after_non_stateful_pseudo_element = true }); + return !this.after_slotted and !this.after_non_stateful_pseudo_element; } pub fn allowsCombinators(this: SelectorParsingState) bool { - return !this.intersects(SelectorParsingState{ .disallow_combinators = true }); + return !this.disallow_combinators; } pub fn allowsCustomFunctionalPseudoClasses(this: SelectorParsingState) bool { - return !this.intersects(SelectorParsingState.AFTER_PSEUDO); + return !this.afterAnyPseudo(); } }; -pub const SpecifityAndFlags = struct { +pub const SpecificityAndFlags = struct { /// There are two free bits here, since we use ten bits for each specificity /// kind (id, class, element). specificity: u32, /// There's padding after this field due to the size of the flags. flags: SelectorFlags, - pub fn eql(this: *const SpecifityAndFlags, other: *const SpecifityAndFlags) bool { + pub fn eql(this: *const SpecificityAndFlags, other: *const SpecificityAndFlags) bool { return css.implementEql(@This(), this, other); } - pub fn hasPseudoElement(this: *const SpecifityAndFlags) bool { - return this.flags.intersects(SelectorFlags{ .has_pseudo = true }); + pub fn hasPseudoElement(this: *const SpecificityAndFlags) bool { + return this.flags.has_pseudo; } pub fn hash(this: *const @This(), hasher: *std.hash.Wyhash) void { @@ -2188,8 +2182,6 @@ pub const SelectorFlags = packed struct(u8) { has_slotted: bool = false, has_part: bool = false, __unused: u5 = 0, - - pub usingnamespace css.Bitflags(@This()); }; /// How to treat invalid selectors in a selector list. @@ -2465,7 +2457,7 @@ pub const PseudoElement = union(enum) { .placeholder => |*p| .{ p, F.pseudo_element_placeholder }, .backdrop => |*p| .{ p, F.pseudo_element_backdrop }, .file_selector_button => |*p| .{ p, F.pseudo_element_file_selector_button }, - else => return css.VendorPrefix.empty(), + else => return css.VendorPrefix{}, }; p.* = targets.prefixes(p.*, feature); @@ -2476,7 +2468,7 @@ pub const PseudoElement = union(enum) { pub fn getPrefix(this: *const PseudoElement) css.VendorPrefix { return switch (this.*) { .selection, .placeholder, .backdrop, .file_selector_button => |p| p, - else => css.VendorPrefix.empty(), + else => css.VendorPrefix{}, }; } @@ -2585,7 +2577,7 @@ pub fn parse_type_selector( const namespace: QNamePrefix(Impl) = result.some[0]; const local_name: ?[]const u8 = result.some[1]; - if (state.intersects(SelectorParsingState.AFTER_PSEUDO)) { + if (state.afterAnyPseudo()) { return .{ .err = input.newCustomError(SelectorParseErrorKind.intoDefaultParserError(.invalid_state)) }; } @@ -2678,7 +2670,7 @@ pub fn parse_one_simple_selector( switch (token) { .idhash => |id| { - if (state.intersects(SelectorParsingState.AFTER_PSEUDO)) { + if (state.afterAnyPseudo()) { return .{ .err = token_location.newCustomError(SelectorParseErrorKind.intoDefaultParserError(.{ .unexpected_selector_after_pseudo_element = .{ .idhash = id } })) }; } const component: GenericComponent(Impl) = .{ .id = parser.newLocalIdentifier(input, .ID, id, token_loc) }; @@ -2687,7 +2679,7 @@ pub fn parse_one_simple_selector( } }; }, .open_square => { - if (state.intersects(SelectorParsingState.AFTER_PSEUDO)) { + if (state.afterAnyPseudo()) { return .{ .err = token_location.newCustomError(SelectorParseErrorKind.intoDefaultParserError(.{ .unexpected_selector_after_pseudo_element = .open_square })) }; } const Closure = struct { @@ -2823,7 +2815,7 @@ pub fn parse_one_simple_selector( }; }; - if (state.intersects(.{ .after_slotted = true }) and pseudo_element.validAfterSlotted()) { + if (state.after_slotted and pseudo_element.validAfterSlotted()) { return .{ .result = .{ .pseudo_element = pseudo_element } }; } @@ -2858,7 +2850,7 @@ pub fn parse_one_simple_selector( .delim => |d| { switch (d) { '.' => { - if (state.intersects(SelectorParsingState.AFTER_PSEUDO)) { + if (state.afterAnyPseudo()) { return .{ .err = token_location.newCustomError(SelectorParseErrorKind.intoDefaultParserError(.{ .unexpected_selector_after_pseudo_element = .{ .delim = '.' } })) }; } const location = input.currentSourceLocation(); @@ -2876,7 +2868,7 @@ pub fn parse_one_simple_selector( }, '&' => { if (parser.isNestingAllowed()) { - state.insert(SelectorParsingState{ .after_nesting = true }); + state.after_nesting = true; return .{ .result = S{ .simple_selector = .nesting, } }; @@ -3181,7 +3173,7 @@ pub fn parse_simple_pseudo_class( // The view-transition pseudo elements accept the :only-child pseudo class. // https://w3c.github.io/csswg-drafts/css-view-transitions-1/#pseudo-root - if (state.intersects(SelectorParsingState{ .after_view_transition = true })) { + if (state.after_view_transition) { if (bun.strings.eqlCaseInsensitiveASCIIICheckLength(name, "only-child")) { return .{ .result = .{ .nth = NthSelectorData.only(false) } }; } @@ -3191,11 +3183,11 @@ pub fn parse_simple_pseudo_class( .err => |e| return .{ .err = e }, .result => |v| v, }; - if (state.intersects(SelectorParsingState{ .after_webkit_scrollbar = true })) { + if (state.after_webkit_scrollbar) { if (!pseudo_class.isValidAfterWebkitScrollbar()) { return .{ .err = location.newCustomError(SelectorParseErrorKind.intoDefaultParserError(.invalid_pseudo_class_after_webkit_scrollbar)) }; } - } else if (state.intersects(SelectorParsingState{ .after_pseudo_element = true })) { + } else if (state.after_pseudo_element) { if (!pseudo_class.isUserActionState()) { return .{ .err = location.newCustomError(SelectorParseErrorKind.intoDefaultParserError(.invalid_pseudo_class_after_pseudo_element)) }; } diff --git a/src/css/selectors/selector.zig b/src/css/selectors/selector.zig index c7d2cee998..a04b616131 100644 --- a/src/css/selectors/selector.zig +++ b/src/css/selectors/selector.zig @@ -1,8 +1,9 @@ const std = @import("std"); const Allocator = std.mem.Allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const logger = bun.logger; const Log = logger.Log; +const bits = bun.bits; pub const css = @import("../css_parser.zig"); const CSSString = css.CSSString; @@ -102,10 +103,10 @@ pub fn isEquivalent(selectors: []const Selector, other: []const Selector) bool { /// Downlevels the given selectors to be compatible with the given browser targets. /// Returns the necessary vendor prefixes. pub fn downlevelSelectors(allocator: Allocator, selectors: []Selector, targets: css.targets.Targets) css.VendorPrefix { - var necessary_prefixes = css.VendorPrefix.empty(); + var necessary_prefixes = css.VendorPrefix{}; for (selectors) |*selector| { for (selector.components.items) |*component| { - necessary_prefixes.insert(downlevelComponent(allocator, component, targets)); + bun.bits.insert(css.VendorPrefix, &necessary_prefixes, downlevelComponent(allocator, component, targets)); } } return necessary_prefixes; @@ -120,7 +121,7 @@ pub fn downlevelComponent(allocator: Allocator, component: *Component, targets: component.* = downlevelDir(allocator, d.direction, targets); return downlevelComponent(allocator, component, targets); } - return css.VendorPrefix.empty(); + return css.VendorPrefix{}; }, .lang => |l| { // :lang() with multiple languages is not supported everywhere. @@ -129,7 +130,7 @@ pub fn downlevelComponent(allocator: Allocator, component: *Component, targets: component.* = .{ .is = langListToSelectors(allocator, l.languages.items) }; return downlevelComponent(allocator, component, targets); } - return css.VendorPrefix.empty(); + return css.VendorPrefix{}; }, else => pc.getNecessaryPrefixes(targets), }; @@ -147,9 +148,9 @@ pub fn downlevelComponent(allocator: Allocator, component: *Component, targets: } break :brk true; }) { - necessary_prefixes.insert(targets.prefixes(css.VendorPrefix{ .none = true }, .any_pseudo)); + bun.bits.insert(css.VendorPrefix, &necessary_prefixes, targets.prefixes(css.VendorPrefix{ .none = true }, .any_pseudo)); } else { - necessary_prefixes.insert(css.VendorPrefix{ .none = true }); + necessary_prefixes.none = true; } return necessary_prefixes; @@ -173,9 +174,9 @@ pub fn downlevelComponent(allocator: Allocator, component: *Component, targets: component.* = .{ .negation = list.items }; if (targets.shouldCompileSame(.is_selector)) { - necessary_prefixes.insert(targets.prefixes(css.VendorPrefix{ .none = true }, .any_pseudo)); + bun.bits.insert(css.VendorPrefix, &necessary_prefixes, targets.prefixes(css.VendorPrefix{ .none = true }, .any_pseudo)); } else { - necessary_prefixes.insert(css.VendorPrefix{ .none = true }); + bun.bits.insert(css.VendorPrefix, &necessary_prefixes, css.VendorPrefix{ .none = true }); } } @@ -183,7 +184,7 @@ pub fn downlevelComponent(allocator: Allocator, component: *Component, targets: }, .where, .has => |s| downlevelSelectors(allocator, s, targets), .any => |*a| downlevelSelectors(allocator, a.selectors, targets), - else => css.VendorPrefix.empty(), + else => css.VendorPrefix{}, }; } @@ -238,7 +239,7 @@ fn langListToSelectors(allocator: Allocator, langs: []const []const u8) []Select /// Returns the vendor prefix (if any) used in the given selector list. /// If multiple vendor prefixes are seen, this is invalid, and an empty result is returned. pub fn getPrefix(selectors: *const SelectorList) css.VendorPrefix { - var prefix = css.VendorPrefix.empty(); + var prefix = css.VendorPrefix{}; for (selectors.v.slice()) |*selector| { for (selector.components.items) |*component_| { const component: *const Component = component_; @@ -255,16 +256,17 @@ pub fn getPrefix(selectors: *const SelectorList) css.VendorPrefix { .negation => css.VendorPrefix{ .none = true }, .any => |*any| any.vendor_prefix, .pseudo_element => |*pe| pe.getPrefix(), - else => css.VendorPrefix.empty(), + else => css.VendorPrefix{}, }; if (!p.isEmpty()) { // Allow none to be mixed with a prefix. - const prefix_without_none = prefix.maskOut(css.VendorPrefix{ .none = true }); - if (prefix_without_none.isEmpty() or prefix_without_none.eql(p)) { - prefix.insert(p); + var prefix_without_none = prefix; + prefix_without_none.none = false; + if (prefix_without_none.isEmpty() or prefix_without_none == p) { + bun.bits.insert(css.VendorPrefix, &prefix, p); } else { - return css.VendorPrefix.empty(); + return css.VendorPrefix{}; } } } @@ -351,12 +353,12 @@ pub fn isCompatible(selectors: []const parser.Selector, targets: css.targets.Tar .checked, .disabled, .enabled, .target => break :brk F.selectors3, .any_link => |prefix| { - if (prefix.eql(css.VendorPrefix{ .none = true })) break :brk F.any_link; + if (prefix == css.VendorPrefix{ .none = true }) break :brk F.any_link; }, .indeterminate => break :brk F.indeterminate_pseudo, .fullscreen => |prefix| { - if (prefix.eql(css.VendorPrefix{ .none = true })) break :brk F.fullscreen; + if (prefix == css.VendorPrefix{ .none = true }) break :brk F.fullscreen; }, .focus_visible => break :brk F.focus_visible, @@ -365,18 +367,18 @@ pub fn isCompatible(selectors: []const parser.Selector, targets: css.targets.Tar .dir => break :brk F.dir_selector, .optional => break :brk F.optional_pseudo, .placeholder_shown => |prefix| { - if (prefix.eql(css.VendorPrefix{ .none = true })) break :brk F.placeholder_shown; + if (prefix == css.VendorPrefix{ .none = true }) break :brk F.placeholder_shown; }, inline .read_only, .read_write => |prefix| { - if (prefix.eql(css.VendorPrefix{ .none = true })) break :brk F.read_only_write; + if (prefix == css.VendorPrefix{ .none = true }) break :brk F.read_only_write; }, .valid, .invalid, .required => break :brk F.form_validation, .in_range, .out_of_range => break :brk F.in_out_of_range, .autofill => |prefix| { - if (prefix.eql(css.VendorPrefix{ .none = true })) break :brk F.autofill; + if (prefix == css.VendorPrefix{ .none = true }) break :brk F.autofill; }, // Experimental, no browser support. @@ -411,14 +413,14 @@ pub fn isCompatible(selectors: []const parser.Selector, targets: css.targets.Tar .first_line => break :brk F.first_line, .first_letter => break :brk F.first_letter, .selection => |prefix| { - if (prefix.eql(css.VendorPrefix{ .none = true })) break :brk F.selection; + if (prefix == css.VendorPrefix{ .none = true }) break :brk F.selection; }, .placeholder => |prefix| { - if (prefix.eql(css.VendorPrefix{ .none = true })) break :brk F.placeholder; + if (prefix == css.VendorPrefix{ .none = true }) break :brk F.placeholder; }, .marker => break :brk F.marker_pseudo, .backdrop => |prefix| { - if (prefix.eql(css.VendorPrefix{ .none = true })) break :brk F.dialog; + if (prefix == css.VendorPrefix{ .none = true }) break :brk F.dialog; }, .cue => break :brk F.cue, .cue_function => break :brk F.cue_function, @@ -577,7 +579,7 @@ pub const serialize = struct { // which is a universal selector, append the result of // serializing the universal selector to s. // - // Check if `!compound.empty()` first--this can happen if we have + // Check if `!compound{}` first--this can happen if we have // something like `... > ::before`, because we store `>` and `::` // both as combinators internally. // @@ -747,7 +749,7 @@ pub const serialize = struct { } const vp = dest.vendor_prefix; - if (vp.intersects(css.VendorPrefix{ .webkit = true, .moz = true })) { + if (vp.webkit or vp.moz) { try dest.writeChar(':'); try vp.toCss(W, dest); try dest.writeStr("any("); @@ -760,7 +762,7 @@ pub const serialize = struct { }, .any => |v| { const vp = dest.vendor_prefix._or(v.vendor_prefix); - if (vp.intersects(css.VendorPrefix{ .webkit = true, .moz = true })) { + if (vp.webkit or vp.moz) { try dest.writeChar(':'); try vp.toCss(W, dest); try dest.writeStr("any("); @@ -885,7 +887,7 @@ pub const serialize = struct { try d.writeChar(':'); // If the printer has a vendor prefix override, use that. const vp = if (!d.vendor_prefix.isEmpty()) - d.vendor_prefix.bitwiseOr(prefix).orNone() + bun.bits.@"or"(css.VendorPrefix, d.vendor_prefix, prefix).orNone() else prefix; @@ -942,7 +944,7 @@ pub const serialize = struct { .fullscreen => |prefix| { try dest.writeChar(':'); const vp = if (!dest.vendor_prefix.isEmpty()) - dest.vendor_prefix.bitwiseAnd(prefix).orNone() + bits.@"and"(css.VendorPrefix, dest.vendor_prefix, prefix).orNone() else prefix; try vp.toCss(W, dest); @@ -1048,7 +1050,10 @@ pub const serialize = struct { pub fn writePrefix(d: *Printer(W), prefix: css.VendorPrefix) PrintErr!css.VendorPrefix { try d.writeStr("::"); // If the printer has a vendor prefix override, use that. - const vp = if (!d.vendor_prefix.isEmpty()) d.vendor_prefix.bitwiseAnd(prefix).orNone() else prefix; + const vp = if (!d.vendor_prefix.isEmpty()) + bits.@"and"(css.VendorPrefix, d.vendor_prefix, prefix).orNone() + else + prefix; try vp.toCss(W, d); debug("VENDOR PREFIX {d} OVERRIDE {d}", .{ vp.asBits(), d.vendor_prefix.asBits() }); return vp; @@ -1246,7 +1251,7 @@ pub const tocss_servo = struct { // which is a universal selector, append the result of // serializing the universal selector to s. // - // Check if `!compound.empty()` first--this can happen if we have + // Check if `!compound{}` first--this can happen if we have // something like `... > ::before`, because we store `>` and `::` // both as combinators internally. // diff --git a/src/css/small_list.zig b/src/css/small_list.zig index 22b78ebe2e..a2925ea166 100644 --- a/src/css/small_list.zig +++ b/src/css/small_list.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const css = @import("./css_parser.zig"); const Printer = css.Printer; const Parser = css.Parser; @@ -213,16 +213,16 @@ pub fn SmallList(comptime T: type, comptime N: comptime_int) type { if (@hasDecl(T, "getImage") and N == 1) { const ColorFallbackKind = css.css_values.color.ColorFallbackKind; // Determine what vendor prefixes and color fallbacks are needed. - var prefixes = css.VendorPrefix.empty(); - var fallbacks = ColorFallbackKind.empty(); + var prefixes = css.VendorPrefix{}; + var fallbacks = ColorFallbackKind{}; var res: bun.BabyList(@This()) = .{}; for (this.slice()) |*item| { - prefixes.insert(item.getImage().getNecessaryPrefixes(targets)); - fallbacks.insert(item.getNecessaryFallbacks(targets)); + bun.bits.insert(css.VendorPrefix, &prefixes, item.getImage().getNecessaryPrefixes(targets)); + bun.bits.insert(css.ColorFallbackKind, &fallbacks, item.getNecessaryFallbacks(targets)); } // Get RGB fallbacks if needed. - const rgb: ?SmallList(T, 1) = if (fallbacks.contains(ColorFallbackKind{ .rgb = true })) brk: { + const rgb: ?SmallList(T, 1) = if (fallbacks.rgb) brk: { var shallow_clone = this.shallowClone(allocator); for (shallow_clone.slice_mut(), this.slice_mut()) |*out, *in| { out.* = in.getFallback(allocator, ColorFallbackKind{ .rgb = true }); @@ -234,7 +234,7 @@ pub fn SmallList(comptime T: type, comptime N: comptime_int) type { const prefix_images: *const SmallList(T, 1) = if (rgb) |*r| r else this; // Legacy -webkit-gradient() - if (prefixes.contains(css.VendorPrefix{ .webkit = true }) and targets.browsers != null and css.prefixes.Feature.isWebkitGradient(targets.browsers.?)) { + if (prefixes.webkit and targets.browsers != null and css.prefixes.Feature.isWebkitGradient(targets.browsers.?)) { const images = images: { var images = SmallList(T, 1){}; for (prefix_images.slice()) |*item| { @@ -251,7 +251,7 @@ pub fn SmallList(comptime T: type, comptime N: comptime_int) type { const prefix = struct { pub inline fn helper(comptime prefix: []const u8, pfs: *css.VendorPrefix, pfi: *const SmallList(T, 1), r: *bun.BabyList(This), alloc: Allocator) void { - if (pfs.contains(css.VendorPrefix.fromName(prefix))) { + if (bun.bits.contains(css.VendorPrefix, pfs.*, .fromName(prefix))) { var images = SmallList(T, 1).initCapacity(alloc, pfi.len()); images.setLen(pfi.len()); for (images.slice_mut(), pfi.slice()) |*out, *in| { @@ -267,12 +267,12 @@ pub fn SmallList(comptime T: type, comptime N: comptime_int) type { prefix("moz", &prefixes, prefix_images, &res, allocator); prefix("o", &prefixes, prefix_images, &res, allocator); - if (prefixes.contains(css.VendorPrefix{ .none = true })) { + if (prefixes.none) { if (rgb) |r| { res.push(allocator, r) catch bun.outOfMemory(); } - if (fallbacks.contains(ColorFallbackKind{ .p3 = true })) { + if (fallbacks.p3) { var p3_images = this.shallowClone(allocator); for (p3_images.slice_mut(), this.slice_mut()) |*out, *in| { out.* = in.getFallback(allocator, ColorFallbackKind{ .p3 = true }); @@ -280,7 +280,7 @@ pub fn SmallList(comptime T: type, comptime N: comptime_int) type { } // Convert to lab if needed (e.g. if oklab is not supported but lab is). - if (fallbacks.contains(ColorFallbackKind{ .lab = true })) { + if (fallbacks.lab) { for (this.slice_mut()) |*item| { var old = item.*; item.* = item.getFallback(allocator, ColorFallbackKind{ .lab = true }); @@ -298,13 +298,13 @@ pub fn SmallList(comptime T: type, comptime N: comptime_int) type { return res; } if (T == TextShadow and N == 1) { - var fallbacks = css.ColorFallbackKind.empty(); + var fallbacks = css.ColorFallbackKind{}; for (this.slice()) |*shadow| { - fallbacks.insert(shadow.color.getNecessaryFallbacks(targets)); + bun.bits.insert(css.ColorFallbackKind, &fallbacks, shadow.color.getNecessaryFallbacks(targets)); } var res = SmallList(SmallList(TextShadow, 1), 2){}; - if (fallbacks.contains(css.ColorFallbackKind{ .rgb = true })) { + if (fallbacks.rgb) { var rgb = SmallList(TextShadow, 1).initCapacity(allocator, this.len()); for (this.slice()) |*shadow| { var new_shadow = shadow.*; @@ -317,7 +317,7 @@ pub fn SmallList(comptime T: type, comptime N: comptime_int) type { res.append(allocator, rgb); } - if (fallbacks.contains(css.ColorFallbackKind{ .p3 = true })) { + if (fallbacks.p3) { var p3 = SmallList(TextShadow, 1).initCapacity(allocator, this.len()); for (this.slice()) |*shadow| { var new_shadow = shadow.*; @@ -330,7 +330,7 @@ pub fn SmallList(comptime T: type, comptime N: comptime_int) type { res.append(allocator, p3); } - if (fallbacks.contains(css.ColorFallbackKind{ .lab = true })) { + if (fallbacks.lab) { for (this.slice_mut()) |*shadow| { const out = shadow.color.toLAB(allocator).?; shadow.color.deinit(allocator); diff --git a/src/css/sourcemap.zig b/src/css/sourcemap.zig index 57f5cab30f..96984c52f7 100644 --- a/src/css/sourcemap.zig +++ b/src/css/sourcemap.zig @@ -1,6 +1,6 @@ const std = @import("std"); const Allocator = std.mem.Allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const logger = bun.logger; const Log = logger.Log; diff --git a/src/css/targets.zig b/src/css/targets.zig index 97c2dda099..9e168f2486 100644 --- a/src/css/targets.zig +++ b/src/css/targets.zig @@ -1,8 +1,9 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Allocator = std.mem.Allocator; pub const css = @import("./css_parser.zig"); +const bits = bun.bits; const Printer = css.Printer; const PrintErr = css.PrintErr; @@ -90,9 +91,9 @@ pub const Targets = struct { } pub fn prefixes(this: *const Targets, prefix: css.VendorPrefix, feature: css.prefixes.Feature) css.VendorPrefix { - if (prefix.contains(css.VendorPrefix{ .none = true }) and !this.exclude.contains(css.targets.Features{ .vendor_prefixes = true })) { - if (this.include.contains(css.targets.Features{ .vendor_prefixes = true })) { - return css.VendorPrefix.all(); + if (prefix.none and !this.exclude.vendor_prefixes) { + if (this.include.vendor_prefixes) { + return .all; } else { return if (this.browsers) |b| feature.prefixesFor(b) else prefix; } @@ -106,7 +107,8 @@ pub const Targets = struct { } pub fn shouldCompile(this: *const Targets, feature: css.compat.Feature, flag: Features) bool { - return this.include.contains(flag) or (!this.exclude.contains(flag) and !this.isCompatible(feature)); + return bits.contains(Features, this.include, flag) or + (!bits.contains(Features, this.exclude, flag) and !this.isCompatible(feature)); } pub fn shouldCompileSame(this: *const Targets, comptime compat_feature: css.compat.Feature) bool { @@ -120,8 +122,8 @@ pub const Targets = struct { } pub fn shouldCompileSelectors(this: *const Targets) bool { - return this.include.intersects(Features.selectors) or - (!this.exclude.intersects(Features.selectors) and this.browsers != null); + return bun.bits.intersects(Features, this.include, Features.selectors) or + (!bun.bits.intersects(Features, this.exclude, Features.selectors) and this.browsers != null); } pub fn isCompatible(this: *const Targets, feature: css.compat.Feature) bool { @@ -132,8 +134,6 @@ pub const Targets = struct { } }; -/// Autogenerated by build-prefixes.js -/// /// Browser versions to compile CSS for. /// /// Versions are represented as a single 24-bit integer, with one byte @@ -159,7 +159,148 @@ pub const Browsers = struct { opera: ?u32 = null, safari: ?u32 = null, samsung: ?u32 = null, - pub usingnamespace BrowsersImpl(@This()); + + pub const browserDefault = convertFromString(&.{ + "es2020", // support import.meta.url + "edge88", + "firefox78", + "chrome87", + "safari14", + }) catch unreachable; + + /// Ported from here: + /// https://github.com/vitejs/vite/blob/ac329685bba229e1ff43e3d96324f817d48abe48/packages/vite/src/node/plugins/css.ts#L3335 + pub fn convertFromString(esbuild_target: []const []const u8) anyerror!Browsers { + var browsers: Browsers = .{}; + + for (esbuild_target) |str| { + var entries_buf: [5][]const u8 = undefined; + const entries_without_es: [][]const u8 = entries_without_es: { + if (str.len <= 2 or !(str[0] == 'e' and str[1] == 's')) { + entries_buf[0] = str; + break :entries_without_es entries_buf[0..1]; + } + + const number_part = str[2..]; + const year = try std.fmt.parseInt(u16, number_part, 10); + switch (year) { + // https://caniuse.com/?search=es2015 + 2015 => { + entries_buf[0..5].* = .{ "chrome49", "edge13", "safari10", "firefox44", "opera36" }; + break :entries_without_es entries_buf[0..5]; + }, + // https://caniuse.com/?search=es2016 + 2016 => { + entries_buf[0..5].* = .{ "chrome50", "edge13", "safari10", "firefox43", "opera37" }; + break :entries_without_es entries_buf[0..5]; + }, + // https://caniuse.com/?search=es2017 + 2017 => { + entries_buf[0..5].* = .{ "chrome58", "edge15", "safari11", "firefox52", "opera45" }; + break :entries_without_es entries_buf[0..5]; + }, + // https://caniuse.com/?search=es2018 + 2018 => { + entries_buf[0..5].* = .{ "chrome63", "edge79", "safari12", "firefox58", "opera50" }; + break :entries_without_es entries_buf[0..5]; + }, + // https://caniuse.com/?search=es2019 + 2019 => { + entries_buf[0..5].* = .{ "chrome73", "edge79", "safari12.1", "firefox64", "opera60" }; + break :entries_without_es entries_buf[0..5]; + }, + // https://caniuse.com/?search=es2020 + 2020 => { + entries_buf[0..5].* = .{ "chrome80", "edge80", "safari14.1", "firefox80", "opera67" }; + break :entries_without_es entries_buf[0..5]; + }, + // https://caniuse.com/?search=es2021 + 2021 => { + entries_buf[0..5].* = .{ "chrome85", "edge85", "safari14.1", "firefox80", "opera71" }; + break :entries_without_es entries_buf[0..5]; + }, + // https://caniuse.com/?search=es2022 + 2022 => { + entries_buf[0..5].* = .{ "chrome94", "edge94", "safari16.4", "firefox93", "opera80" }; + break :entries_without_es entries_buf[0..5]; + }, + // https://caniuse.com/?search=es2023 + 2023 => { + entries_buf[0..4].* = .{ "chrome110", "edge110", "safari16.4", "opera96" }; + break :entries_without_es entries_buf[0..4]; + }, + else => { + if (@inComptime()) { + @compileLog("Invalid target: " ++ str); + } + return error.UnsupportedCSSTarget; + }, + } + }; + + for_loop: for (entries_without_es) |entry| { + if (bun.strings.eql(entry, "esnext")) continue; + const maybe_idx: ?usize = maybe_idx: { + for (entry, 0..) |c, i| { + if (std.ascii.isDigit(c)) break :maybe_idx i; + } + break :maybe_idx null; + }; + + if (maybe_idx) |idx| { + const Browser = enum { + chrome, + edge, + firefox, + ie, + ios_saf, + opera, + safari, + no_mapping, + }; + const Map = bun.ComptimeStringMap(Browser, .{ + .{ "chrome", Browser.chrome }, + .{ "edge", Browser.edge }, + .{ "firefox", Browser.firefox }, + .{ "hermes", Browser.no_mapping }, + .{ "ie", Browser.ie }, + .{ "ios", Browser.ios_saf }, + .{ "node", Browser.no_mapping }, + .{ "opera", Browser.opera }, + .{ "rhino", Browser.no_mapping }, + .{ "safari", Browser.safari }, + }); + const browser = Map.get(entry[0..idx]); + if (browser == null or browser.? == .no_mapping) continue; // No mapping available + + const major, const minor = major_minor: { + const version_str = entry[idx..]; + const dot_index = std.mem.indexOfScalar(u8, version_str, '.') orelse version_str.len; + const major = std.fmt.parseInt(u16, version_str[0..dot_index], 10) catch continue; + const minor = if (dot_index < version_str.len) + std.fmt.parseInt(u16, version_str[dot_index + 1 ..], 10) catch 0 + else + 0; + break :major_minor .{ major, minor }; + }; + + const version: u32 = (@as(u32, major) << 16) | @as(u32, minor << 8); + switch (browser.?) { + inline else => |browser_name| { + if (@field(browsers, @tagName(browser_name)) == null or + version < @field(browsers, @tagName(browser_name)).?) + { + @field(browsers, @tagName(browser_name)) = version; + } + continue :for_loop; + }, + } + } + } + } + + return browsers; + } }; /// Autogenerated by build-prefixes.js @@ -186,169 +327,25 @@ pub const Features = packed struct(u32) { vendor_prefixes: bool = false, logical_properties: bool = false, __unused: u12 = 0, - pub const selectors = Features.fromNames(&.{ "nesting", "not_selector_list", "dir_selector", "lang_selector_list", "is_selector" }); - pub const media_queries = Features.fromNames(&.{ "media_interval_syntax", "media_range_syntax", "custom_media_queries" }); - pub const colors = Features.fromNames(&.{ "color_function", "oklab_colors", "lab_colors", "p3_colors", "hex_alpha_colors", "space_separated_color_notation" }); - pub usingnamespace css.Bitflags(@This()); - pub usingnamespace FeaturesImpl(@This()); -}; - -pub fn BrowsersImpl(comptime T: type) type { - return struct { - pub const browserDefault = convertFromString(&.{ - "es2020", // support import.meta.url - "edge88", - "firefox78", - "chrome87", - "safari14", - }) catch |e| std.debug.panic("WOOPSIE: {s}\n", .{@errorName(e)}); - - // pub const bundlerDefault = T{ - // .chrome = 80 << 16, - // .edge = 80 << 16, - // .firefox = 78 << 16, - // .safari = 14 << 16, - // .opera = 67 << 16, - // }; - - /// Ported from here: - /// https://github.com/vitejs/vite/blob/ac329685bba229e1ff43e3d96324f817d48abe48/packages/vite/src/node/plugins/css.ts#L3335 - pub fn convertFromString(esbuild_target: []const []const u8) anyerror!T { - var browsers: T = .{}; - - for (esbuild_target) |str| { - var entries_buf: [5][]const u8 = undefined; - const entries_without_es: [][]const u8 = entries_without_es: { - if (str.len <= 2 or !(str[0] == 'e' and str[1] == 's')) { - entries_buf[0] = str; - break :entries_without_es entries_buf[0..1]; - } - - const number_part = str[2..]; - const year = try std.fmt.parseInt(u16, number_part, 10); - switch (year) { - // https://caniuse.com/?search=es2015 - 2015 => { - entries_buf[0..5].* = .{ "chrome49", "edge13", "safari10", "firefox44", "opera36" }; - break :entries_without_es entries_buf[0..5]; - }, - // https://caniuse.com/?search=es2016 - 2016 => { - entries_buf[0..5].* = .{ "chrome50", "edge13", "safari10", "firefox43", "opera37" }; - break :entries_without_es entries_buf[0..5]; - }, - // https://caniuse.com/?search=es2017 - 2017 => { - entries_buf[0..5].* = .{ "chrome58", "edge15", "safari11", "firefox52", "opera45" }; - break :entries_without_es entries_buf[0..5]; - }, - // https://caniuse.com/?search=es2018 - 2018 => { - entries_buf[0..5].* = .{ "chrome63", "edge79", "safari12", "firefox58", "opera50" }; - break :entries_without_es entries_buf[0..5]; - }, - // https://caniuse.com/?search=es2019 - 2019 => { - entries_buf[0..5].* = .{ "chrome73", "edge79", "safari12.1", "firefox64", "opera60" }; - break :entries_without_es entries_buf[0..5]; - }, - // https://caniuse.com/?search=es2020 - 2020 => { - entries_buf[0..5].* = .{ "chrome80", "edge80", "safari14.1", "firefox80", "opera67" }; - break :entries_without_es entries_buf[0..5]; - }, - // https://caniuse.com/?search=es2021 - 2021 => { - entries_buf[0..5].* = .{ "chrome85", "edge85", "safari14.1", "firefox80", "opera71" }; - break :entries_without_es entries_buf[0..5]; - }, - // https://caniuse.com/?search=es2022 - 2022 => { - entries_buf[0..5].* = .{ "chrome94", "edge94", "safari16.4", "firefox93", "opera80" }; - break :entries_without_es entries_buf[0..5]; - }, - // https://caniuse.com/?search=es2023 - 2023 => { - entries_buf[0..4].* = .{ "chrome110", "edge110", "safari16.4", "opera96" }; - break :entries_without_es entries_buf[0..4]; - }, - else => { - if (@inComptime()) { - @compileLog("Invalid target: " ++ str); - } - return error.UnsupportedCSSTarget; - }, - } - }; - - for_loop: for (entries_without_es) |entry| { - if (bun.strings.eql(entry, "esnext")) continue; - const maybe_idx: ?usize = maybe_idx: { - for (entry, 0..) |c, i| { - if (std.ascii.isDigit(c)) break :maybe_idx i; - } - break :maybe_idx null; - }; - - if (maybe_idx) |idx| { - const Browser = enum { - chrome, - edge, - firefox, - ie, - ios_saf, - opera, - safari, - no_mapping, - }; - const Map = bun.ComptimeStringMap(Browser, .{ - .{ "chrome", Browser.chrome }, - .{ "edge", Browser.edge }, - .{ "firefox", Browser.firefox }, - .{ "hermes", Browser.no_mapping }, - .{ "ie", Browser.ie }, - .{ "ios", Browser.ios_saf }, - .{ "node", Browser.no_mapping }, - .{ "opera", Browser.opera }, - .{ "rhino", Browser.no_mapping }, - .{ "safari", Browser.safari }, - }); - const browser = Map.get(entry[0..idx]); - if (browser == null or browser.? == .no_mapping) continue; // No mapping available - - const major, const minor = major_minor: { - const version_str = entry[idx..]; - const dot_index = std.mem.indexOfScalar(u8, version_str, '.') orelse version_str.len; - const major = std.fmt.parseInt(u16, version_str[0..dot_index], 10) catch continue; - const minor = if (dot_index < version_str.len) - std.fmt.parseInt(u16, version_str[dot_index + 1 ..], 10) catch 0 - else - 0; - break :major_minor .{ major, minor }; - }; - - const version: u32 = (@as(u32, major) << 16) | @as(u32, minor << 8); - switch (browser.?) { - inline else => |browser_name| { - if (@field(browsers, @tagName(browser_name)) == null or - version < @field(browsers, @tagName(browser_name)).?) - { - @field(browsers, @tagName(browser_name)) = version; - } - continue :for_loop; - }, - } - } - } - } - - return browsers; - } + pub const selectors: @This() = .{ + .nesting = true, + .not_selector_list = true, + .dir_selector = true, + .lang_selector_list = true, + .is_selector = true, }; -} - -pub fn FeaturesImpl(comptime T: type) type { - _ = T; // autofix - return struct {}; -} + pub const media_queries: @This() = .{ + .media_interval_syntax = true, + .media_range_syntax = true, + .custom_media_queries = true, + }; + pub const colors: @This() = .{ + .color_function = true, + .oklab_colors = true, + .lab_colors = true, + .p3_colors = true, + .hex_alpha_colors = true, + .space_separated_color_notation = true, + }; +}; diff --git a/src/css/values/alpha.zig b/src/css/values/alpha.zig index 531e718b52..275fd2dac4 100644 --- a/src/css/values/alpha.zig +++ b/src/css/values/alpha.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); pub const css = @import("../css_parser.zig"); const Result = css.Result; const ArrayList = std.ArrayListUnmanaged; diff --git a/src/css/values/angle.zig b/src/css/values/angle.zig index 4649960715..3c9c3257be 100644 --- a/src/css/values/angle.zig +++ b/src/css/values/angle.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); pub const css = @import("../css_parser.zig"); const Result = css.Result; const ArrayList = std.ArrayListUnmanaged; diff --git a/src/css/values/calc.zig b/src/css/values/calc.zig index 4c992c75d1..1e17b69d26 100644 --- a/src/css/values/calc.zig +++ b/src/css/values/calc.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Allocator = std.mem.Allocator; pub const css = @import("../css_parser.zig"); const Result = css.Result; diff --git a/src/css/values/color.zig b/src/css/values/color.zig index 31331bd72a..6936e02c42 100644 --- a/src/css/values/color.zig +++ b/src/css/values/color.zig @@ -1,8 +1,9 @@ const std = @import("std"); const Allocator = std.mem.Allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const logger = bun.logger; const Log = logger.Log; +const bits = bun.bits; pub const css = @import("../css_parser.zig"); pub const Result = css.Result; @@ -497,15 +498,15 @@ pub const CssColor = union(enum) { var res = css.SmallList(CssColor, 2){}; - if (fallbacks.contains(ColorFallbackKind{ .rgb = true })) { + if (fallbacks.rgb) { res.appendAssumeCapacity(this.toRGB(allocator).?); } - if (fallbacks.contains(ColorFallbackKind{ .p3 = true })) { + if (fallbacks.p3) { res.appendAssumeCapacity(this.toP3(allocator).?); } - if (fallbacks.contains(ColorFallbackKind{ .lab = true })) { + if (fallbacks.lab) { const foo = this.toLAB(allocator).?; this.* = foo; } @@ -526,49 +527,49 @@ pub const CssColor = union(enum) { // below and including the authored color space, and remove the ones that aren't // compatible with our browser targets. var fallbacks = switch (this.*) { - .current_color, .rgba, .float, .system => return ColorFallbackKind.empty(), + .current_color, .rgba, .float, .system => return ColorFallbackKind{}, .lab => |lab| brk: { if (lab.* == .lab or lab.* == .lch and targets.shouldCompileSame(.lab_colors)) break :brk ColorFallbackKind.andBelow(.{ .lab = true }); if (lab.* == .oklab or lab.* == .oklch and targets.shouldCompileSame(.oklab_colors)) break :brk ColorFallbackKind.andBelow(.{ .oklab = true }); - return ColorFallbackKind.empty(); + return ColorFallbackKind{}; }, .predefined => |predefined| brk: { if (predefined.* == .display_p3 and targets.shouldCompileSame(.p3_colors)) break :brk ColorFallbackKind.andBelow(.{ .p3 = true }); if (targets.shouldCompileSame(.color_function)) break :brk ColorFallbackKind.andBelow(.{ .lab = true }); - return ColorFallbackKind.empty(); + return ColorFallbackKind{}; }, .light_dark => |*ld| { - return ld.light.getPossibleFallbacks(targets).bitwiseOr(ld.dark.getPossibleFallbacks(targets)); + return bun.bits.@"or"(ColorFallbackKind, ld.light.getPossibleFallbacks(targets), ld.dark.getPossibleFallbacks(targets)); }, }; - if (fallbacks.contains(.{ .oklab = true })) { + if (fallbacks.oklab) { if (!targets.shouldCompileSame(.oklab_colors)) { - fallbacks.remove(ColorFallbackKind.andBelow(.{ .lab = true })); + fallbacks = fallbacks.difference(ColorFallbackKind.andBelow(.{ .lab = true })); } } - if (fallbacks.contains(.{ .lab = true })) { + if (fallbacks.lab) { if (!targets.shouldCompileSame(.lab_colors)) { fallbacks = fallbacks.difference(ColorFallbackKind.andBelow(.{ .p3 = true })); } else if (targets.browsers != null and css.compat.Feature.isPartiallyCompatible(&css.compat.Feature.lab_colors, targets.browsers.?)) { // We don't need P3 if Lab is supported by some of our targets. // No browser implements Lab but not P3. - fallbacks.remove(.{ .p3 = true }); + fallbacks.p3 = false; } } - if (fallbacks.contains(.{ .p3 = true })) { + if (fallbacks.p3) { if (!targets.shouldCompileSame(.p3_colors)) { - fallbacks.remove(.{ .rgb = true }); - } else if (fallbacks.highest().asBits() != ColorFallbackKind.asBits(.{ .p3 = true }) and + fallbacks.rgb = false; + } else if (fallbacks.highest() != ColorFallbackKind.P3 and (targets.browsers == null or !css.compat.Feature.isPartiallyCompatible(&css.compat.Feature.p3_colors, targets.browsers.?))) { // Remove P3 if it isn't supported by any targets, and wasn't the // original authored color. - fallbacks.remove(.{ .p3 = true }); + fallbacks.p3 = false; } } @@ -673,7 +674,7 @@ pub fn parseColorFunction(location: css.SourceLocation, function: []const u8, in fn callback(allocator: Allocator, h: f32, s: f32, l: f32, a: f32) CssColor { const hsl = HSL{ .h = h, .s = s, .l = l, .alpha = a }; if (!std.math.isNan(h) and !std.math.isNan(s) and !std.math.isNan(l) and !std.math.isNan(a)) { - return CssColor{ .rgba = hsl.intoRGBA() }; + return CssColor{ .rgba = hsl.into(.RGBA) }; } else { return CssColor{ .float = bun.create(allocator, FloatColor, .{ .hsl = hsl }) }; } @@ -683,7 +684,7 @@ pub fn parseColorFunction(location: css.SourceLocation, function: []const u8, in fn callback(allocator: Allocator, h: f32, w: f32, b: f32, a: f32) CssColor { const hwb = HWB{ .h = h, .w = w, .b = b, .alpha = a }; if (!std.math.isNan(h) and !std.math.isNan(w) and !std.math.isNan(b) and !std.math.isNan(a)) { - return CssColor{ .rgba = hwb.intoRGBA() }; + return CssColor{ .rgba = hwb.into(.RGBA) }; } else { return CssColor{ .float = bun.create(allocator, FloatColor, .{ .hwb = hwb }) }; } @@ -818,12 +819,12 @@ pub fn parseHSLHWBComponents(comptime T: type, input: *css.Parser, parser: *Comp } pub fn mapGamut(comptime T: type, color: T) T { - const conversion_function_name = "into" ++ comptime bun.meta.typeName(T); + const conversion_target = comptime ConvertTo.fromType(T); const JND: f32 = 0.02; const EPSILON: f32 = 0.00001; // https://www.w3.org/TR/css-color-4/#binsearch - var current: OKLCH = color.intoOKLCH(); + var current: OKLCH = color.into(.OKLCH); // If lightness is >= 100%, return pure white. if (@abs(current.l - 1.0) < EPSILON or current.l > 1.0) { @@ -833,7 +834,7 @@ pub fn mapGamut(comptime T: type, color: T) T { .h = 0.0, .alpha = current.alpha, }; - return @call(.auto, @field(OKLCH, conversion_function_name), .{&oklch}); + return oklch.into(conversion_target); } // If lightness <= 0%, return pure black. @@ -844,7 +845,7 @@ pub fn mapGamut(comptime T: type, color: T) T { .h = 0.0, .alpha = current.alpha, }; - return @call(.auto, @field(OKLCH, conversion_function_name), .{&oklch}); + return oklch.into(conversion_target); } var min: f32 = 0.0; @@ -854,7 +855,7 @@ pub fn mapGamut(comptime T: type, color: T) T { const chroma = (min + max) / 2.0; current.c = chroma; - const converted = @call(.auto, @field(OKLCH, conversion_function_name), .{¤t}); + const converted = current.into(conversion_target); if (converted.inGamut()) { min = chroma; continue; @@ -869,13 +870,13 @@ pub fn mapGamut(comptime T: type, color: T) T { max = chroma; } - return @call(.auto, @field(OKLCH, conversion_function_name), .{¤t}); + return current.into(conversion_target); } pub fn deltaEok(comptime T: type, _a: T, _b: OKLCH) f32 { // https://www.w3.org/TR/css-color-4/#color-difference-OK - const a = T.intoOKLAB(&_a); - const b: OKLAB = _b.intoOKLAB(); + const a: OKLAB = _a.into(.OKLAB); + const b: OKLAB = _b.into(.OKLAB); const delta_l = a.l - b.l; const delta_a = a.a - b.a; @@ -1337,8 +1338,15 @@ pub const RGBA = struct { /// The alpha component. alpha: u8, - pub usingnamespace ColorspaceConversions(@This()); - pub usingnamespace color_conversions.convert_RGBA; + /// Convert the color into another color format. + pub const into = ColorIntoMixin(@This(), .RGBA).into; + + const conversions_impl = ColorspaceConversions(@This()); + pub const fromLABColor = conversions_impl.fromLABColor; + pub const fromPredefinedColor = conversions_impl.fromPredefinedColor; + pub const fromFloatColor = conversions_impl.fromFloatColor; + pub const tryFromCssColor = conversions_impl.tryFromCssColor; + pub const hash = conversions_impl.hash; pub fn new(red: u8, green: u8, blue: u8, alpha: f32) RGBA { return RGBA{ @@ -1620,15 +1628,33 @@ pub const LAB = struct { /// The alpha component. alpha: f32, - pub usingnamespace DefineColorspace(@This(), ChannelTypeMap); - pub usingnamespace ColorspaceConversions(@This()); - pub usingnamespace UnboundedColorGamut(@This()); + const colorspace_impl = DefineColorspace(@This(), ChannelTypeMap); + pub const components = colorspace_impl.components; + pub const types = colorspace_impl.types; + pub const channels = colorspace_impl.channels; + pub const resolveMissing = colorspace_impl.resolveMissing; + pub const resolve = colorspace_impl.resolve; + const conversions_impl = ColorspaceConversions(@This()); + pub const fromLABColor = conversions_impl.fromLABColor; + pub const fromPredefinedColor = conversions_impl.fromPredefinedColor; + pub const fromFloatColor = conversions_impl.fromFloatColor; + pub const tryFromCssColor = conversions_impl.tryFromCssColor; + pub const hash = conversions_impl.hash; + const gamut_impl = UnboundedColorGamut(@This()); + pub const clip = gamut_impl.clip; + pub const inGamut = gamut_impl.inGamut; - pub usingnamespace AdjustPowerlessLAB(@This()); - pub usingnamespace DeriveInterpolate(@This(), "l", "a", "b"); - pub usingnamespace RecangularPremultiply(@This(), "l", "a", "b"); + pub const adjustPowerlessComponents = AdjustPowerlessLAB(@This()).adjustPowerlessComponents; + const interpolate_impl = DeriveInterpolate(@This(), "l", "a", "b"); + pub const fillMissingComponents = interpolate_impl.fillMissingComponents; + pub const interpolate = interpolate_impl.interpolate; + const recangular_impl = RecangularPremultiply(@This(), "l", "a", "b"); + pub const premultiply = recangular_impl.premultiply; + pub const unpremultiply = recangular_impl.unpremultiply; - pub usingnamespace color_conversions.convert_LAB; + /// Convert this color into another color format. + pub const into = ColorIntoMixin(@This(), .LAB).into; + pub const intoCssColor = ImplementIntoCssColor(@This(), .LAB); pub const ChannelTypeMap = .{ .l = ChannelType{ .percentage = true }, @@ -1650,14 +1676,32 @@ pub const SRGB = struct { /// The alpha component. alpha: f32, - pub usingnamespace DefineColorspace(@This(), ChannelTypeMap); - pub usingnamespace ColorspaceConversions(@This()); - pub usingnamespace BoundedColorGamut(@This()); + const colorspace_impl = DefineColorspace(@This(), ChannelTypeMap); + pub const components = colorspace_impl.components; + pub const channels = colorspace_impl.channels; + pub const types = colorspace_impl.types; + pub const resolveMissing = colorspace_impl.resolveMissing; + pub const resolve = colorspace_impl.resolve; + const conversions_impl = ColorspaceConversions(@This()); + pub const fromLABColor = conversions_impl.fromLABColor; + pub const fromPredefinedColor = conversions_impl.fromPredefinedColor; + pub const fromFloatColor = conversions_impl.fromFloatColor; + pub const tryFromCssColor = conversions_impl.tryFromCssColor; + pub const hash = conversions_impl.hash; + const gamut_impl = BoundedColorGamut(@This()); + pub const clip = gamut_impl.clip; + pub const inGamut = gamut_impl.inGamut; - pub usingnamespace DeriveInterpolate(@This(), "r", "g", "b"); - pub usingnamespace RecangularPremultiply(@This(), "r", "g", "b"); + const interpolate_impl = DeriveInterpolate(@This(), "r", "g", "b"); + pub const fillMissingComponents = interpolate_impl.fillMissingComponents; + pub const interpolate = interpolate_impl.interpolate; + const recangular_impl = RecangularPremultiply(@This(), "r", "g", "b"); + pub const premultiply = recangular_impl.premultiply; + pub const unpremultiply = recangular_impl.unpremultiply; - pub usingnamespace color_conversions.convert_SRGB; + /// Convert this color into another color format. + pub const into = ColorIntoMixin(@This(), .SRGB).into; + pub const intoCssColor = ImplementIntoCssColor(@This(), .SRGB); pub const ChannelTypeMap = .{ .r = ChannelType{ .percentage = true }, @@ -1690,14 +1734,32 @@ pub const HSL = struct { /// The alpha component. alpha: f32, - pub usingnamespace DefineColorspace(@This(), ChannelTypeMap); - pub usingnamespace ColorspaceConversions(@This()); - pub usingnamespace HslHwbColorGamut(@This(), "s", "l"); + const colorspace_impl = DefineColorspace(@This(), ChannelTypeMap); + pub const components = colorspace_impl.components; + pub const channels = colorspace_impl.channels; + pub const types = colorspace_impl.types; + pub const resolveMissing = colorspace_impl.resolveMissing; + pub const resolve = colorspace_impl.resolve; + const conversions_impl = ColorspaceConversions(@This()); + pub const fromLABColor = conversions_impl.fromLABColor; + pub const fromPredefinedColor = conversions_impl.fromPredefinedColor; + pub const fromFloatColor = conversions_impl.fromFloatColor; + pub const tryFromCssColor = conversions_impl.tryFromCssColor; + pub const hash = conversions_impl.hash; + const gamut_impl = HslHwbColorGamut(@This(), "s", "l"); + pub const clip = gamut_impl.clip; + pub const inGamut = gamut_impl.inGamut; - pub usingnamespace PolarPremultiply(@This(), "s", "l"); - pub usingnamespace DeriveInterpolate(@This(), "h", "s", "l"); + const polar_impl = PolarPremultiply(@This(), "s", "l"); + pub const premultiply = polar_impl.premultiply; + pub const unpremultiply = polar_impl.unpremultiply; + const interpolate_impl = DeriveInterpolate(@This(), "h", "s", "l"); + pub const fillMissingComponents = interpolate_impl.fillMissingComponents; + pub const interpolate = interpolate_impl.interpolate; - pub usingnamespace color_conversions.convert_HSL; + /// Convert this color into another color format. + pub const into = ColorIntoMixin(@This(), .HSL).into; + pub const intoCssColor = ImplementIntoCssColor(@This(), .HSL); pub const ChannelTypeMap = .{ .h = ChannelType{ .angle = true }, @@ -1734,14 +1796,32 @@ pub const HWB = struct { /// The alpha component. alpha: f32, - pub usingnamespace DefineColorspace(@This(), ChannelTypeMap); - pub usingnamespace ColorspaceConversions(@This()); - pub usingnamespace HslHwbColorGamut(@This(), "w", "b"); + const colorspace_impl = DefineColorspace(@This(), ChannelTypeMap); + pub const components = colorspace_impl.components; + pub const channels = colorspace_impl.channels; + pub const types = colorspace_impl.types; + pub const resolveMissing = colorspace_impl.resolveMissing; + pub const resolve = colorspace_impl.resolve; + const conversions_impl = ColorspaceConversions(@This()); + pub const fromLABColor = conversions_impl.fromLABColor; + pub const fromPredefinedColor = conversions_impl.fromPredefinedColor; + pub const fromFloatColor = conversions_impl.fromFloatColor; + pub const tryFromCssColor = conversions_impl.tryFromCssColor; + pub const hash = conversions_impl.hash; + const gamut_impl = HslHwbColorGamut(@This(), "w", "b"); + pub const inGamut = gamut_impl.inGamut; + pub const clip = gamut_impl.clip; - pub usingnamespace PolarPremultiply(@This(), "w", "b"); - pub usingnamespace DeriveInterpolate(@This(), "h", "w", "b"); + const polar_impl = PolarPremultiply(@This(), "w", "b"); + pub const premultiply = polar_impl.premultiply; + pub const unpremultiply = polar_impl.unpremultiply; + const interpolate_impl = DeriveInterpolate(@This(), "h", "w", "b"); + pub const fillMissingComponents = interpolate_impl.fillMissingComponents; + pub const interpolate = interpolate_impl.interpolate; - pub usingnamespace color_conversions.convert_HWB; + /// Convert this color into another color format. + pub const into = ColorIntoMixin(@This(), .HWB).into; + pub const intoCssColor = ImplementIntoCssColor(@This(), .HWB); pub const ChannelTypeMap = .{ .h = ChannelType{ .angle = true }, @@ -1773,14 +1853,32 @@ pub const SRGBLinear = struct { /// The alpha component. alpha: f32, - pub usingnamespace DefineColorspace(@This(), ChannelTypeMap); - pub usingnamespace ColorspaceConversions(@This()); - pub usingnamespace BoundedColorGamut(@This()); + const colorspace_impl = DefineColorspace(@This(), ChannelTypeMap); + pub const components = colorspace_impl.components; + pub const channels = colorspace_impl.channels; + pub const types = colorspace_impl.types; + pub const resolveMissing = colorspace_impl.resolveMissing; + pub const resolve = colorspace_impl.resolve; + const conversions_impl = ColorspaceConversions(@This()); + pub const fromLABColor = conversions_impl.fromLABColor; + pub const fromPredefinedColor = conversions_impl.fromPredefinedColor; + pub const fromFloatColor = conversions_impl.fromFloatColor; + pub const tryFromCssColor = conversions_impl.tryFromCssColor; + pub const hash = conversions_impl.hash; + const gamut_impl = BoundedColorGamut(@This()); + pub const clip = gamut_impl.clip; + pub const inGamut = gamut_impl.inGamut; - pub usingnamespace DeriveInterpolate(@This(), "r", "g", "b"); - pub usingnamespace RecangularPremultiply(@This(), "r", "g", "b"); + const interpolate_impl = DeriveInterpolate(@This(), "r", "g", "b"); + pub const fillMissingComponents = interpolate_impl.fillMissingComponents; + pub const interpolate = interpolate_impl.interpolate; + const recangular_impl = RecangularPremultiply(@This(), "r", "g", "b"); + pub const premultiply = recangular_impl.premultiply; + pub const unpremultiply = recangular_impl.unpremultiply; - pub usingnamespace color_conversions.convert_SRGBLinear; + /// Convert this color into another color format. + pub const into = ColorIntoMixin(@This(), .SRGBLinear).into; + pub const intoCssColor = ImplementIntoCssColor(@This(), .SRGBLinear); pub const ChannelTypeMap = .{ .r = ChannelType{ .angle = true }, @@ -1803,11 +1901,25 @@ pub const P3 = struct { /// The alpha component. alpha: f32, - pub usingnamespace DefineColorspace(@This(), ChannelTypeMap); - pub usingnamespace ColorspaceConversions(@This()); - pub usingnamespace BoundedColorGamut(@This()); + const colorspace_impl = DefineColorspace(@This(), ChannelTypeMap); + pub const components = colorspace_impl.components; + pub const channels = colorspace_impl.channels; + pub const types = colorspace_impl.types; + pub const resolveMissing = colorspace_impl.resolveMissing; + pub const resolve = colorspace_impl.resolve; + const conversions_impl = ColorspaceConversions(@This()); + pub const fromLABColor = conversions_impl.fromLABColor; + pub const fromPredefinedColor = conversions_impl.fromPredefinedColor; + pub const fromFloatColor = conversions_impl.fromFloatColor; + pub const tryFromCssColor = conversions_impl.tryFromCssColor; + pub const hash = conversions_impl.hash; + const gamut_impl = BoundedColorGamut(@This()); + pub const clip = gamut_impl.clip; + pub const inGamut = gamut_impl.inGamut; - pub usingnamespace color_conversions.convert_P3; + /// Convert this color into another color format. + pub const into = ColorIntoMixin(@This(), .P3).into; + pub const intoCssColor = ImplementIntoCssColor(@This(), .P3); pub const ChannelTypeMap = .{ .r = ChannelType{ .percentage = true }, @@ -1827,11 +1939,25 @@ pub const A98 = struct { /// The alpha component. alpha: f32, - pub usingnamespace DefineColorspace(@This(), ChannelTypeMap); - pub usingnamespace ColorspaceConversions(@This()); - pub usingnamespace BoundedColorGamut(@This()); + const colorspace_impl = DefineColorspace(@This(), ChannelTypeMap); + pub const components = colorspace_impl.components; + pub const channels = colorspace_impl.channels; + pub const types = colorspace_impl.types; + pub const resolveMissing = colorspace_impl.resolveMissing; + pub const resolve = colorspace_impl.resolve; + const conversions_impl = ColorspaceConversions(@This()); + pub const fromLABColor = conversions_impl.fromLABColor; + pub const fromPredefinedColor = conversions_impl.fromPredefinedColor; + pub const fromFloatColor = conversions_impl.fromFloatColor; + pub const tryFromCssColor = conversions_impl.tryFromCssColor; + pub const hash = conversions_impl.hash; + const gamut_impl = BoundedColorGamut(@This()); + pub const clip = gamut_impl.clip; + pub const inGamut = gamut_impl.inGamut; - pub usingnamespace color_conversions.convert_A98; + /// Convert this color into another color format. + pub const into = ColorIntoMixin(@This(), .A98).into; + pub const intoCssColor = ImplementIntoCssColor(@This(), .A98); pub const ChannelTypeMap = .{ .r = ChannelType{ .percentage = true }, @@ -1851,11 +1977,25 @@ pub const ProPhoto = struct { /// The alpha component. alpha: f32, - pub usingnamespace DefineColorspace(@This(), ChannelTypeMap); - pub usingnamespace ColorspaceConversions(@This()); - pub usingnamespace BoundedColorGamut(@This()); + const colorspace_impl = DefineColorspace(@This(), ChannelTypeMap); + pub const components = colorspace_impl.components; + pub const channels = colorspace_impl.channels; + pub const types = colorspace_impl.types; + pub const resolveMissing = colorspace_impl.resolveMissing; + pub const resolve = colorspace_impl.resolve; + const conversions_impl = ColorspaceConversions(@This()); + pub const fromLABColor = conversions_impl.fromLABColor; + pub const fromPredefinedColor = conversions_impl.fromPredefinedColor; + pub const fromFloatColor = conversions_impl.fromFloatColor; + pub const tryFromCssColor = conversions_impl.tryFromCssColor; + pub const hash = conversions_impl.hash; + const gamut_impl = BoundedColorGamut(@This()); + pub const clip = gamut_impl.clip; + pub const inGamut = gamut_impl.inGamut; - pub usingnamespace color_conversions.convert_ProPhoto; + /// Convert this color into another color format. + pub const into = ColorIntoMixin(@This(), .ProPhoto).into; + pub const intoCssColor = ImplementIntoCssColor(@This(), .ProPhoto); pub const ChannelTypeMap = .{ .r = ChannelType{ .percentage = true }, @@ -1875,11 +2015,25 @@ pub const Rec2020 = struct { /// The alpha component. alpha: f32, - pub usingnamespace DefineColorspace(@This(), ChannelTypeMap); - pub usingnamespace ColorspaceConversions(@This()); - pub usingnamespace BoundedColorGamut(@This()); + const colorspace_impl = DefineColorspace(@This(), ChannelTypeMap); + pub const components = colorspace_impl.components; + pub const channels = colorspace_impl.channels; + pub const types = colorspace_impl.types; + pub const resolveMissing = colorspace_impl.resolveMissing; + pub const resolve = colorspace_impl.resolve; + const conversions_impl = ColorspaceConversions(@This()); + pub const fromLABColor = conversions_impl.fromLABColor; + pub const fromPredefinedColor = conversions_impl.fromPredefinedColor; + pub const fromFloatColor = conversions_impl.fromFloatColor; + pub const tryFromCssColor = conversions_impl.tryFromCssColor; + pub const hash = conversions_impl.hash; + const gamut_impl = BoundedColorGamut(@This()); + pub const clip = gamut_impl.clip; + pub const inGamut = gamut_impl.inGamut; - pub usingnamespace color_conversions.convert_Rec2020; + /// Convert this color into another color format. + pub const into = ColorIntoMixin(@This(), .Rec2020).into; + pub const intoCssColor = ImplementIntoCssColor(@This(), .Rec2020); pub const ChannelTypeMap = .{ .r = ChannelType{ .percentage = true }, @@ -1899,14 +2053,32 @@ pub const XYZd50 = struct { /// The alpha component. alpha: f32, - pub usingnamespace DefineColorspace(@This(), ChannelTypeMap); - pub usingnamespace ColorspaceConversions(@This()); - pub usingnamespace UnboundedColorGamut(@This()); + const colorspace_impl = DefineColorspace(@This(), ChannelTypeMap); + pub const components = colorspace_impl.components; + pub const channels = colorspace_impl.channels; + pub const types = colorspace_impl.types; + pub const resolveMissing = colorspace_impl.resolveMissing; + pub const resolve = colorspace_impl.resolve; + const conversions_impl = ColorspaceConversions(@This()); + pub const fromLABColor = conversions_impl.fromLABColor; + pub const fromPredefinedColor = conversions_impl.fromPredefinedColor; + pub const fromFloatColor = conversions_impl.fromFloatColor; + pub const tryFromCssColor = conversions_impl.tryFromCssColor; + pub const hash = conversions_impl.hash; + const gamut_impl = UnboundedColorGamut(@This()); + pub const clip = gamut_impl.clip; + pub const inGamut = gamut_impl.inGamut; - pub usingnamespace DeriveInterpolate(@This(), "x", "y", "z"); - pub usingnamespace RecangularPremultiply(@This(), "x", "y", "z"); + const interpolate_impl = DeriveInterpolate(@This(), "x", "y", "z"); + pub const fillMissingComponents = interpolate_impl.fillMissingComponents; + pub const interpolate = interpolate_impl.interpolate; + const recangular_impl = RecangularPremultiply(@This(), "x", "y", "z"); + pub const premultiply = recangular_impl.premultiply; + pub const unpremultiply = recangular_impl.unpremultiply; - pub usingnamespace color_conversions.convert_XYZd50; + /// Convert this color into another color format. + pub const into = ColorIntoMixin(@This(), .XYZd50).into; + pub const intoCssColor = ImplementIntoCssColor(@This(), .XYZd50); pub const ChannelTypeMap = .{ .x = ChannelType{ .percentage = true }, @@ -1926,14 +2098,32 @@ pub const XYZd65 = struct { /// The alpha component. alpha: f32, - pub usingnamespace DefineColorspace(@This(), ChannelTypeMap); - pub usingnamespace ColorspaceConversions(@This()); - pub usingnamespace UnboundedColorGamut(@This()); + const colorspace_impl = DefineColorspace(@This(), ChannelTypeMap); + pub const components = colorspace_impl.components; + pub const channels = colorspace_impl.channels; + pub const types = colorspace_impl.types; + pub const resolveMissing = colorspace_impl.resolveMissing; + pub const resolve = colorspace_impl.resolve; + const conversions_impl = ColorspaceConversions(@This()); + pub const fromLABColor = conversions_impl.fromLABColor; + pub const fromPredefinedColor = conversions_impl.fromPredefinedColor; + pub const fromFloatColor = conversions_impl.fromFloatColor; + pub const tryFromCssColor = conversions_impl.tryFromCssColor; + pub const hash = conversions_impl.hash; + const gamut_impl = UnboundedColorGamut(@This()); + pub const clip = gamut_impl.clip; + pub const inGamut = gamut_impl.inGamut; - pub usingnamespace DeriveInterpolate(@This(), "x", "y", "z"); - pub usingnamespace RecangularPremultiply(@This(), "x", "y", "z"); + const interpolate_impl = DeriveInterpolate(@This(), "x", "y", "z"); + pub const fillMissingComponents = interpolate_impl.fillMissingComponents; + pub const interpolate = interpolate_impl.interpolate; + const recangular_impl = RecangularPremultiply(@This(), "x", "y", "z"); + pub const premultiply = recangular_impl.premultiply; + pub const unpremultiply = recangular_impl.unpremultiply; - pub usingnamespace color_conversions.convert_XYZd65; + /// Convert this color into another color format. + pub const into = ColorIntoMixin(@This(), .XYZd65).into; + pub const intoCssColor = ImplementIntoCssColor(@This(), .XYZd65); pub const ChannelTypeMap = .{ .x = ChannelType{ .percentage = true }, @@ -1956,15 +2146,35 @@ pub const LCH = struct { /// The alpha component. alpha: f32, - pub usingnamespace DefineColorspace(@This(), ChannelTypeMap); - pub usingnamespace ColorspaceConversions(@This()); - pub usingnamespace UnboundedColorGamut(@This()); + const colorspace_impl = DefineColorspace(@This(), ChannelTypeMap); + pub const components = colorspace_impl.components; + pub const channels = colorspace_impl.channels; + pub const types = colorspace_impl.types; + pub const resolveMissing = colorspace_impl.resolveMissing; + pub const resolve = colorspace_impl.resolve; + const conversions_impl = ColorspaceConversions(@This()); + pub const fromLABColor = conversions_impl.fromLABColor; + pub const fromPredefinedColor = conversions_impl.fromPredefinedColor; + pub const fromFloatColor = conversions_impl.fromFloatColor; + pub const tryFromCssColor = conversions_impl.tryFromCssColor; + pub const hash = conversions_impl.hash; + const gamut_impl = UnboundedColorGamut(@This()); + pub const clip = gamut_impl.clip; + pub const inGamut = gamut_impl.inGamut; - pub usingnamespace AdjustPowerlessLCH(@This()); - pub usingnamespace DeriveInterpolate(@This(), "l", "c", "h"); - pub usingnamespace RecangularPremultiply(@This(), "l", "c", "h"); + const powerless_lch_impl = AdjustPowerlessLCH(@This()); + pub const adjustPowerlessComponents = powerless_lch_impl.adjustPowerlessComponents; + pub const adjustHue = powerless_lch_impl.adjustHue; + const interpolate_impl = DeriveInterpolate(@This(), "l", "c", "h"); + pub const fillMissingComponents = interpolate_impl.fillMissingComponents; + pub const interpolate = interpolate_impl.interpolate; + const recangular_impl = RecangularPremultiply(@This(), "l", "c", "h"); + pub const premultiply = recangular_impl.premultiply; + pub const unpremultiply = recangular_impl.unpremultiply; - pub usingnamespace color_conversions.convert_LCH; + /// Convert this color into another color format. + pub const into = ColorIntoMixin(@This(), .LCH).into; + pub const intoCssColor = ImplementIntoCssColor(@This(), .LCH); pub const ChannelTypeMap = .{ .l = ChannelType{ .percentage = true }, @@ -1984,15 +2194,33 @@ pub const OKLAB = struct { /// The alpha component. alpha: f32, - pub usingnamespace DefineColorspace(@This(), ChannelTypeMap); - pub usingnamespace ColorspaceConversions(@This()); - pub usingnamespace UnboundedColorGamut(@This()); + const colorspace_impl = DefineColorspace(@This(), ChannelTypeMap); + pub const components = colorspace_impl.components; + pub const channels = colorspace_impl.channels; + pub const types = colorspace_impl.types; + pub const resolveMissing = colorspace_impl.resolveMissing; + pub const resolve = colorspace_impl.resolve; + const conversions_impl = ColorspaceConversions(@This()); + pub const fromLABColor = conversions_impl.fromLABColor; + pub const fromPredefinedColor = conversions_impl.fromPredefinedColor; + pub const fromFloatColor = conversions_impl.fromFloatColor; + pub const tryFromCssColor = conversions_impl.tryFromCssColor; + pub const hash = conversions_impl.hash; + const gamut_impl = UnboundedColorGamut(@This()); + pub const clip = gamut_impl.clip; + pub const inGamut = gamut_impl.inGamut; - pub usingnamespace AdjustPowerlessLAB(@This()); - pub usingnamespace DeriveInterpolate(@This(), "l", "a", "b"); - pub usingnamespace RecangularPremultiply(@This(), "l", "a", "b"); + pub const adjustPowerlessComponents = AdjustPowerlessLAB(@This()).adjustPowerlessComponents; + const interpolate_impl = DeriveInterpolate(@This(), "l", "a", "b"); + pub const fillMissingComponents = interpolate_impl.fillMissingComponents; + pub const interpolate = interpolate_impl.interpolate; + const recangular_impl = RecangularPremultiply(@This(), "l", "a", "b"); + pub const premultiply = recangular_impl.premultiply; + pub const unpremultiply = recangular_impl.unpremultiply; - pub usingnamespace color_conversions.convert_OKLAB; + /// Convert this color into another color format. + pub const into = ColorIntoMixin(@This(), .OKLAB).into; + pub const intoCssColor = ImplementIntoCssColor(@This(), .OKLAB); pub const ChannelTypeMap = .{ .l = ChannelType{ .percentage = true }, @@ -2014,15 +2242,36 @@ pub const OKLCH = struct { /// The alpha component. alpha: f32, - pub usingnamespace DefineColorspace(@This(), ChannelTypeMap); - pub usingnamespace ColorspaceConversions(@This()); - pub usingnamespace UnboundedColorGamut(@This()); + const colorspace_impl = DefineColorspace(@This(), ChannelTypeMap); + pub const components = colorspace_impl.components; + pub const channels = colorspace_impl.channels; + pub const types = colorspace_impl.types; + pub const resolveMissing = colorspace_impl.resolveMissing; + pub const resolve = colorspace_impl.resolve; + const conversions_impl = ColorspaceConversions(@This()); + pub const fromLABColor = conversions_impl.fromLABColor; + pub const fromPredefinedColor = conversions_impl.fromPredefinedColor; + pub const fromFloatColor = conversions_impl.fromFloatColor; + pub const tryFromCssColor = conversions_impl.tryFromCssColor; + pub const hash = conversions_impl.hash; + const gamut_impl = UnboundedColorGamut(@This()); + pub const clip = gamut_impl.clip; + pub const inGamut = gamut_impl.inGamut; - pub usingnamespace AdjustPowerlessLCH(@This()); - pub usingnamespace DeriveInterpolate(@This(), "l", "c", "h"); - pub usingnamespace RecangularPremultiply(@This(), "l", "c", "h"); + const powerless_lch_impl = AdjustPowerlessLCH(@This()); + pub const adjustPowerlessComponents = powerless_lch_impl.adjustPowerlessComponents; + pub const adjustHue = powerless_lch_impl.adjustHue; + const interpolate_impl = DeriveInterpolate(@This(), "l", "c", "h"); + pub const fillMissingComponents = interpolate_impl.fillMissingComponents; + pub const interpolate = interpolate_impl.interpolate; - pub usingnamespace color_conversions.convert_OKLCH; + const recangular_impl = RecangularPremultiply(@This(), "l", "c", "h"); + pub const premultiply = recangular_impl.premultiply; + pub const unpremultiply = recangular_impl.unpremultiply; + + /// Convert this color into another color format. + pub const into = ColorIntoMixin(@This(), .OKLCH).into; + pub const intoCssColor = ImplementIntoCssColor(@This(), .OKLCH); pub const ChannelTypeMap = .{ .l = ChannelType{ .percentage = true }, @@ -2455,19 +2704,25 @@ const RelativeComponentParser = struct { ident: []const u8, allowed_types: ChannelType, ) ?f32 { - if (bun.strings.eqlCaseInsensitiveASCIIICheckLength(ident, this.names[0]) and allowed_types.intersects(this.types[0])) { + if (bun.strings.eqlCaseInsensitiveASCIIICheckLength(ident, this.names[0]) and + bits.intersects(ChannelType, allowed_types, this.types[0])) + { return this.components[0]; } - if (bun.strings.eqlCaseInsensitiveASCIIICheckLength(ident, this.names[1]) and allowed_types.intersects(this.types[1])) { + if (bun.strings.eqlCaseInsensitiveASCIIICheckLength(ident, this.names[1]) and + bits.intersects(ChannelType, allowed_types, this.types[1])) + { return this.components[1]; } - if (bun.strings.eqlCaseInsensitiveASCIIICheckLength(ident, this.names[2]) and allowed_types.intersects(this.types[2])) { + if (bun.strings.eqlCaseInsensitiveASCIIICheckLength(ident, this.names[2]) and + bits.intersects(ChannelType, allowed_types, this.types[2])) + { return this.components[2]; } - if (bun.strings.eqlCaseInsensitiveASCIIICheckLength(ident, "alpha") and allowed_types.intersects(ChannelType{ .percentage = true })) { + if (bun.strings.eqlCaseInsensitiveASCIIICheckLength(ident, "alpha") and allowed_types.percentage) { return this.components[3]; } @@ -2485,8 +2740,6 @@ pub const ChannelType = packed struct(u8) { /// Channel represents a number. number: bool = false, __unused: u5 = 0, - - pub usingnamespace css.Bitflags(@This()); }; pub fn parsePredefined(input: *css.Parser, parser: *ComponentParser) Result(CssColor) { @@ -2707,24 +2960,30 @@ pub const ColorFallbackKind = packed struct(u8) { pub const LAB = ColorFallbackKind{ .lab = true }; pub const OKLAB = ColorFallbackKind{ .oklab = true }; - pub usingnamespace css.Bitflags(@This()); - pub fn lowest(this: @This()) ColorFallbackKind { - return this.bitwiseAnd(ColorFallbackKind.fromBitsTruncate(bun.wrappingNegation(this.asBits()))); + return bun.bits.@"and"( + ColorFallbackKind, + this, + fromBitsTruncate(bun.wrappingNegation(@as(u8, @bitCast(this)))), + ); } pub fn highest(this: @This()) ColorFallbackKind { // This finds the highest set bit. - if (this.isEmpty()) return ColorFallbackKind.empty(); + if (this.isEmpty()) return ColorFallbackKind{}; - const zeroes: u3 = @intCast(@as(u4, 7) - this.leadingZeroes()); - return ColorFallbackKind.fromBitsTruncate(@as(u8, 1) << zeroes); + const zeroes: u3 = @intCast(@as(u4, 7) - bun.bits.leadingZeros(ColorFallbackKind, this)); + return fromBitsTruncate(@as(u8, 1) << zeroes); + } + + pub fn difference(left: @This(), right: @This()) ColorFallbackKind { + return @bitCast(@as(u8, @bitCast(left)) - @as(u8, @bitCast(right))); } pub fn andBelow(this: @This()) ColorFallbackKind { - if (this.isEmpty()) return ColorFallbackKind.empty(); + if (this.isEmpty()) return .{}; - return this.bitwiseOr(ColorFallbackKind.fromBitsTruncate(this.asBits() - 1)); + return bun.bits.@"or"(ColorFallbackKind, this, fromBitsTruncate(@as(u8, @bitCast(this)) - 1)); } pub fn supportsCondition(this: @This()) css.SupportsCondition { @@ -2741,6 +3000,20 @@ pub const ColorFallbackKind = packed struct(u8) { }, }; } + + pub fn isEmpty(cfk: ColorFallbackKind) bool { + return @as(u8, @bitCast(cfk)) == 0; + } + + pub inline fn fromBitsTruncate(b: u8) ColorFallbackKind { + var cfk: ColorFallbackKind = @bitCast(b); + cfk.__unused = 0; + return cfk; + } + + pub fn asBits(this: @This()) u8 { + return @bitCast(this); + } }; /// A [color space](https://www.w3.org/TR/css-color-4/#interpolation-space) keyword @@ -2937,91 +3210,30 @@ fn rectangularToPolar(l: f32, a: f32, b: f32) struct { f32, f32, f32 } { } pub fn ColorspaceConversions(comptime T: type) type { - // e.g. T = LAB, so then: into_this_function_name = "intoLAB" - const into_this_function_name = "into" ++ comptime bun.meta.typeName(T); - return struct { + const convert_type: ConvertTo = .fromType(T); + pub fn fromLABColor(color: *const LABColor) T { return switch (color.*) { - .lab => |*v| { - if (comptime @TypeOf(v.*) == T) return v.*; - return @call(.auto, @field(@TypeOf(v.*), into_this_function_name), .{v}); - }, - .lch => |*v| { - if (comptime @TypeOf(v.*) == T) return v.*; - return @call(.auto, @field(@TypeOf(v.*), into_this_function_name), .{v}); - }, - .oklab => |*v| { - if (comptime @TypeOf(v.*) == T) return v.*; - return @call(.auto, @field(@TypeOf(v.*), into_this_function_name), .{v}); - }, - .oklch => |*v| { - if (comptime @TypeOf(v.*) == T) return v.*; - return @call(.auto, @field(@TypeOf(v.*), into_this_function_name), .{v}); - }, + inline else => |*v| v.into(convert_type), }; } pub fn fromPredefinedColor(color: *const PredefinedColor) T { return switch (color.*) { - .srgb => |*v| { - if (comptime @TypeOf(v.*) == T) return v.*; - return @call(.auto, @field(@TypeOf(v.*), into_this_function_name), .{v}); - }, - .srgb_linear => |*v| { - if (comptime @TypeOf(v.*) == T) return v.*; - return @call(.auto, @field(@TypeOf(v.*), into_this_function_name), .{v}); - }, - .display_p3 => |*v| { - if (comptime @TypeOf(v.*) == T) return v.*; - return @call(.auto, @field(@TypeOf(v.*), into_this_function_name), .{v}); - }, - .a98 => |*v| { - if (comptime @TypeOf(v.*) == T) return v.*; - return @call(.auto, @field(@TypeOf(v.*), into_this_function_name), .{v}); - }, - .prophoto => |*v| { - if (comptime @TypeOf(v.*) == T) return v.*; - return @call(.auto, @field(@TypeOf(v.*), into_this_function_name), .{v}); - }, - .rec2020 => |*v| { - if (comptime @TypeOf(v.*) == T) return v.*; - return @call(.auto, @field(@TypeOf(v.*), into_this_function_name), .{v}); - }, - .xyz_d50 => |*v| { - if (comptime @TypeOf(v.*) == T) return v.*; - return @call(.auto, @field(@TypeOf(v.*), into_this_function_name), .{v}); - }, - .xyz_d65 => |*v| { - if (comptime @TypeOf(v.*) == T) return v.*; - return @call(.auto, @field(@TypeOf(v.*), into_this_function_name), .{v}); - }, + inline else => |*v| v.into(convert_type), }; } pub fn fromFloatColor(color: *const FloatColor) T { return switch (color.*) { - .rgb => |*v| { - if (comptime T == SRGB) return v.*; - return @call(.auto, @field(@TypeOf(v.*), into_this_function_name), .{v}); - }, - .hsl => |*v| { - if (comptime T == HSL) return v.*; - return @call(.auto, @field(@TypeOf(v.*), into_this_function_name), .{v}); - }, - .hwb => |*v| { - if (comptime T == HWB) return v.*; - return @call(.auto, @field(@TypeOf(v.*), into_this_function_name), .{v}); - }, + inline else => |*v| v.into(convert_type), }; } pub fn tryFromCssColor(color: *const CssColor) ?T { return switch (color.*) { - .rgba => |*rgba| { - if (comptime T == RGBA) return rgba.*; - return @call(.auto, @field(@TypeOf(rgba.*), into_this_function_name), .{rgba}); - }, + .rgba => |*rgba| rgba.into(convert_type), .lab => |lab| fromLABColor(lab), .predefined => |predefined| fromPredefinedColor(predefined), .float => |float| fromFloatColor(float), @@ -3038,7 +3250,7 @@ pub fn ColorspaceConversions(comptime T: type) type { } pub fn DefineColorspace(comptime T: type, comptime ChannelTypeMap: anytype) type { - const fields: []const std.builtin.Type.StructField = std.meta.fields(T); + const fields: []const std.builtin.Type.StructField = @typeInfo(T).@"struct".fields; const a = fields[0].name; const b = fields[1].name; const c = fields[2].name; @@ -3471,16 +3683,11 @@ pub fn polarToRectangular(l: f32, c: f32, h: f32) struct { f32, f32, f32 } { const D50: []const f32 = &.{ @floatCast(@as(f64, 0.3457) / @as(f64, 0.3585)), 1.00000, @floatCast((@as(f64, 1.0) - @as(f64, 0.3457) - @as(f64, 0.3585)) / @as(f64, 0.3585)) }; // const D50: []const f32 = &.{ 0.9642956, 1.0, 0.82510453 }; +const generated_color_conversions = @import("./color_generated.zig").generated_color_conversions; const color_conversions = struct { - const generated = @import("./color_generated.zig").generated_color_conversions; - - pub const convert_RGBA = struct { - pub usingnamespace generated.convert_RGBA; - }; + pub const convert_RGBA = struct {}; pub const convert_LAB = struct { - pub usingnamespace generated.convert_LAB; - pub fn intoCssColor(c: *const LAB, allocator: Allocator) CssColor { return CssColor{ .lab = bun.create( allocator, @@ -3543,12 +3750,10 @@ const color_conversions = struct { }; pub const convert_SRGB = struct { - pub usingnamespace generated.convert_SRGB; - pub fn intoCssColor(srgb: *const SRGB, _: Allocator) CssColor { // TODO: should we serialize as color(srgb, ...)? // would be more precise than 8-bit color. - return CssColor{ .rgba = srgb.intoRGBA() }; + return CssColor{ .rgba = srgb.into(.RGBA) }; } pub fn intoSRGBLinear(rgb: *const SRGB) SRGBLinear { @@ -3605,7 +3810,7 @@ const color_conversions = struct { pub fn intoHWB(_rgb: *const SRGB) HWB { const rgb = _rgb.resolve(); - const hsl = rgb.intoHSL(); + const hsl = rgb.into(.HSL); const r = rgb.r; const g = rgb.g; const _b = rgb.b; @@ -3621,12 +3826,10 @@ const color_conversions = struct { }; pub const convert_HSL = struct { - pub usingnamespace generated.convert_HSL; - pub fn intoCssColor(c: *const HSL, _: Allocator) CssColor { // TODO: should we serialize as color(srgb, ...)? // would be more precise than 8-bit color. - return CssColor{ .rgba = c.intoRGBA() }; + return CssColor{ .rgba = c.into(.RGBA) }; } pub fn intoSRGB(hsl_: *const HSL) SRGB { @@ -3644,12 +3847,10 @@ const color_conversions = struct { }; pub const convert_HWB = struct { - pub usingnamespace generated.convert_HWB; - pub fn intoCssColor(c: *const HWB, _: Allocator) CssColor { // TODO: should we serialize as color(srgb, ...)? // would be more precise than 8-bit color. - return CssColor{ .rgba = c.intoRGBA() }; + return CssColor{ .rgba = c.into(.RGBA) }; } pub fn intoSRGB(_hwb: *const HWB) SRGB { @@ -3669,7 +3870,7 @@ const color_conversions = struct { }; } - var rgba = (HSL{ .h = h, .s = 1.0, .l = 0.5, .alpha = hwb.alpha }).intoSRGB(); + var rgba = (HSL{ .h = h, .s = 1.0, .l = 0.5, .alpha = hwb.alpha }).into(.SRGB); const x = 1.0 - w - b; rgba.r = rgba.r * x + w; rgba.g = rgba.g * x + w; @@ -3679,8 +3880,6 @@ const color_conversions = struct { }; pub const convert_SRGBLinear = struct { - pub usingnamespace generated.convert_SRGBLinear; - pub fn intoPredefinedColor(rgb: *const SRGBLinear) PredefinedColor { return PredefinedColor{ .srgb_linear = rgb.* }; } @@ -3690,7 +3889,7 @@ const color_conversions = struct { .predefined = bun.create( allocator, PredefinedColor, - rgb.intoPredefinedColor(), + rgb.into(.PredefinedColor), ), }; } @@ -3734,8 +3933,6 @@ const color_conversions = struct { }; pub const convert_P3 = struct { - pub usingnamespace generated.convert_P3; - pub fn intoPredefinedColor(rgb: *const P3) PredefinedColor { return PredefinedColor{ .display_p3 = rgb.* }; } @@ -3745,7 +3942,7 @@ const color_conversions = struct { .predefined = bun.create( allocator, PredefinedColor, - rgb.intoPredefinedColor(), + rgb.into(.PredefinedColor), ), }; } @@ -3780,8 +3977,6 @@ const color_conversions = struct { }; pub const convert_A98 = struct { - pub usingnamespace generated.convert_A98; - pub fn intoPredefinedColor(rgb: *const A98) PredefinedColor { return PredefinedColor{ .a98 = rgb.* }; } @@ -3791,7 +3986,7 @@ const color_conversions = struct { .predefined = bun.create( allocator, PredefinedColor, - rgb.intoPredefinedColor(), + rgb.into(.PredefinedColor), ), }; } @@ -3843,8 +4038,6 @@ const color_conversions = struct { }; pub const convert_ProPhoto = struct { - pub usingnamespace generated.convert_ProPhoto; - pub fn intoPredefinedColor(rgb: *const ProPhoto) PredefinedColor { return PredefinedColor{ .prophoto = rgb.* }; } @@ -3854,7 +4047,7 @@ const color_conversions = struct { .predefined = bun.create( allocator, PredefinedColor, - rgb.intoPredefinedColor(), + rgb.into(.PredefinedColor), ), }; } @@ -3911,8 +4104,6 @@ const color_conversions = struct { }; pub const convert_Rec2020 = struct { - pub usingnamespace generated.convert_Rec2020; - pub fn intoPredefinedColor(rgb: *const Rec2020) PredefinedColor { return PredefinedColor{ .rec2020 = rgb.* }; } @@ -3922,7 +4113,7 @@ const color_conversions = struct { .predefined = bun.create( allocator, PredefinedColor, - rgb.intoPredefinedColor(), + rgb.into(.PredefinedColor), ), }; } @@ -3984,8 +4175,6 @@ const color_conversions = struct { }; pub const convert_XYZd50 = struct { - pub usingnamespace generated.convert_XYZd50; - pub fn intoPredefinedColor(rgb: *const XYZd50) PredefinedColor { return PredefinedColor{ .xyz_d50 = rgb.* }; } @@ -3995,7 +4184,7 @@ const color_conversions = struct { .predefined = bun.create( allocator, PredefinedColor, - rgb.intoPredefinedColor(), + rgb.into(.PredefinedColor), ), }; } @@ -4101,8 +4290,6 @@ const color_conversions = struct { }; pub const convert_XYZd65 = struct { - pub usingnamespace generated.convert_XYZd65; - pub fn intoPredefinedColor(rgb: *const XYZd65) PredefinedColor { return PredefinedColor{ .xyz_d65 = rgb.* }; } @@ -4112,7 +4299,7 @@ const color_conversions = struct { .predefined = bun.create( allocator, PredefinedColor, - rgb.intoPredefinedColor(), + rgb.into(.PredefinedColor), ), }; } @@ -4319,8 +4506,6 @@ const color_conversions = struct { }; pub const convert_LCH = struct { - pub usingnamespace generated.convert_LCH; - pub fn intoCssColor(c: *const LCH, allocator: Allocator) CssColor { return CssColor{ .lab = bun.create( allocator, @@ -4342,8 +4527,6 @@ const color_conversions = struct { }; pub const convert_OKLAB = struct { - pub usingnamespace generated.convert_OKLAB; - pub fn intoCssColor(c: *const OKLAB, allocator: Allocator) CssColor { return CssColor{ .lab = bun.create( allocator, @@ -4412,8 +4595,6 @@ const color_conversions = struct { }; pub const convert_OKLCH = struct { - pub usingnamespace generated.convert_OKLCH; - pub fn intoCssColor(c: *const OKLCH, allocator: Allocator) CssColor { return CssColor{ .lab = bun.create( allocator, @@ -4438,3 +4619,93 @@ const color_conversions = struct { } }; }; + +pub const ConvertTo = enum { + RGBA, + LAB, + SRGB, + HSL, + HWB, + SRGBLinear, + P3, + A98, + ProPhoto, + Rec2020, + XYZd50, + XYZd65, + LCH, + OKLAB, + OKLCH, + PredefinedColor, + pub fn fromType(comptime T: type) ConvertTo { + return @field(ConvertTo, bun.meta.typeName(T)); + } + pub fn Type(comptime space: ConvertTo) type { + return switch (space) { + .RGBA => RGBA, + .LAB => LAB, + .SRGB => SRGB, + .HSL => HSL, + .HWB => HWB, + .SRGBLinear => SRGBLinear, + .P3 => P3, + .A98 => A98, + .ProPhoto => ProPhoto, + .Rec2020 => Rec2020, + .XYZd50 => XYZd50, + .XYZd65 => XYZd65, + .LCH => LCH, + .OKLAB => OKLAB, + .OKLCH => OKLCH, + .PredefinedColor => PredefinedColor, + }; + } +}; +pub fn ColorIntoMixin(T: type, space: ConvertTo) type { + return struct { + pub const into_names = struct { + const RGBA = "intoRGBA"; + const LAB = "intoLAB"; + const SRGB = "intoSRGB"; + const HSL = "intoHSL"; + const HWB = "intoHWB"; + const SRGBLinear = "intoSRGBLinear"; + const P3 = "intoP3"; + const A98 = "intoA98"; + const ProPhoto = "intoProPhoto"; + const Rec2020 = "intoRec2020"; + const XYZd50 = "intoXYZd50"; + const XYZd65 = "intoXYZd65"; + const LCH = "intoLCH"; + const OKLAB = "intoOKLAB"; + const OKLCH = "intoOKLCH"; + const PredefinedColor = "intoPredefinedColor"; + }; + const ns = "convert_" ++ @tagName(space); + + const handwritten_conversions = @field(color_conversions, ns); + const generated_conversions = @field(generated_color_conversions, ns); + + pub fn into(color: *const T, comptime target_space: ConvertTo) target_space.Type() { + if (target_space == space) return color.*; + + const name = @field(into_names, @tagName(target_space)); + + const function = if (@hasDecl(handwritten_conversions, name)) + @field(handwritten_conversions, name) + else if (@hasDecl(generated_conversions, name)) + @field(generated_conversions, name) + else if (@hasDecl(T, name)) + @field(T, name) + else + @compileError("No conversion from " ++ @tagName(space) ++ " to " ++ @tagName(target_space)); + + return function(color); + } + }; +} + +pub fn ImplementIntoCssColor(comptime T: type, space: ConvertTo) fn (*const T, Allocator) CssColor { + const ns = "convert_" ++ @tagName(space); + return @field(color_conversions, ns).intoCssColor; +} diff --git a/src/css/values/color_generated.zig b/src/css/values/color_generated.zig index a767990f1f..596d0fb586 100644 --- a/src/css/values/color_generated.zig +++ b/src/css/values/color_generated.zig @@ -19,927 +19,927 @@ const Rec2020 = color.Rec2020; pub const generated_color_conversions = struct { pub const convert_RGBA = struct { pub fn intoLAB(this: *const RGBA) LAB { - const xyz: SRGB = this.intoSRGB(); - return xyz.intoLAB(); + const xyz: SRGB = this.into(.SRGB); + return xyz.into(.LAB); } pub fn intoLCH(this: *const RGBA) LCH { - const xyz: SRGB = this.intoSRGB(); - return xyz.intoLCH(); + const xyz: SRGB = this.into(.SRGB); + return xyz.into(.LCH); } pub fn intoOKLAB(this: *const RGBA) OKLAB { - const xyz: SRGB = this.intoSRGB(); - return xyz.intoOKLAB(); + const xyz: SRGB = this.into(.SRGB); + return xyz.into(.OKLAB); } pub fn intoOKLCH(this: *const RGBA) OKLCH { - const xyz: SRGB = this.intoSRGB(); - return xyz.intoOKLCH(); + const xyz: SRGB = this.into(.SRGB); + return xyz.into(.OKLCH); } pub fn intoP3(this: *const RGBA) P3 { - const xyz: SRGB = this.intoSRGB(); - return xyz.intoP3(); + const xyz: SRGB = this.into(.SRGB); + return xyz.into(.P3); } pub fn intoSRGBLinear(this: *const RGBA) SRGBLinear { - const xyz: SRGB = this.intoSRGB(); - return xyz.intoSRGBLinear(); + const xyz: SRGB = this.into(.SRGB); + return xyz.into(.SRGBLinear); } pub fn intoA98(this: *const RGBA) A98 { - const xyz: SRGB = this.intoSRGB(); - return xyz.intoA98(); + const xyz: SRGB = this.into(.SRGB); + return xyz.into(.A98); } pub fn intoProPhoto(this: *const RGBA) ProPhoto { - const xyz: SRGB = this.intoSRGB(); - return xyz.intoProPhoto(); + const xyz: SRGB = this.into(.SRGB); + return xyz.into(.ProPhoto); } pub fn intoXYZd50(this: *const RGBA) XYZd50 { - const xyz: SRGB = this.intoSRGB(); - return xyz.intoXYZd50(); + const xyz: SRGB = this.into(.SRGB); + return xyz.into(.XYZd50); } pub fn intoXYZd65(this: *const RGBA) XYZd65 { - const xyz: SRGB = this.intoSRGB(); - return xyz.intoXYZd65(); + const xyz: SRGB = this.into(.SRGB); + return xyz.into(.XYZd65); } pub fn intoRec2020(this: *const RGBA) Rec2020 { - const xyz: SRGB = this.intoSRGB(); - return xyz.intoRec2020(); + const xyz: SRGB = this.into(.SRGB); + return xyz.into(.Rec2020); } pub fn intoHSL(this: *const RGBA) HSL { - const xyz: SRGB = this.intoSRGB(); - return xyz.intoHSL(); + const xyz: SRGB = this.into(.SRGB); + return xyz.into(.HSL); } pub fn intoHWB(this: *const RGBA) HWB { - const xyz: SRGB = this.intoSRGB(); - return xyz.intoHWB(); + const xyz: SRGB = this.into(.SRGB); + return xyz.into(.HWB); } }; pub const convert_LAB = struct { pub fn intoXYZd65(this: *const LAB) XYZd65 { - const xyz: XYZd50 = this.intoXYZd50(); - return xyz.intoXYZd65(); + const xyz: XYZd50 = this.into(.XYZd50); + return xyz.into(.XYZd65); } pub fn intoOKLAB(this: *const LAB) OKLAB { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoOKLAB(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.OKLAB); } pub fn intoOKLCH(this: *const LAB) OKLCH { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoOKLCH(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.OKLCH); } pub fn intoSRGB(this: *const LAB) SRGB { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoSRGB(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.SRGB); } pub fn intoSRGBLinear(this: *const LAB) SRGBLinear { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoSRGBLinear(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.SRGBLinear); } pub fn intoP3(this: *const LAB) P3 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoP3(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.P3); } pub fn intoA98(this: *const LAB) A98 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoA98(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.A98); } pub fn intoProPhoto(this: *const LAB) ProPhoto { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoProPhoto(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.ProPhoto); } pub fn intoRec2020(this: *const LAB) Rec2020 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoRec2020(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.Rec2020); } pub fn intoHSL(this: *const LAB) HSL { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoHSL(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.HSL); } pub fn intoHWB(this: *const LAB) HWB { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoHWB(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.HWB); } pub fn intoRGBA(this: *const LAB) RGBA { - const xyz: SRGB = this.intoSRGB(); - return xyz.intoRGBA(); + const xyz: SRGB = this.into(.SRGB); + return xyz.into(.RGBA); } }; pub const convert_SRGB = struct { pub fn intoLAB(this: *const SRGB) LAB { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoLAB(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.LAB); } pub fn intoLCH(this: *const SRGB) LCH { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoLCH(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.LCH); } pub fn intoXYZd65(this: *const SRGB) XYZd65 { - const xyz: SRGBLinear = this.intoSRGBLinear(); - return xyz.intoXYZd65(); + const xyz: SRGBLinear = this.into(.SRGBLinear); + return xyz.into(.XYZd65); } pub fn intoOKLAB(this: *const SRGB) OKLAB { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoOKLAB(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.OKLAB); } pub fn intoOKLCH(this: *const SRGB) OKLCH { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoOKLCH(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.OKLCH); } pub fn intoP3(this: *const SRGB) P3 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoP3(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.P3); } pub fn intoA98(this: *const SRGB) A98 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoA98(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.A98); } pub fn intoProPhoto(this: *const SRGB) ProPhoto { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoProPhoto(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.ProPhoto); } pub fn intoRec2020(this: *const SRGB) Rec2020 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoRec2020(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.Rec2020); } pub fn intoXYZd50(this: *const SRGB) XYZd50 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoXYZd50(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.XYZd50); } }; pub const convert_HSL = struct { pub fn intoLAB(this: *const HSL) LAB { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoLAB(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.LAB); } pub fn intoLCH(this: *const HSL) LCH { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoLCH(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.LCH); } pub fn intoP3(this: *const HSL) P3 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoP3(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.P3); } pub fn intoSRGBLinear(this: *const HSL) SRGBLinear { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoSRGBLinear(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.SRGBLinear); } pub fn intoA98(this: *const HSL) A98 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoA98(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.A98); } pub fn intoProPhoto(this: *const HSL) ProPhoto { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoProPhoto(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.ProPhoto); } pub fn intoXYZd50(this: *const HSL) XYZd50 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoXYZd50(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.XYZd50); } pub fn intoRec2020(this: *const HSL) Rec2020 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoRec2020(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.Rec2020); } pub fn intoOKLAB(this: *const HSL) OKLAB { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoOKLAB(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.OKLAB); } pub fn intoOKLCH(this: *const HSL) OKLCH { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoOKLCH(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.OKLCH); } pub fn intoXYZd65(this: *const HSL) XYZd65 { - const xyz: SRGB = this.intoSRGB(); - return xyz.intoXYZd65(); + const xyz: SRGB = this.into(.SRGB); + return xyz.into(.XYZd65); } pub fn intoHWB(this: *const HSL) HWB { - const xyz: SRGB = this.intoSRGB(); - return xyz.intoHWB(); + const xyz: SRGB = this.into(.SRGB); + return xyz.into(.HWB); } pub fn intoRGBA(this: *const HSL) RGBA { - const xyz: SRGB = this.intoSRGB(); - return xyz.intoRGBA(); + const xyz: SRGB = this.into(.SRGB); + return xyz.into(.RGBA); } }; pub const convert_HWB = struct { pub fn intoLAB(this: *const HWB) LAB { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoLAB(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.LAB); } pub fn intoLCH(this: *const HWB) LCH { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoLCH(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.LCH); } pub fn intoP3(this: *const HWB) P3 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoP3(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.P3); } pub fn intoSRGBLinear(this: *const HWB) SRGBLinear { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoSRGBLinear(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.SRGBLinear); } pub fn intoA98(this: *const HWB) A98 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoA98(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.A98); } pub fn intoProPhoto(this: *const HWB) ProPhoto { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoProPhoto(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.ProPhoto); } pub fn intoXYZd50(this: *const HWB) XYZd50 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoXYZd50(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.XYZd50); } pub fn intoRec2020(this: *const HWB) Rec2020 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoRec2020(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.Rec2020); } pub fn intoHSL(this: *const HWB) HSL { - const xyz: SRGB = this.intoSRGB(); - return xyz.intoHSL(); + const xyz: SRGB = this.into(.SRGB); + return xyz.into(.HSL); } pub fn intoXYZd65(this: *const HWB) XYZd65 { - const xyz: SRGB = this.intoSRGB(); - return xyz.intoXYZd65(); + const xyz: SRGB = this.into(.SRGB); + return xyz.into(.XYZd65); } pub fn intoOKLAB(this: *const HWB) OKLAB { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoOKLAB(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.OKLAB); } pub fn intoOKLCH(this: *const HWB) OKLCH { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoOKLCH(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.OKLCH); } pub fn intoRGBA(this: *const HWB) RGBA { - const xyz: SRGB = this.intoSRGB(); - return xyz.intoRGBA(); + const xyz: SRGB = this.into(.SRGB); + return xyz.into(.RGBA); } }; pub const convert_SRGBLinear = struct { pub fn intoLAB(this: *const SRGBLinear) LAB { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoLAB(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.LAB); } pub fn intoLCH(this: *const SRGBLinear) LCH { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoLCH(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.LCH); } pub fn intoP3(this: *const SRGBLinear) P3 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoP3(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.P3); } pub fn intoOKLAB(this: *const SRGBLinear) OKLAB { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoOKLAB(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.OKLAB); } pub fn intoOKLCH(this: *const SRGBLinear) OKLCH { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoOKLCH(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.OKLCH); } pub fn intoA98(this: *const SRGBLinear) A98 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoA98(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.A98); } pub fn intoProPhoto(this: *const SRGBLinear) ProPhoto { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoProPhoto(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.ProPhoto); } pub fn intoRec2020(this: *const SRGBLinear) Rec2020 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoRec2020(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.Rec2020); } pub fn intoXYZd50(this: *const SRGBLinear) XYZd50 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoXYZd50(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.XYZd50); } pub fn intoHSL(this: *const SRGBLinear) HSL { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoHSL(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.HSL); } pub fn intoHWB(this: *const SRGBLinear) HWB { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoHWB(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.HWB); } pub fn intoRGBA(this: *const SRGBLinear) RGBA { - const xyz: SRGB = this.intoSRGB(); - return xyz.intoRGBA(); + const xyz: SRGB = this.into(.SRGB); + return xyz.into(.RGBA); } }; pub const convert_P3 = struct { pub fn intoLAB(this: *const P3) LAB { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoLAB(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.LAB); } pub fn intoLCH(this: *const P3) LCH { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoLCH(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.LCH); } pub fn intoSRGB(this: *const P3) SRGB { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoSRGB(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.SRGB); } pub fn intoSRGBLinear(this: *const P3) SRGBLinear { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoSRGBLinear(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.SRGBLinear); } pub fn intoOKLAB(this: *const P3) OKLAB { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoOKLAB(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.OKLAB); } pub fn intoOKLCH(this: *const P3) OKLCH { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoOKLCH(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.OKLCH); } pub fn intoA98(this: *const P3) A98 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoA98(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.A98); } pub fn intoProPhoto(this: *const P3) ProPhoto { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoProPhoto(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.ProPhoto); } pub fn intoRec2020(this: *const P3) Rec2020 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoRec2020(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.Rec2020); } pub fn intoXYZd50(this: *const P3) XYZd50 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoXYZd50(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.XYZd50); } pub fn intoHSL(this: *const P3) HSL { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoHSL(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.HSL); } pub fn intoHWB(this: *const P3) HWB { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoHWB(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.HWB); } pub fn intoRGBA(this: *const P3) RGBA { - const xyz: SRGB = this.intoSRGB(); - return xyz.intoRGBA(); + const xyz: SRGB = this.into(.SRGB); + return xyz.into(.RGBA); } }; pub const convert_A98 = struct { pub fn intoLAB(this: *const A98) LAB { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoLAB(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.LAB); } pub fn intoLCH(this: *const A98) LCH { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoLCH(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.LCH); } pub fn intoSRGB(this: *const A98) SRGB { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoSRGB(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.SRGB); } pub fn intoP3(this: *const A98) P3 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoP3(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.P3); } pub fn intoSRGBLinear(this: *const A98) SRGBLinear { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoSRGBLinear(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.SRGBLinear); } pub fn intoOKLAB(this: *const A98) OKLAB { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoOKLAB(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.OKLAB); } pub fn intoOKLCH(this: *const A98) OKLCH { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoOKLCH(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.OKLCH); } pub fn intoProPhoto(this: *const A98) ProPhoto { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoProPhoto(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.ProPhoto); } pub fn intoRec2020(this: *const A98) Rec2020 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoRec2020(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.Rec2020); } pub fn intoXYZd50(this: *const A98) XYZd50 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoXYZd50(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.XYZd50); } pub fn intoHSL(this: *const A98) HSL { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoHSL(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.HSL); } pub fn intoHWB(this: *const A98) HWB { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoHWB(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.HWB); } pub fn intoRGBA(this: *const A98) RGBA { - const xyz: SRGB = this.intoSRGB(); - return xyz.intoRGBA(); + const xyz: SRGB = this.into(.SRGB); + return xyz.into(.RGBA); } }; pub const convert_ProPhoto = struct { pub fn intoXYZd65(this: *const ProPhoto) XYZd65 { - const xyz: XYZd50 = this.intoXYZd50(); - return xyz.intoXYZd65(); + const xyz: XYZd50 = this.into(.XYZd50); + return xyz.into(.XYZd65); } pub fn intoLAB(this: *const ProPhoto) LAB { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoLAB(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.LAB); } pub fn intoLCH(this: *const ProPhoto) LCH { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoLCH(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.LCH); } pub fn intoSRGB(this: *const ProPhoto) SRGB { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoSRGB(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.SRGB); } pub fn intoP3(this: *const ProPhoto) P3 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoP3(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.P3); } pub fn intoSRGBLinear(this: *const ProPhoto) SRGBLinear { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoSRGBLinear(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.SRGBLinear); } pub fn intoA98(this: *const ProPhoto) A98 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoA98(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.A98); } pub fn intoOKLAB(this: *const ProPhoto) OKLAB { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoOKLAB(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.OKLAB); } pub fn intoOKLCH(this: *const ProPhoto) OKLCH { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoOKLCH(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.OKLCH); } pub fn intoRec2020(this: *const ProPhoto) Rec2020 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoRec2020(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.Rec2020); } pub fn intoHSL(this: *const ProPhoto) HSL { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoHSL(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.HSL); } pub fn intoHWB(this: *const ProPhoto) HWB { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoHWB(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.HWB); } pub fn intoRGBA(this: *const ProPhoto) RGBA { - const xyz: SRGB = this.intoSRGB(); - return xyz.intoRGBA(); + const xyz: SRGB = this.into(.SRGB); + return xyz.into(.RGBA); } }; pub const convert_Rec2020 = struct { pub fn intoLAB(this: *const Rec2020) LAB { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoLAB(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.LAB); } pub fn intoLCH(this: *const Rec2020) LCH { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoLCH(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.LCH); } pub fn intoSRGB(this: *const Rec2020) SRGB { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoSRGB(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.SRGB); } pub fn intoP3(this: *const Rec2020) P3 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoP3(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.P3); } pub fn intoSRGBLinear(this: *const Rec2020) SRGBLinear { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoSRGBLinear(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.SRGBLinear); } pub fn intoA98(this: *const Rec2020) A98 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoA98(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.A98); } pub fn intoProPhoto(this: *const Rec2020) ProPhoto { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoProPhoto(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.ProPhoto); } pub fn intoXYZd50(this: *const Rec2020) XYZd50 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoXYZd50(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.XYZd50); } pub fn intoOKLAB(this: *const Rec2020) OKLAB { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoOKLAB(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.OKLAB); } pub fn intoOKLCH(this: *const Rec2020) OKLCH { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoOKLCH(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.OKLCH); } pub fn intoHSL(this: *const Rec2020) HSL { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoHSL(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.HSL); } pub fn intoHWB(this: *const Rec2020) HWB { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoHWB(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.HWB); } pub fn intoRGBA(this: *const Rec2020) RGBA { - const xyz: SRGB = this.intoSRGB(); - return xyz.intoRGBA(); + const xyz: SRGB = this.into(.SRGB); + return xyz.into(.RGBA); } }; pub const convert_XYZd50 = struct { pub fn intoLCH(this: *const XYZd50) LCH { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoLCH(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.LCH); } pub fn intoSRGB(this: *const XYZd50) SRGB { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoSRGB(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.SRGB); } pub fn intoP3(this: *const XYZd50) P3 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoP3(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.P3); } pub fn intoSRGBLinear(this: *const XYZd50) SRGBLinear { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoSRGBLinear(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.SRGBLinear); } pub fn intoA98(this: *const XYZd50) A98 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoA98(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.A98); } pub fn intoOKLAB(this: *const XYZd50) OKLAB { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoOKLAB(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.OKLAB); } pub fn intoOKLCH(this: *const XYZd50) OKLCH { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoOKLCH(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.OKLCH); } pub fn intoRec2020(this: *const XYZd50) Rec2020 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoRec2020(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.Rec2020); } pub fn intoHSL(this: *const XYZd50) HSL { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoHSL(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.HSL); } pub fn intoHWB(this: *const XYZd50) HWB { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoHWB(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.HWB); } pub fn intoRGBA(this: *const XYZd50) RGBA { - const xyz: SRGB = this.intoSRGB(); - return xyz.intoRGBA(); + const xyz: SRGB = this.into(.SRGB); + return xyz.into(.RGBA); } }; pub const convert_XYZd65 = struct { pub fn intoLAB(this: *const XYZd65) LAB { - const xyz: XYZd50 = this.intoXYZd50(); - return xyz.intoLAB(); + const xyz: XYZd50 = this.into(.XYZd50); + return xyz.into(.LAB); } pub fn intoProPhoto(this: *const XYZd65) ProPhoto { - const xyz: XYZd50 = this.intoXYZd50(); - return xyz.intoProPhoto(); + const xyz: XYZd50 = this.into(.XYZd50); + return xyz.into(.ProPhoto); } pub fn intoOKLCH(this: *const XYZd65) OKLCH { - const xyz: OKLAB = this.intoOKLAB(); - return xyz.intoOKLCH(); + const xyz: OKLAB = this.into(.OKLAB); + return xyz.into(.OKLCH); } pub fn intoLCH(this: *const XYZd65) LCH { - const xyz: LAB = this.intoLAB(); - return xyz.intoLCH(); + const xyz: LAB = this.into(.LAB); + return xyz.into(.LCH); } pub fn intoSRGB(this: *const XYZd65) SRGB { - const xyz: SRGBLinear = this.intoSRGBLinear(); - return xyz.intoSRGB(); + const xyz: SRGBLinear = this.into(.SRGBLinear); + return xyz.into(.SRGB); } pub fn intoHSL(this: *const XYZd65) HSL { - const xyz: SRGB = this.intoSRGB(); - return xyz.intoHSL(); + const xyz: SRGB = this.into(.SRGB); + return xyz.into(.HSL); } pub fn intoHWB(this: *const XYZd65) HWB { - const xyz: SRGB = this.intoSRGB(); - return xyz.intoHWB(); + const xyz: SRGB = this.into(.SRGB); + return xyz.into(.HWB); } pub fn intoRGBA(this: *const XYZd65) RGBA { - const xyz: SRGB = this.intoSRGB(); - return xyz.intoRGBA(); + const xyz: SRGB = this.into(.SRGB); + return xyz.into(.RGBA); } }; pub const convert_LCH = struct { pub fn intoXYZd65(this: *const LCH) XYZd65 { - const xyz: LAB = this.intoLAB(); - return xyz.intoXYZd65(); + const xyz: LAB = this.into(.LAB); + return xyz.into(.XYZd65); } pub fn intoOKLAB(this: *const LCH) OKLAB { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoOKLAB(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.OKLAB); } pub fn intoOKLCH(this: *const LCH) OKLCH { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoOKLCH(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.OKLCH); } pub fn intoSRGB(this: *const LCH) SRGB { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoSRGB(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.SRGB); } pub fn intoSRGBLinear(this: *const LCH) SRGBLinear { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoSRGBLinear(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.SRGBLinear); } pub fn intoP3(this: *const LCH) P3 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoP3(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.P3); } pub fn intoA98(this: *const LCH) A98 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoA98(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.A98); } pub fn intoProPhoto(this: *const LCH) ProPhoto { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoProPhoto(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.ProPhoto); } pub fn intoRec2020(this: *const LCH) Rec2020 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoRec2020(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.Rec2020); } pub fn intoXYZd50(this: *const LCH) XYZd50 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoXYZd50(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.XYZd50); } pub fn intoHSL(this: *const LCH) HSL { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoHSL(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.HSL); } pub fn intoHWB(this: *const LCH) HWB { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoHWB(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.HWB); } pub fn intoRGBA(this: *const LCH) RGBA { - const xyz: SRGB = this.intoSRGB(); - return xyz.intoRGBA(); + const xyz: SRGB = this.into(.SRGB); + return xyz.into(.RGBA); } }; pub const convert_OKLAB = struct { pub fn intoLAB(this: *const OKLAB) LAB { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoLAB(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.LAB); } pub fn intoLCH(this: *const OKLAB) LCH { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoLCH(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.LCH); } pub fn intoSRGB(this: *const OKLAB) SRGB { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoSRGB(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.SRGB); } pub fn intoP3(this: *const OKLAB) P3 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoP3(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.P3); } pub fn intoSRGBLinear(this: *const OKLAB) SRGBLinear { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoSRGBLinear(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.SRGBLinear); } pub fn intoA98(this: *const OKLAB) A98 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoA98(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.A98); } pub fn intoProPhoto(this: *const OKLAB) ProPhoto { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoProPhoto(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.ProPhoto); } pub fn intoXYZd50(this: *const OKLAB) XYZd50 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoXYZd50(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.XYZd50); } pub fn intoRec2020(this: *const OKLAB) Rec2020 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoRec2020(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.Rec2020); } pub fn intoHSL(this: *const OKLAB) HSL { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoHSL(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.HSL); } pub fn intoHWB(this: *const OKLAB) HWB { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoHWB(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.HWB); } pub fn intoRGBA(this: *const OKLAB) RGBA { - const xyz: SRGB = this.intoSRGB(); - return xyz.intoRGBA(); + const xyz: SRGB = this.into(.SRGB); + return xyz.into(.RGBA); } }; pub const convert_OKLCH = struct { pub fn intoXYZd65(this: *const OKLCH) XYZd65 { - const xyz: OKLAB = this.intoOKLAB(); - return xyz.intoXYZd65(); + const xyz: OKLAB = this.into(.OKLAB); + return xyz.into(.XYZd65); } pub fn intoLAB(this: *const OKLCH) LAB { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoLAB(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.LAB); } pub fn intoLCH(this: *const OKLCH) LCH { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoLCH(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.LCH); } pub fn intoSRGB(this: *const OKLCH) SRGB { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoSRGB(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.SRGB); } pub fn intoP3(this: *const OKLCH) P3 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoP3(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.P3); } pub fn intoSRGBLinear(this: *const OKLCH) SRGBLinear { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoSRGBLinear(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.SRGBLinear); } pub fn intoA98(this: *const OKLCH) A98 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoA98(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.A98); } pub fn intoProPhoto(this: *const OKLCH) ProPhoto { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoProPhoto(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.ProPhoto); } pub fn intoXYZd50(this: *const OKLCH) XYZd50 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoXYZd50(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.XYZd50); } pub fn intoRec2020(this: *const OKLCH) Rec2020 { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoRec2020(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.Rec2020); } pub fn intoHSL(this: *const OKLCH) HSL { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoHSL(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.HSL); } pub fn intoHWB(this: *const OKLCH) HWB { - const xyz: XYZd65 = this.intoXYZd65(); - return xyz.intoHWB(); + const xyz: XYZd65 = this.into(.XYZd65); + return xyz.into(.HWB); } pub fn intoRGBA(this: *const OKLCH) RGBA { - const xyz: SRGB = this.intoSRGB(); - return xyz.intoRGBA(); + const xyz: SRGB = this.into(.SRGB); + return xyz.into(.RGBA); } }; }; diff --git a/src/css/values/color_js.zig b/src/css/values/color_js.zig index 234e6e08d5..0438bcc4b0 100644 --- a/src/css/values/color_js.zig +++ b/src/css/values/color_js.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const std = @import("std"); const color = @import("./color.zig"); const RGBA = color.RGBA; @@ -281,15 +281,15 @@ pub fn jsFunctionColor(globalThis: *JSC.JSGlobalObject, callFrame: *JSC.CallFram const srgba = switch (result.*) { .float => |float| switch (float.*) { .rgb => |rgb| rgb, - inline else => |*val| val.intoSRGB(), + inline else => |*val| val.into(.SRGB), }, - .rgba => |*rgba| rgba.intoSRGB(), + .rgba => |*rgba| rgba.into(.SRGB), .lab => |lab| switch (lab.*) { - inline else => |entry| entry.intoSRGB(), + inline else => |entry| entry.into(.SRGB), }, else => break :formatted, }; - const rgba = srgba.intoRGBA(); + const rgba = srgba.into(.RGBA); switch (tag) { .@"{rgba}" => { const object = JSC.JSValue.createEmptyObject(globalThis, 4); @@ -385,12 +385,12 @@ pub fn jsFunctionColor(globalThis: *JSC.JSGlobalObject, callFrame: *JSC.CallFram .float => |float| brk: { switch (float.*) { .hsl => |hsl| break :brk hsl, - inline else => |*val| break :brk val.intoHSL(), + inline else => |*val| break :brk val.into(.HSL), } }, - .rgba => |*rgba| rgba.intoHSL(), + .rgba => |*rgba| rgba.into(.HSL), .lab => |lab| switch (lab.*) { - inline else => |entry| entry.intoHSL(), + inline else => |entry| entry.into(.HSL), }, else => break :formatted, }; @@ -400,13 +400,13 @@ pub fn jsFunctionColor(globalThis: *JSC.JSGlobalObject, callFrame: *JSC.CallFram .lab => { const lab = switch (result.*) { .float => |float| switch (float.*) { - inline else => |*val| val.intoLAB(), + inline else => |*val| val.into(.LAB), }, .lab => |lab| switch (lab.*) { .lab => |lab_| lab_, - inline else => |entry| entry.intoLAB(), + inline else => |entry| entry.into(.LAB), }, - .rgba => |*rgba| rgba.intoLAB(), + .rgba => |*rgba| rgba.into(.LAB), else => break :formatted, }; diff --git a/src/css/values/css_string.zig b/src/css/values/css_string.zig index 7cb042cd3d..5e8e710392 100644 --- a/src/css/values/css_string.zig +++ b/src/css/values/css_string.zig @@ -1,6 +1,6 @@ const std = @import("std"); const Allocator = std.mem.Allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const logger = bun.logger; const Log = logger.Log; diff --git a/src/css/values/easing.zig b/src/css/values/easing.zig index ee3a847e4c..8fcb6807db 100644 --- a/src/css/values/easing.zig +++ b/src/css/values/easing.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); pub const css = @import("../css_parser.zig"); const Result = css.Result; const ArrayList = std.ArrayListUnmanaged; @@ -250,7 +250,7 @@ pub const StepPosition = enum { /// The first rise occurs at input progress value of 0 and the last rise occurs at input progress value of 1. @"jump-both", - pub usingnamespace css.DeriveToCss(@This()); + pub const toCss = css.DeriveToCss(@This()).toCss; const Map = bun.ComptimeEnumMap(enum { start, diff --git a/src/css/values/gradient.zig b/src/css/values/gradient.zig index 0ee9d2010d..2a49f088cb 100644 --- a/src/css/values/gradient.zig +++ b/src/css/values/gradient.zig @@ -1,6 +1,6 @@ const std = @import("std"); const Allocator = std.mem.Allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const ArrayList = std.ArrayListUnmanaged; pub const css = @import("../css_parser.zig"); const Result = css.Result; @@ -212,7 +212,7 @@ pub const Gradient = union(enum) { switch (this.*) { .linear, .repeating_linear => |*linear| { - try linear.toCss(W, dest, linear.vendor_prefix.neq(css.VendorPrefix{ .none = true })); + try linear.toCss(W, dest, linear.vendor_prefix != css.VendorPrefix{ .none = true }); }, .radial, .repeating_radial => |*radial| { try radial.toCss(W, dest); @@ -330,21 +330,21 @@ pub const Gradient = union(enum) { /// Returns the color fallback types needed for the given browser targets. pub fn getNecessaryFallbacks(this: *const @This(), targets: css.targets.Targets) css.ColorFallbackKind { - var fallbacks = css.ColorFallbackKind.empty(); + var fallbacks = css.ColorFallbackKind{}; switch (this.*) { .linear, .repeating_linear => |*linear| { for (linear.items.items) |*item| { - fallbacks = fallbacks.bitwiseOr(item.getNecessaryFallbacks(targets)); + bun.bits.insert(css.ColorFallbackKind, &fallbacks, item.getNecessaryFallbacks(targets)); } }, .radial, .repeating_radial => |*radial| { for (radial.items.items) |*item| { - fallbacks = fallbacks.bitwiseOr(item.getNecessaryFallbacks(targets)); + bun.bits.insert(css.ColorFallbackKind, &fallbacks, item.getNecessaryFallbacks(targets)); } }, .conic, .repeating_conic => |*conic| { for (conic.items.items) |*item| { - fallbacks = fallbacks.bitwiseOr(item.getNecessaryFallbacks(targets)); + bun.bits.insert(css.ColorFallbackKind, &fallbacks, item.getNecessaryFallbacks(targets)); } }, .@"webkit-gradient" => {}, @@ -363,7 +363,7 @@ pub const LinearGradient = struct { items: ArrayList(GradientItem(LengthPercentage)), pub fn parse(input: *css.Parser, vendor_prefix: VendorPrefix) Result(LinearGradient) { - const direction: LineDirection = if (input.tryParse(LineDirection.parse, .{vendor_prefix.neq(VendorPrefix{ .none = true })}).asValue()) |dir| direction: { + const direction: LineDirection = if (input.tryParse(LineDirection.parse, .{vendor_prefix != VendorPrefix{ .none = true }}).asValue()) |dir| direction: { if (input.expectComma().asErr()) |e| return .{ .err = e }; break :direction dir; } else LineDirection{ .vertical = .bottom }; @@ -1083,7 +1083,7 @@ pub fn GradientItem(comptime D: type) type { pub fn getNecessaryFallbacks(this: *const @This(), targets: css.targets.Targets) css.ColorFallbackKind { return switch (this.*) { .color_stop => |*stop| stop.color.getNecessaryFallbacks(targets), - .hint => css.ColorFallbackKind.empty(), + .hint => css.ColorFallbackKind{}, }; } }; @@ -1098,8 +1098,8 @@ pub const EndingShape = union(enum) { /// A circle. circle: Circle, - pub usingnamespace css.DeriveParse(@This()); - pub usingnamespace css.DeriveToCss(@This()); + pub const parse = css.DeriveParse(@This()).parse; + pub const toCss = css.DeriveToCss(@This()).toCss; pub fn default() EndingShape { return .{ .ellipse = .{ .extent = .@"farthest-corner" } }; diff --git a/src/css/values/ident.zig b/src/css/values/ident.zig index c86c6e3700..5b202fbbb4 100644 --- a/src/css/values/ident.zig +++ b/src/css/values/ident.zig @@ -1,6 +1,6 @@ const std = @import("std"); const Allocator = std.mem.Allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const logger = bun.logger; const Log = logger.Log; const Symbol = bun.JSAst.Symbol; diff --git a/src/css/values/image.zig b/src/css/values/image.zig index e8a5cb8844..d0c2d914e1 100644 --- a/src/css/values/image.zig +++ b/src/css/values/image.zig @@ -1,6 +1,6 @@ const std = @import("std"); const Allocator = std.mem.Allocator; -const bun = @import("root").bun; +const bun = @import("bun"); pub const css = @import("../css_parser.zig"); const Result = css.Result; const ArrayList = std.ArrayListUnmanaged; @@ -25,8 +25,8 @@ pub const Image = union(enum) { /// An `image-set()`. image_set: ImageSet, - pub usingnamespace css.DeriveParse(@This()); - pub usingnamespace css.DeriveToCss(@This()); + pub const parse = css.DeriveParse(@This()).parse; + pub const toCss = css.DeriveToCss(@This()).toCss; pub fn deinit(_: *@This(), _: std.mem.Allocator) void { // TODO: implement this @@ -68,7 +68,7 @@ pub const Image = union(enum) { pub fn hasVendorPrefix(this: *const @This()) bool { const prefix = this.getVendorPrefix(); - return !prefix.isEmpty() and !prefix.eq(VendorPrefix{ .none = true }); + return !prefix.isEmpty() and prefix != VendorPrefix{ .none = true }; } /// Returns the vendor prefix used in the image value. @@ -76,7 +76,7 @@ pub const Image = union(enum) { return switch (this.*) { .gradient => |a| a.getVendorPrefix(), .image_set => |a| a.getVendorPrefix(), - else => VendorPrefix.empty(), + else => .{}, }; } @@ -120,7 +120,7 @@ pub const Image = union(enum) { var res = css.SmallList(Image, 6){}; // Get RGB fallbacks if needed. - const rgb = if (fallbacks.contains(ColorFallbackKind.RGB)) + const rgb = if (fallbacks.rgb) this.getFallback(allocator, ColorFallbackKind.RGB) else null; @@ -129,7 +129,7 @@ pub const Image = union(enum) { const prefix_image = if (rgb) |r| &r else this; // Legacy -webkit-gradient() - if (prefixes.contains(VendorPrefix.WEBKIT) and + if (prefixes.webkit and if (targets.browsers) |browsers| css.prefixes.Feature.isWebkitGradient(browsers) else false and prefix_image.* == .gradient) { @@ -139,31 +139,31 @@ pub const Image = union(enum) { } // Standard syntax, with prefixes. - if (prefixes.contains(VendorPrefix.WEBKIT)) { + if (prefixes.webkit) { res.append(allocator, prefix_image.getPrefixed(allocator, css.VendorPrefix.WEBKIT)); } - if (prefixes.contains(VendorPrefix.MOZ)) { + if (prefixes.moz) { res.append(allocator, prefix_image.getPrefixed(allocator, css.VendorPrefix.MOZ)); } - if (prefixes.contains(VendorPrefix.O)) { + if (prefixes.o) { res.append(allocator, prefix_image.getPrefixed(allocator, css.VendorPrefix.O)); } - if (prefixes.contains(VendorPrefix.NONE)) { + if (prefixes.none) { // Unprefixed, rgb fallback. if (rgb) |r| { res.append(allocator, r); } // P3 fallback. - if (fallbacks.contains(ColorFallbackKind.P3)) { + if (fallbacks.p3) { res.append(allocator, this.getFallback(allocator, ColorFallbackKind.P3)); } // Convert original to lab if needed (e.g. if oklab is not supported but lab is). - if (fallbacks.contains(ColorFallbackKind.LAB)) { + if (fallbacks.lab) { this.* = this.getFallback(allocator, ColorFallbackKind.LAB); } } else if (res.pop()) |last| { @@ -186,7 +186,7 @@ pub const Image = union(enum) { pub fn getNecessaryFallbacks(this: *const @This(), targets: css.targets.Targets) css.ColorFallbackKind { return switch (this.*) { .gradient => |grad| grad.getNecessaryFallbacks(targets), - else => css.ColorFallbackKind.empty(), + else => css.ColorFallbackKind{}, }; } @@ -255,7 +255,7 @@ pub const ImageSet = struct { } else { try dest.delim(',', false); } - try option.toCss(W, dest, this.vendor_prefix.neq(VendorPrefix{ .none = true })); + try option.toCss(W, dest, this.vendor_prefix != VendorPrefix{ .none = true }); } return dest.writeChar(')'); } diff --git a/src/css/values/length.zig b/src/css/values/length.zig index 2983788a97..b3a4df8dae 100644 --- a/src/css/values/length.zig +++ b/src/css/values/length.zig @@ -1,6 +1,6 @@ const std = @import("std"); const Allocator = std.mem.Allocator; -const bun = @import("root").bun; +const bun = @import("bun"); pub const css = @import("../css_parser.zig"); const Result = css.Result; const ArrayList = std.ArrayListUnmanaged; @@ -19,8 +19,8 @@ pub const LengthOrNumber = union(enum) { /// A length. length: Length, - pub usingnamespace css.DeriveParse(@This()); - pub usingnamespace css.DeriveToCss(@This()); + pub const parse = css.DeriveParse(@This()).parse; + pub const toCss = css.DeriveToCss(@This()).toCss; pub fn deinit(this: *const LengthOrNumber, allocator: std.mem.Allocator) void { switch (this.*) { @@ -57,8 +57,8 @@ pub const LengthPercentageOrAuto = union(enum) { /// A [``](https://www.w3.org/TR/css-values-4/#typedef-length-percentage). length: LengthPercentage, - pub usingnamespace css.DeriveParse(@This()); - pub usingnamespace css.DeriveToCss(@This()); + pub const parse = css.DeriveParse(@This()).parse; + pub const toCss = css.DeriveToCss(@This()).toCss; pub fn isCompatible(this: *const @This(), browsers: css.targets.Browsers) bool { return switch (this.*) { diff --git a/src/css/values/number.zig b/src/css/values/number.zig index 448ccb71ad..0868f6a5d0 100644 --- a/src/css/values/number.zig +++ b/src/css/values/number.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); pub const css = @import("../css_parser.zig"); const Result = css.Result; const ArrayList = std.ArrayListUnmanaged; diff --git a/src/css/values/percentage.zig b/src/css/values/percentage.zig index da05ce2c84..b5308c3671 100644 --- a/src/css/values/percentage.zig +++ b/src/css/values/percentage.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); pub const css = @import("../css_parser.zig"); const Result = css.Result; const ArrayList = std.ArrayListUnmanaged; @@ -471,8 +471,8 @@ pub const NumberOrPercentage = union(enum) { percentage: Percentage, // TODO: implement this - pub usingnamespace css.DeriveParse(@This()); - pub usingnamespace css.DeriveToCss(@This()); + pub const parse = css.DeriveParse(@This()).parse; + pub const toCss = css.DeriveToCss(@This()).toCss; // pub fn parse(input: *css.Parser) Result(NumberOrPercentage) { // _ = input; // autofix diff --git a/src/css/values/position.zig b/src/css/values/position.zig index d01085f1ed..2e3fa34123 100644 --- a/src/css/values/position.zig +++ b/src/css/values/position.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); pub const css = @import("../css_parser.zig"); const Result = css.Result; const ArrayList = std.ArrayListUnmanaged; diff --git a/src/css/values/ratio.zig b/src/css/values/ratio.zig index 8784f898fd..5543030e26 100644 --- a/src/css/values/ratio.zig +++ b/src/css/values/ratio.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); pub const css = @import("../css_parser.zig"); const Result = css.Result; const ArrayList = std.ArrayListUnmanaged; diff --git a/src/css/values/rect.zig b/src/css/values/rect.zig index dde9986ca8..5602229aaf 100644 --- a/src/css/values/rect.zig +++ b/src/css/values/rect.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); pub const css = @import("../css_parser.zig"); const Result = css.Result; const ArrayList = std.ArrayListUnmanaged; diff --git a/src/css/values/resolution.zig b/src/css/values/resolution.zig index cfe0f081f2..16e8808020 100644 --- a/src/css/values/resolution.zig +++ b/src/css/values/resolution.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); pub const css = @import("../css_parser.zig"); const Result = css.Result; const ArrayList = std.ArrayListUnmanaged; diff --git a/src/css/values/size.zig b/src/css/values/size.zig index 8b8060c49e..128ec478c7 100644 --- a/src/css/values/size.zig +++ b/src/css/values/size.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); pub const css = @import("../css_parser.zig"); const Result = css.Result; const ArrayList = std.ArrayListUnmanaged; diff --git a/src/css/values/syntax.zig b/src/css/values/syntax.zig index ee46b209da..4673707226 100644 --- a/src/css/values/syntax.zig +++ b/src/css/values/syntax.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); pub const css = @import("../css_parser.zig"); const Result = css.Result; const ArrayList = std.ArrayListUnmanaged; diff --git a/src/css/values/time.zig b/src/css/values/time.zig index 39d5b2210a..a6ba266130 100644 --- a/src/css/values/time.zig +++ b/src/css/values/time.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); pub const css = @import("../css_parser.zig"); const Result = css.Result; const ArrayList = std.ArrayListUnmanaged; diff --git a/src/css/values/url.zig b/src/css/values/url.zig index aab52cb10b..da3619decb 100644 --- a/src/css/values/url.zig +++ b/src/css/values/url.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); pub const css = @import("../css_parser.zig"); const Result = css.Result; const ArrayList = std.ArrayListUnmanaged; diff --git a/src/css/values/values.zig b/src/css/values/values.zig index f500f14ae7..3033009b18 100644 --- a/src/css/values/values.zig +++ b/src/css/values/values.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); pub const css = @import("../css_parser.zig"); const Error = css.Error; const ArrayList = std.ArrayListUnmanaged; diff --git a/src/css_scanner.zig b/src/css_scanner.zig index 03ad54e3bb..8ef7c05352 100644 --- a/src/css_scanner.zig +++ b/src/css_scanner.zig @@ -1,6 +1,6 @@ const Fs = @import("fs.zig"); const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/src/darwin_c.zig b/src/darwin_c.zig index a64faba152..0db5b30398 100644 --- a/src/darwin_c.zig +++ b/src/darwin_c.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const builtin = @import("builtin"); const posix = std.posix; const mem = std.mem; diff --git a/src/defines-table.zig b/src/defines-table.zig index 8fdfeda58e..a67f6d3957 100644 --- a/src/defines-table.zig +++ b/src/defines-table.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/src/defines.zig b/src/defines.zig index a28ce3eedc..6926b304d1 100644 --- a/src/defines.zig +++ b/src/defines.zig @@ -4,7 +4,7 @@ const logger = bun.logger; const js_lexer = bun.js_lexer; const json_parser = bun.JSON; const fs = @import("fs.zig"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/src/deps/boringssl.translated.zig b/src/deps/boringssl.translated.zig index c65d159db0..e1a0c52660 100644 --- a/src/deps/boringssl.translated.zig +++ b/src/deps/boringssl.translated.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const C = @import("std").zig.c_builtins; const pthread_rwlock_t = if (bun.Environment.isPosix) @import("../sync.zig").RwLock.pthread_rwlock_t else *anyopaque; const time_t = C.time_t; diff --git a/src/deps/brotli_decoder.zig b/src/deps/brotli_decoder.zig index 1634931b54..c205836cd6 100644 --- a/src/deps/brotli_decoder.zig +++ b/src/deps/brotli_decoder.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const std = @import("std"); pub const brotli_alloc_func = ?*const fn (?*anyopaque, usize) callconv(.C) ?*anyopaque; diff --git a/src/deps/brotli_encoder.zig b/src/deps/brotli_encoder.zig index 5143169724..6e557f2ae4 100644 --- a/src/deps/brotli_encoder.zig +++ b/src/deps/brotli_encoder.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const std = @import("std"); pub const brotli_alloc_func = ?*const fn (?*anyopaque, usize) callconv(.C) ?*anyopaque; diff --git a/src/deps/c_ares.zig b/src/deps/c_ares.zig index 336c0e86e0..71584fac52 100644 --- a/src/deps/c_ares.zig +++ b/src/deps/c_ares.zig @@ -1,6 +1,6 @@ const c = @import("std").c; const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const strings = bun.strings; const iovec = @import("std").os.iovec; diff --git a/src/deps/diffz/DiffMatchPatch.zig b/src/deps/diffz/DiffMatchPatch.zig index 0cdcc4c585..060c0b4778 100644 --- a/src/deps/diffz/DiffMatchPatch.zig +++ b/src/deps/diffz/DiffMatchPatch.zig @@ -23,7 +23,7 @@ const DiffMatchPatch = @This(); const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const testing = std.testing; const ArrayListUnmanaged = std.ArrayListUnmanaged; const DiffList = ArrayListUnmanaged(Diff); diff --git a/src/deps/libdeflate.zig b/src/deps/libdeflate.zig index d38d6dcb9f..aa3261db53 100644 --- a/src/deps/libdeflate.zig +++ b/src/deps/libdeflate.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); pub const Options = extern struct { sizeof_options: usize = @sizeOf(Options), malloc_func: ?*const fn (usize) callconv(.C) ?*anyopaque = @import("std").mem.zeroes(?*const fn (usize) callconv(.C) ?*anyopaque), diff --git a/src/deps/libuv.zig b/src/deps/libuv.zig index 9f534148ef..3149b3d45b 100644 --- a/src/deps/libuv.zig +++ b/src/deps/libuv.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const Maybe = bun.JSC.Maybe; const WORD = c_ushort; @@ -459,7 +459,7 @@ fn HandleMixin(comptime Type: type) type { if (fd_ == windows.INVALID_HANDLE_VALUE) return bun.invalid_fd; - return bun.FDImpl.fromSystem(fd_).encode(); + return .fromNative(fd_); } }; } @@ -1324,7 +1324,7 @@ pub const Pipe = extern struct { } pub fn open(this: *Pipe, file: bun.FileDescriptor) Maybe(void) { - const uv_fd = bun.uvfdcast(file); + const uv_fd = file.uv(); if (uv_pipe_open(this, uv_fd).toError(.open)) |err| return .{ .err = err }; return .{ .result = {} }; @@ -2327,8 +2327,6 @@ pub extern fn uv_get_process_title(buffer: [*]u8, size: usize) c_int; pub extern fn uv_set_process_title(title: [*]const u8) c_int; pub extern fn uv_resident_set_memory(rss: [*c]usize) c_int; pub extern fn uv_uptime(uptime: [*c]f64) c_int; -pub extern fn uv_get_osfhandle(fd: c_int) uv_os_fd_t; -pub extern fn uv_open_osfhandle(os_fd: uv_os_fd_t) c_int; pub const uv_rusage_t = extern struct { ru_utime: uv_timeval_t, ru_stime: uv_timeval_t, @@ -2834,7 +2832,7 @@ pub const ReturnCodeI64 = enum(i64) { } pub fn toFD(this: ReturnCodeI64) bun.FileDescriptor { - return bun.toFD(@as(i32, @truncate(this.int()))); + return .fromUV(@truncate(this.int())); } }; diff --git a/src/deps/lol-html.zig b/src/deps/lol-html.zig index 3552fe6218..d011db105f 100644 --- a/src/deps/lol-html.zig +++ b/src/deps/lol-html.zig @@ -1,6 +1,6 @@ pub const Error = error{Fail}; const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); pub const MemorySettings = extern struct { preallocated_parsing_buffer_size: usize, max_allowed_memory_usage: usize, diff --git a/src/deps/picohttp.zig b/src/deps/picohttp.zig index 39896dc8cd..dc0b6ce904 100644 --- a/src/deps/picohttp.zig +++ b/src/deps/picohttp.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const c = @import("picohttpparser.zig"); const ExactSizeMatcher = bun.ExactSizeMatcher; const Match = ExactSizeMatcher(2); diff --git a/src/deps/uws.zig b/src/deps/uws.zig index cf992ec6d6..cf8433e1da 100644 --- a/src/deps/uws.zig +++ b/src/deps/uws.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const std = @import("std"); const Environment = bun.Environment; pub const LIBUS_LISTEN_DEFAULT: i32 = 0; @@ -1489,11 +1489,11 @@ pub fn NewSocketHandler(comptime is_ssl: bool) type { } const socket = this.socket.get() orelse return bun.invalid_fd; + // on windows uSockets exposes SOCKET return if (comptime Environment.isWindows) - // on windows uSockets exposes SOCKET - bun.toFD(@as(bun.FDImpl.System, @ptrCast(socket.getNativeHandle(is_ssl).?))) + .fromNative(@ptrCast(socket.getNativeHandle(is_ssl).?)) else - bun.toFD(@as(i32, @intCast(@intFromPtr(socket.getNativeHandle(is_ssl))))); + .fromNative(@intCast(@intFromPtr(socket.getNativeHandle(is_ssl)))); } pub fn markNeedsMoreForSendfile(this: ThisSocket) void { @@ -1763,7 +1763,7 @@ pub fn NewSocketHandler(comptime is_ssl: bool) type { this: *This, comptime socket_field_name: ?[]const u8, ) ?ThisSocket { - const socket_ = ThisSocket{ .socket = .{ .connected = us_socket_from_fd(ctx, @sizeOf(*anyopaque), bun.socketcast(handle)) orelse return null } }; + const socket_ = ThisSocket{ .socket = .{ .connected = us_socket_from_fd(ctx, @sizeOf(*anyopaque), handle.asSocketFd()) orelse return null } }; if (socket_.ext(*anyopaque)) |holder| { holder.* = this; @@ -3653,10 +3653,10 @@ pub fn NewApp(comptime ssl: bool) type { pub fn getNativeHandle(res: *Response) bun.FileDescriptor { if (comptime Environment.isWindows) { // on windows uSockets exposes SOCKET - return bun.toFD(@as(bun.FDImpl.System, @ptrCast(uws_res_get_native_handle(ssl_flag, res.downcast())))); + return .fromNative(@ptrCast(uws_res_get_native_handle(ssl_flag, res.downcast()))); } - return bun.toFD(@as(i32, @intCast(@intFromPtr(uws_res_get_native_handle(ssl_flag, res.downcast()))))); + return .fromNative(@intCast(@intFromPtr(uws_res_get_native_handle(ssl_flag, res.downcast())))); } pub fn getRemoteAddressAsText(res: *Response) ?[]const u8 { var buf: [*]const u8 = undefined; diff --git a/src/deps/uws/socket.zig b/src/deps/uws/socket.zig index a319a14f99..cda69d45c1 100644 --- a/src/deps/uws/socket.zig +++ b/src/deps/uws/socket.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const uws = @import("../uws.zig"); const SocketContext = uws.SocketContext; diff --git a/src/deps/zig-clap/clap.zig b/src/deps/zig-clap/clap.zig index f814f62926..1f5704274d 100644 --- a/src/deps/zig-clap/clap.zig +++ b/src/deps/zig-clap/clap.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const debug = std.debug; const heap = std.heap; diff --git a/src/deps/zig-clap/clap/args.zig b/src/deps/zig-clap/clap/args.zig index aba747eb5e..0ac4a4f748 100644 --- a/src/deps/zig-clap/clap/args.zig +++ b/src/deps/zig-clap/clap/args.zig @@ -43,7 +43,7 @@ test "SliceIterator" { } } -const bun = @import("root").bun; +const bun = @import("bun"); /// An argument iterator which wraps the ArgIterator in ::std. /// On windows, this iterator allocates. pub const OsIterator = struct { diff --git a/src/deps/zig-clap/clap/comptime.zig b/src/deps/zig-clap/clap/comptime.zig index cbd920952b..e95ddafd2e 100644 --- a/src/deps/zig-clap/clap/comptime.zig +++ b/src/deps/zig-clap/clap/comptime.zig @@ -1,5 +1,5 @@ const clap = @import("../clap.zig"); -const bun = @import("root").bun; +const bun = @import("bun"); const std = @import("std"); const debug = std.debug; diff --git a/src/deps/zig-clap/clap/streaming.zig b/src/deps/zig-clap/clap/streaming.zig index e861325a7e..5aca708f29 100644 --- a/src/deps/zig-clap/clap/streaming.zig +++ b/src/deps/zig-clap/clap/streaming.zig @@ -1,7 +1,7 @@ const builtin = @import("builtin"); const clap = @import("../clap.zig"); const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Output = bun.Output; const args = clap.args; diff --git a/src/deps/zstd.zig b/src/deps/zstd.zig index 0cc0291292..fdaa1ec7ed 100644 --- a/src/deps/zstd.zig +++ b/src/deps/zstd.zig @@ -224,4 +224,4 @@ pub const Result = union(enum) { err: [:0]const u8, }; -const bun = @import("root").bun; +const bun = @import("bun"); diff --git a/src/dir.zig b/src/dir.zig index c8580046b1..3b2de9841b 100644 --- a/src/dir.zig +++ b/src/dir.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const std = @import("std"); const builtin = @import("builtin"); diff --git a/src/dns.zig b/src/dns.zig index 6986767bfc..dc8cc51606 100644 --- a/src/dns.zig +++ b/src/dns.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const std = @import("std"); const JSC = bun.JSC; const JSValue = JSC.JSValue; diff --git a/src/env.zig b/src/env.zig index 986259f9bf..f6fa1d55c1 100644 --- a/src/env.zig +++ b/src/env.zig @@ -1,6 +1,6 @@ const std = @import("std"); const builtin = @import("builtin"); -const bun = @import("root").bun; +const bun = @import("bun"); pub const BuildTarget = enum { native, wasm, wasi }; pub const build_target: BuildTarget = brk: { diff --git a/src/env_loader.zig b/src/env_loader.zig index e4a1f15b6b..47453b9c88 100644 --- a/src/env_loader.zig +++ b/src/env_loader.zig @@ -1,6 +1,6 @@ const std = @import("std"); const logger = bun.logger; -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/src/exact_size_matcher.zig b/src/exact_size_matcher.zig index 607b5ce589..693a4ad87b 100644 --- a/src/exact_size_matcher.zig +++ b/src/exact_size_matcher.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); pub fn ExactSizeMatcher(comptime max_bytes: usize) type { switch (max_bytes) { diff --git a/src/fd.zig b/src/fd.zig index 6ee1fd9f2e..cf40557487 100644 --- a/src/fd.zig +++ b/src/fd.zig @@ -1,30 +1,616 @@ -const std = @import("std"); -const posix = std.posix; +const backing_int = if (is_posix) c_int else u64; +const WindowsHandleNumber = u63; +const HandleNumber = if (is_posix) c_int else WindowsHandleNumber; +/// Abstraction over file descriptors. On POSIX, fd is a wrapper around a "fd_t", +/// and there is no special behavior. In return for using fd, you get access to +/// a 'close' method, and a handful of decl literals like '.cwd()' and '.stdin()'. +/// +/// On Windows, a tag differentiates two sources: +/// - system: A "std.os.windows.HANDLE" that windows APIs can interact with. +/// In fd case it is actually just an "*anyopaque" that points to some windows internals. +/// - uv: A c-runtime file descriptor that looks like a linux file descriptor. +/// ("uv", "uv_file", "c runtime file descriptor", "crt fd" are interchangeable terms) +/// +/// When a Windows HANDLE is converted to a UV descriptor, it +/// becomes owned by the C runtime, in which it can only be properly freed by +/// closing it. fd is problematic because it means that calling a libuv +/// function with a windows handle is impossible since the conversion will +/// make it impossible for the caller to close it. In these siutations, +/// the descriptor must be converted much higher up in the call stack. +pub const FD = packed struct(backing_int) { + value: Value, + kind: Kind, + pub const Kind = if (is_posix) + enum(u0) { system } + else + enum(u1) { system = 0, uv = 1 }; + pub const Value = if (is_posix) + packed union { as_system: fd_t } + else + packed union { as_system: WindowsHandleNumber, as_uv: uv_file }; -const bun = @import("root").bun; -const environment = bun.Environment; -const JSC = bun.JSC; -const JSValue = JSC.JSValue; -const libuv = bun.windows.libuv; + /// An invalid file descriptor. + /// Avoid in new code. Prefer `bun.FD.Optional` and `.none` instead. + pub const invalid: FD = .{ .kind = .system, .value = .{ .as_system = invalid_value } }; + const invalid_value = std.math.minInt(@FieldType(Value, "as_system")); -const allow_assert = environment.allow_assert; + // NOTE: there is no universal anytype init function. please annotate at each + // call site the source of the file descriptor you are initializing. with + // heavy decl literal usage, it can be confusing if you just see `.from()`, + // especially since numerical values have very subtle differences on Windows. -const log = bun.sys.syslog; -fn handleToNumber(handle: FDImpl.System) FDImpl.SystemAsInt { - if (environment.os == .windows) { + /// Initialize using the native system handle + pub fn fromNative(value: fd_t) FD { + if (os == .windows) { + // the current process fd is max usize + // https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getcurrentprocess + bun.assert(@intFromPtr(value) <= std.math.maxInt(u63)); + } + return .{ .kind = .system, .value = .{ .as_system = handleToNumber(value) } }; + } + pub const fromSystem = fromNative; + + /// Initialize using the c-runtime / libuv file descriptor + pub fn fromUV(value: uv_file) FD { + return if (is_posix) + .{ .kind = .system, .value = .{ .as_system = value } } + else + .{ .kind = .uv, .value = .{ .as_uv = value } }; + } + + pub fn cwd() FD { + return .fromNative(std.fs.cwd().fd); + } + + pub fn stdin() FD { + if (os != .windows) return .fromUV(0); + const in_comptime = @inComptime(); + comptime assert(!in_comptime); // windows std handles are not known at build time + return windows_cached_stdin; + } + + pub fn stdout() FD { + if (os != .windows) return .fromUV(1); + const in_comptime = @inComptime(); + comptime assert(!in_comptime); // windows std handles are not known at build time + return windows_cached_stdout; + } + + pub fn stderr() FD { + if (os != .windows) return .fromUV(2); + const in_comptime = @inComptime(); + comptime assert(!in_comptime); // windows std handles are not known at build time + return windows_cached_stderr; + } + + pub fn fromStdFile(file: std.fs.File) FD { + return .fromNative(file.handle); + } + + pub fn fromStdDir(dir: std.fs.Dir) FD { + return .fromNative(dir.fd); + } + + pub fn stdFile(fd: FD) std.fs.File { + return .{ .handle = fd.native() }; + } + + pub fn stdDir(fd: FD) std.fs.Dir { + return .{ .fd = fd.native() }; + } + + /// Perform different logic for each kind of windows file descriptor + pub fn decodeWindows(fd: FD) DecodeWindows { + return switch (fd.kind) { + .system => .{ .windows = numberToHandle(fd.value.as_system) }, + .uv => .{ .uv = fd.value.as_uv }, + }; + } + + pub fn isValid(fd: FD) bool { + return switch (os) { + else => fd.value.as_system != invalid_value, + .windows => switch (fd.kind) { + .system => fd.value.as_system != invalid_value, + .uv => true, + }, + }; + } + pub fn unwrapValid(fd: FD) ?FD { + return if (fd.isValid()) fd else null; + } + + /// When calling fd function, you may not be able to close the returned fd. + /// To close the fd, you have to call `.close()` on the `bun.FD`. + pub fn native(fd: FD) fd_t { + if (Environment.isDebug and !@inComptime()) bun.assert(fd.isValid()); + return switch (os) { + else => fd.value.as_system, + .windows => switch (fd.decodeWindows()) { + .windows => |handle| handle, + .uv => |file_number| uv_get_osfhandle(file_number), + }, + }; + } + /// Deprecated: renamed to `native` because it is unclear what `cast` would cast to. + pub const cast = native; + + /// When calling fd function, you should consider the FD struct to now be + /// invalid. Calling `.close()` on the FD at that point may not work. + pub fn uv(fd: FD) uv_file { + return switch (os) { + else => fd.value.as_system, + .windows => switch (fd.decodeWindows()) { + .windows => |handle| { + if (isStdioHandle(std.os.windows.STD_INPUT_HANDLE, handle)) return 0; + if (isStdioHandle(std.os.windows.STD_OUTPUT_HANDLE, handle)) return 1; + if (isStdioHandle(std.os.windows.STD_ERROR_HANDLE, handle)) return 2; + std.debug.panic( + \\Cast bun.FD.uv({}) makes closing impossible! + \\ + \\The supplier of fd FD should call 'FD.makeLibUVOwned', + \\probably where open() was called. + , + .{fd}, + ); + }, + .uv => fd.value.as_uv, + }, + }; + } + + pub fn asSocketFd(fd: FD) std.posix.socket_t { + return switch (os) { + .windows => @ptrCast(fd.native()), + else => fd.native(), + }; + } + + /// Assumes given a valid file descriptor + /// If error, the handle has not been closed + pub fn makeLibUVOwned(fd: FD) !FD { + if (allow_assert) bun.assert(fd.isValid()); + return switch (os) { + else => fd, + .windows => switch (fd.kind) { + .system => fd: { + break :fd FD.fromUV(try uv_open_osfhandle(numberToHandle(fd.value.as_system))); + }, + .uv => fd, + }, + }; + } + pub fn makeLibUVOwnedForSyscall( + maybe_windows_fd: bun.FileDescriptor, + comptime syscall_tag: bun.sys.Tag, + comptime error_case: enum { close_on_fail, leak_fd_on_fail }, + ) bun.sys.Maybe(bun.FileDescriptor) { + if (os != .windows) { + return .{ .result = maybe_windows_fd }; + } + return .{ .result = maybe_windows_fd.makeLibUVOwned() catch |err| switch (err) { + error.SystemFdQuotaExceeded => { + if (error_case == .close_on_fail) { + maybe_windows_fd.close(); + } + return .{ .err = .{ + .errno = @intFromEnum(bun.C.E.MFILE), + .syscall = syscall_tag, + } }; + }, + } }; + } + + /// fd function will NOT CLOSE stdin/stdout/stderr. + /// Expects a VALID file descriptor object. + /// + /// Do not use fd on JS-provided file descriptors (e.g. in + /// `fs.closeSync`). For those cases, the developer may provide a faulty + /// value, and we must forward EBADF to them. For internal situations, we + /// should never hit EBADF since it means we could have replaced the file + /// descriptor, closing something completely unrelated; fd would cause + /// weird behavior as you see EBADF errors in unrelated places. + /// + /// One day, we can add code to track file descriptor allocations and frees. + /// In debug, fd assertion failure can print where the FD was actually + /// closed. + pub fn close(fd: FD) void { + bun.debugAssert(fd.closeAllowingBadFileDescriptor(@returnAddress()) == null); // use after close! + } + + /// fd function will NOT CLOSE stdin/stdout/stderr. + /// + /// Use fd API to implement `node:fs` close. + /// Prefer asserting that EBADF does not happen with `.close()` + pub fn closeAllowingBadFileDescriptor(fd: FD, return_address: ?usize) ?bun.sys.Error { + if (fd.stdioTag() != null) { + log("close({}) SKIPPED", .{fd}); + return null; + } + return fd.closeAllowingStandardIo(return_address orelse @returnAddress()); + } + + /// fd allows you to close standard io. It also returns the error. + /// Consider fd the raw close method. + pub fn closeAllowingStandardIo(fd: FD, return_address: ?usize) ?bun.sys.Error { + if (allow_assert) bun.assert(fd.isValid()); // probably a UAF + + // Format the file descriptor for logging BEFORE closing it. + // Otherwise the file descriptor is always invalid after closing it. + var buf: if (Environment.isDebug) [1050]u8 else void = undefined; + const fd_fmt = if (Environment.isDebug) std.fmt.bufPrint(&buf, "{}", .{fd}) catch buf[0..]; + + const result: ?bun.sys.Error = switch (os) { + .linux => result: { + bun.assert(fd.native() >= 0); + break :result switch (bun.C.getErrno(bun.sys.syscall.close(fd.native()))) { + .BADF => .{ .errno = @intFromEnum(E.BADF), .syscall = .close, .fd = fd }, + else => null, + }; + }, + .mac => result: { + bun.assert(fd.native() >= 0); + break :result switch (bun.C.getErrno(bun.sys.syscall.@"close$NOCANCEL"(fd.native()))) { + .BADF => .{ .errno = @intFromEnum(E.BADF), .syscall = .close, .fd = fd }, + else => null, + }; + }, + .windows => switch (fd.decodeWindows()) { + .uv => |file_number| result: { + var req: libuv.fs_t = libuv.fs_t.uninitialized; + defer req.deinit(); + const rc = libuv.uv_fs_close(libuv.Loop.get(), &req, file_number, null); + break :result if (rc.errno()) |errno| + .{ .errno = errno, .syscall = .close, .fd = fd, .from_libuv = true } + else + null; + }, + .windows => |handle| result: { + break :result switch (bun.windows.NtClose(handle)) { + .SUCCESS => null, + else => |rc| bun.sys.Error{ + .errno = if (bun.windows.Win32Error.fromNTStatus(rc).toSystemErrno()) |errno| @intFromEnum(errno) else 1, + .syscall = .CloseHandle, + .fd = fd, + }, + }; + }, + }, + else => @compileError("FD.close() not implemented for fd platform"), + }; + if (Environment.isDebug) { + if (result) |err| { + if (err.errno == @intFromEnum(E.BADF)) { + bun.Output.debugWarn("close({s}) = EBADF. This is an indication of a file descriptor UAF", .{fd_fmt}); + bun.crash_handler.dumpCurrentStackTrace(return_address orelse @returnAddress(), .{ .frame_count = 4, .stop_at_jsc_llint = true }); + } else { + log("close({s}) = {}", .{ fd_fmt, err }); + } + } else { + log("close({s})", .{fd_fmt}); + } + } + return result; + } + + /// fd "fails" if not given an int32, returning null in that case + pub fn fromJS(value: JSValue) ?FD { + if (!value.isAnyInt()) return null; + const fd64 = value.toInt64(); + if (fd64 < 0 or fd64 > std.math.maxInt(i32)) { + return null; + } + const fd: i32 = @intCast(fd64); + if (os == .windows) { + return switch (fd) { + 0 => .stdin(), + 1 => .stdout(), + 2 => .stderr(), + else => .fromUV(fd), + }; + } + return .fromUV(fd); + } + // If a non-number is given, returns null. + // If the given number is not an fd (negative), an error is thrown and error.JSException is returned. + pub fn fromJSValidated(value: JSValue, global: *JSC.JSGlobalObject) bun.JSError!?FD { + if (!value.isNumber()) + return null; + const float = value.asNumber(); + if (@mod(float, 1) != 0) { + return global.throwRangeError(float, .{ .field_name = "fd", .msg = "an integer" }); + } + const int: i64 = @intFromFloat(float); + if (int < 0 or int > std.math.maxInt(i32)) { + return global.throwRangeError(int, .{ .field_name = "fd", .min = 0, .max = std.math.maxInt(i32) }); + } + const fd: c_int = @intCast(int); + if (os == .windows) { + if (Stdio.fromInt(fd)) |stdio| { + return stdio.fd(); + } + } + return .fromUV(fd); + } + /// After calling, the input file descriptor is no longer valid and must not be used. + /// If an error is thrown, the file descriptor is cleaned up for you. + pub fn toJS(any_fd: FD, global: *JSC.JSGlobalObject) JSValue { + const uv_owned_fd = any_fd.makeLibUVOwned() catch { + any_fd.close(); + return global.throwValue((JSC.SystemError{ + .message = bun.String.static("EMFILE, too many open files"), + .code = bun.String.static("EMFILE"), + }).toErrorInstance(global)) catch .zero; + }; + return JSValue.jsNumberFromInt32(uv_owned_fd.uv()); + } + + pub const Stdio = enum(u8) { + std_in = 0, + std_out = 1, + std_err = 2, + pub fn fd(tag: Stdio) FD { + return switch (tag) { + .std_in => .stdin(), + .std_out => .stdout(), + .std_err => .stderr(), + }; + } + pub fn fromInt(value: i32) ?Stdio { + if (value < 0 or value > 2) return null; + return @enumFromInt(value); + } + pub fn toInt(tag: Stdio) i32 { + return @intFromEnum(tag); + } + }; + pub fn stdioTag(fd: FD) ?Stdio { + return if (os == .windows) switch (fd.decodeWindows()) { + .windows => |handle| { + const process = std.os.windows.peb().ProcessParameters; + if (handle == process.hStdInput) { + return .std_in; + } else if (handle == process.hStdOutput) { + return .std_out; + } else if (handle == process.hStdError) { + return .std_err; + } + return null; + }, + .uv => |file_number| switch (file_number) { + 0 => .std_in, + 1 => .std_out, + 2 => .std_err, + else => null, + }, + } else switch (fd.value.as_system) { + 0 => .std_in, + 1 => .std_out, + 2 => .std_err, + else => null, + }; + } + + pub const HashMapContext = struct { + pub fn hash(_: @This(), fd: FD) u64 { + // a file descriptor is i32 on linux, u64 on windows + // the goal here is to do zero work and widen the 32 bit type to 64 + return @as(if (os == .windows) u64 else u32, @bitCast(fd)); + } + + pub fn eql(_: @This(), a: FD, b: FD) bool { + return a == b; + } + + pub fn pre(input: FD) Prehashed { + return Prehashed{ + .value = hash(.{}, input), + .input = input, + }; + } + + pub const Prehashed = struct { + value: u64, + input: FD, + + pub fn hash(ctx: @This(), fd: FD) u64 { + if (fd == ctx.input) return ctx.value; + return fd; + } + + pub fn eql(_: @This(), a: FD, b: FD) bool { + return a == b; + } + }; + }; + + pub fn format(fd: FD, comptime fmt: []const u8, _: std.fmt.FormatOptions, writer: anytype) !void { + if (!fd.isValid()) { + try writer.writeAll("[invalid_fd]"); + return; + } + + if (fmt.len != 0) { + // The reason for fd error is because formatting FD as an integer on windows is + // ambiguous and almost certainly a mistake. You probably meant to format fd.cast(). + // + // Remember fd formatter will + // - on posix, print the number + // - on windows, print if it is a handle or a libuv file descriptor + // - in debug on all platforms, print the path of the file descriptor + // + // Not having fd error caused a linux+debug only crash in bun.sys.getFdPath because + // we forgot to change the thing being printed to "fd.native()" when the FD was introduced. + @compileError("invalid format string for bun.FD.format. must be empty like '{}'"); + } + + switch (os) { + else => { + const fd_native = fd.native(); + try writer.print("{d}", .{fd_native}); + if (Environment.isDebug and fd_native >= 3) print_with_path: { + var path_buf: bun.PathBuffer = undefined; + // NOTE: Bun's `fd.getFdPath`, while supporting some + // situations the standard library does not, hits EINVAL + // instead of gracefully handling invalid file descriptors. + // It is assumed that debug builds are ran on systems that + // support the standard library functions (since they would + // likely have run the Zig compiler, and it's not the end of + // the world if this fails. + const path = std.os.getFdPath(fd_native, &path_buf) catch |err| switch (err) { + error.FileNotFound => { + try writer.writeAll("[BADF]"); + break :print_with_path; + }, + else => |e| { + try writer.print("[unknown: error.{s}]", .{@errorName(e)}); + break :print_with_path; + }, + }; + try writer.print("[{s}]", .{path}); + } + }, + .windows => switch (fd.decodeWindows()) { + .windows => |handle| { + if (Environment.isDebug) { + const peb = std.os.windows.peb(); + if (handle == peb.ProcessParameters.hStdInput) { + return try writer.print("{d}[stdin handle]", .{fd.value.as_system}); + } else if (handle == peb.ProcessParameters.hStdOutput) { + return try writer.print("{d}[stdout handle]", .{fd.value.as_system}); + } else if (handle == peb.ProcessParameters.hStdError) { + return try writer.print("{d}[stderr handle]", .{fd.value.as_system}); + } else if (handle == peb.ProcessParameters.CurrentDirectory.Handle) { + return try writer.print("{d}[cwd handle]", .{fd.value.as_system}); + } else print_with_path: { + var fd_path: bun.WPathBuffer = undefined; + const path = std.os.windows.GetFinalPathNameByHandle(handle, .{ .volume_name = .Nt }, &fd_path) catch break :print_with_path; + return try writer.print("{d}[{}]", .{ + fd.value.as_system, + bun.fmt.utf16(path), + }); + } + } + try writer.print("{d}[handle]", .{fd.value.as_system}); + }, + .uv => |file_number| try writer.print("{d}[libuv]", .{file_number}), + }, + } + } + + pub const DecodeWindows = union(enum) { + windows: HANDLE, + uv: uv_file, + }; + + /// Note that currently FD can encode the invalid file descriptor value. + /// Obviously, prefer fd instead of that. + pub const Optional = enum(backing_int) { + none = @bitCast(invalid), + _, + pub fn init(maybe: ?FD) Optional { + return if (maybe) |fd| fd.toOptional() else .none; + } + pub fn close(optional: Optional) void { + if (optional.unwrap()) |fd| + fd.close(); + } + pub fn unwrap(optional: Optional) ?FD { + return if (optional == .none) null else @bitCast(@intFromEnum(optional)); + } + pub fn take(optional: *Optional) ?FD { + defer optional.* = .none; + return optional.unwrap(); + } + }; + /// Properly converts FD.invalid into FD.Optional.none + pub fn toOptional(fd: FD) Optional { + return @enumFromInt(@as(backing_int, @bitCast(fd))); + } + + // The following functions are from bun.sys but with the 'f' prefix dropped + // where it is relevant. These functions all take FD as the first argument, + // so that makes them Zig methods, even when declared in a separate file. + pub const chmod = bun.sys.fchmod; + pub const chmodat = bun.sys.fchmodat; + pub const chown = bun.sys.fchown; + pub const directoryExistsAt = bun.sys.directoryExistsAt; + pub const dup = bun.sys.dup; + pub const dupWithFlags = bun.sys.dupWithFlags; + pub const existsAt = bun.sys.existsAt; + pub const existsAtType = bun.sys.existsAtType; + pub const fcntl = bun.sys.fcntl; + pub const getFcntlFlags = bun.sys.getFcntlFlags; + pub const getFileSize = bun.sys.getFileSize; + pub const linkat = bun.sys.linkat; + pub const linkatTmpfile = bun.sys.linkatTmpfile; + pub const lseek = bun.sys.lseek; + pub const mkdirat = bun.sys.mkdirat; + pub const mkdiratA = bun.sys.mkdiratA; + pub const mkdiratW = bun.sys.mkdiratW; + pub const mkdiratZ = bun.sys.mkdiratZ; + pub const openat = bun.sys.openat; + pub const pread = bun.sys.pread; + pub const preadv = bun.sys.preadv; + pub const pwrite = bun.sys.pwrite; + pub const pwritev = bun.sys.pwritev; + pub const read = bun.sys.read; + pub const readNonblocking = bun.sys.readNonblocking; + pub const readlinkat = bun.sys.readlinkat; + pub const readv = bun.sys.readv; + pub const recv = bun.sys.recv; + pub const recvNonBlock = bun.sys.recvNonBlock; + pub const renameat = bun.sys.renameat; + pub const renameat2 = bun.sys.renameat2; + pub const send = bun.sys.send; + pub const sendNonBlock = bun.sys.sendNonBlock; + pub const sendfile = bun.sys.sendfile; + pub const stat = bun.sys.fstat; + pub const statat = bun.sys.fstatat; + pub const symlinkat = bun.sys.symlinkat; + pub const truncate = bun.sys.ftruncate; + pub const unlinkat = bun.sys.unlinkat; + pub const updateNonblocking = bun.sys.updateNonblocking; + pub const write = bun.sys.write; + pub const writeNonblocking = bun.sys.writeNonblocking; + pub const writev = bun.sys.writev; + + pub const getFdPath = bun.getFdPath; + pub const getFdPathW = bun.getFdPathW; + pub const getFdPathZ = bun.getFdPathZ; + + // TODO: move these methods defined in bun.sys.File to bun.sys. follow + // similar pattern as above. then delete bun.sys.File + pub fn quietWriter(fd: FD) bun.sys.File.QuietWriter { + return .{ .context = .{ .handle = fd } }; + } + + comptime { + if (os == .windows) { + // The conversion from FD to fd_t should be an integer truncate + bun.assert(@as(FD, @bitCast(@as(u64, 512))).value.as_system == 512); + } + } +}; + +fn isStdioHandle(id: std.os.windows.DWORD, handle: HANDLE) bool { + const h = std.os.windows.GetStdHandle(id) catch return false; + return handle == h; +} + +fn handleToNumber(handle: fd_t) HandleNumber { + if (is_posix) { + return handle; + } else { // intCast fails if 'fd > 2^62' // possible with handleToNumber(GetCurrentProcess()); return @intCast(@intFromPtr(handle)); - } else { - return handle; } } -fn numberToHandle(handle: FDImpl.SystemAsInt) FDImpl.System { - if (environment.os == .windows) { - if (!@inComptime()) { - bun.assert(handle != FDImpl.invalid_value); - } +fn numberToHandle(handle: HandleNumber) fd_t { + if (os == .windows) { + if (handle == 0) return std.os.windows.INVALID_HANDLE_VALUE; return @ptrFromInt(handle); } else { return handle; @@ -32,396 +618,43 @@ fn numberToHandle(handle: FDImpl.SystemAsInt) FDImpl.System { } pub fn uv_get_osfhandle(in: c_int) libuv.uv_os_fd_t { - const out = libuv.uv_get_osfhandle(in); + const out = libuv_private.uv_get_osfhandle(in); return out; } pub fn uv_open_osfhandle(in: libuv.uv_os_fd_t) error{SystemFdQuotaExceeded}!c_int { - const out = libuv.uv_open_osfhandle(in); + const out = libuv_private.uv_open_osfhandle(in); bun.assert(out >= -1); if (out == -1) return error.SystemFdQuotaExceeded; return out; } -/// Abstraction over file descriptors. This struct does nothing on non-windows operating systems. -/// -/// bun.FileDescriptor is the bitcast of this struct, which is essentially a tagged pointer. -/// -/// You can acquire one with FDImpl.decode(fd), and convert back to it with FDImpl.encode(fd). -/// -/// On Windows builds we have two kinds of file descriptors: -/// - system: A "std.os.windows.HANDLE" that windows APIs can interact with. -/// In this case it is actually just an "*anyopaque" that points to some windows internals. -/// - uv: A libuv file descriptor that looks like a linux file descriptor. -/// (technically a c runtime file descriptor, libuv might do extra stuff though) -/// -/// When converting UVFDs into Windows FDs, they are still said to be owned by libuv, -/// and they say to NOT close the handle. -pub const FDImpl = packed struct { - value: Value, - kind: Kind, +pub var windows_cached_fd_set: if (Environment.isDebug) bool else void = if (Environment.isDebug) false; +pub var windows_cached_stdin: FD = undefined; +pub var windows_cached_stdout: FD = undefined; +pub var windows_cached_stderr: FD = undefined; - const invalid_value = std.math.maxInt(SystemAsInt); - pub const invalid = FDImpl{ - .kind = .system, - .value = .{ .as_system = invalid_value }, - }; +const fd_t = std.posix.fd_t; +const HANDLE = bun.windows.HANDLE; +const uv_file = bun.windows.libuv.uv_file; +const assert = bun.assert; +const E = std.posix.E; - pub const System = posix.fd_t; +const bun = @import("bun"); - pub const SystemAsInt = switch (environment.os) { - .windows => u63, - else => System, - }; +const Environment = bun.Environment; +const is_posix = Environment.isPosix; +const os = Environment.os; - pub const UV = switch (environment.os) { - .windows => bun.windows.libuv.uv_file, - else => System, - }; +const std = @import("std"); - pub const Value = if (environment.os == .windows) - packed union { as_system: SystemAsInt, as_uv: UV } - else - packed union { as_system: SystemAsInt }; - - pub const Kind = if (environment.os == .windows) - enum(u1) { system = 0, uv = 1 } - else - enum(u0) { system }; - - comptime { - bun.assert(@sizeOf(FDImpl) == @sizeOf(System)); - - if (environment.os == .windows) { - // we want the conversion from FD to fd_t to be a integer truncate - bun.assert(@as(FDImpl, @bitCast(@as(u64, 512))).value.as_system == 512); - } - } - - pub fn fromSystemWithoutAssertion(system_fd: System) FDImpl { - return FDImpl{ - .kind = .system, - .value = .{ .as_system = handleToNumber(system_fd) }, - }; - } - - pub fn fromSystem(system_fd: System) FDImpl { - if (environment.os == .windows) { - // the current process fd is max usize - // https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getcurrentprocess - if (@intFromPtr(system_fd) > std.math.maxInt(SystemAsInt)) { - bun.Output.panic( - \\FDImpl.fromSystem() called with a fd that is too large: 0x{x} - , - .{@intFromPtr(system_fd)}, - ); - return invalid; - } - } - - return fromSystemWithoutAssertion(system_fd); - } - - pub fn fromUV(uv_fd: UV) FDImpl { - return switch (environment.os) { - else => FDImpl{ - .kind = .system, - .value = .{ .as_system = uv_fd }, - }, - .windows => FDImpl{ - .kind = .uv, - .value = .{ .as_uv = uv_fd }, - }, - }; - } - - pub fn isValid(this: FDImpl) bool { - return switch (environment.os) { - // the 'zero' value on posix is debatable. it can be standard in. - // TODO(@paperclover): steamroll away every use of bun.FileDescriptor.zero - else => this.value.as_system != invalid_value, - .windows => switch (this.kind) { - // zero is not allowed in addition to the invalid value (zero would be a null ptr) - .system => this.value.as_system != invalid_value and this.value.as_system != 0, - // the libuv tag is always fine - .uv => true, - }, - }; - } - - /// When calling this function, you may not be able to close the returned fd. - /// To close the fd, you have to call `.close()` on the FD. - pub fn system(this: FDImpl) System { - return switch (environment.os == .windows) { - false => numberToHandle(this.value.as_system), - true => switch (this.kind) { - .system => numberToHandle(this.value.as_system), - .uv => uv_get_osfhandle(this.value.as_uv), - }, - }; - } - - /// Convert to bun.FileDescriptor - pub fn encode(this: FDImpl) bun.FileDescriptor { - // https://github.com/ziglang/zig/issues/18462 - return @enumFromInt(@as(bun.FileDescriptorInt, @bitCast(this))); - } - - pub fn decode(fd: bun.FileDescriptor) FDImpl { - return @bitCast(@intFromEnum(fd)); - } - - /// When calling this function, you should consider the FD struct to now be invalid. - /// Calling `.close()` on the FD at that point may not work. - pub fn uv(this: FDImpl) UV { - return switch (environment.os) { - else => numberToHandle(this.value.as_system), - .windows => switch (this.kind) { - .system => { - const w = std.os.windows; - - const S = struct { - fn is_stdio_handle(id: w.DWORD, handle: w.HANDLE) bool { - const h = w.GetStdHandle(id) catch return false; - return handle == h; - } - }; - const handle = this.encode().cast(); - if (S.is_stdio_handle(w.STD_INPUT_HANDLE, handle)) return 0; - if (S.is_stdio_handle(w.STD_OUTPUT_HANDLE, handle)) return 1; - if (S.is_stdio_handle(w.STD_ERROR_HANDLE, handle)) return 2; - - std.debug.panic( - \\Cast {} -> FDImpl.UV makes closing impossible! - \\ - \\The supplier of this FileDescriptor should call 'bun.toLibUVOwnedFD' - \\or 'FDImpl.makeLibUVOwned', probably where open() was called. - , - .{this}, - ); - }, - .uv => this.value.as_uv, - }, - }; - } - - /// This function will prevent stdin, stdout, and stderr from being closed. - pub fn close(this: FDImpl) ?bun.sys.Error { - if (environment.os != .windows or this.kind == .uv) { - // This branch executes always on linux (uv() is no-op), - // or on Windows when given a UV file descriptor. - const fd = this.uv(); - if (fd == 0 or fd == 1 or fd == 2) { - log("close({}) SKIPPED", .{fd}); - return null; - } - } - return this.closeAllowingStdinStdoutAndStderr(); - } - - /// Assumes given a valid file descriptor - /// If error, the handle has not been closed - pub fn makeLibUVOwned(this: FDImpl) !FDImpl { - this.assertValid(); - return switch (environment.os) { - else => this, - .windows => switch (this.kind) { - .system => fd: { - break :fd FDImpl.fromUV(try uv_open_osfhandle(numberToHandle(this.value.as_system))); - }, - .uv => this, - }, - }; - } - - pub fn closeAllowingStdinStdoutAndStderr(this: FDImpl) ?bun.sys.Error { - if (allow_assert) { - bun.assert(this.value.as_system != invalid_value); // probably a UAF - } - - // Format the file descriptor for logging BEFORE closing it. - // Otherwise the file descriptor is always invalid after closing it. - var buf: if (environment.isDebug) [1050]u8 else void = undefined; - const this_fmt = if (environment.isDebug) std.fmt.bufPrint(&buf, "{}", .{this}) catch unreachable; - - const result: ?bun.sys.Error = switch (environment.os) { - .linux, .mac => result: { - const fd = this.encode(); - bun.assert(fd != bun.invalid_fd); - bun.assert(fd.cast() >= 0); - break :result switch (bun.C.getErrno(bun.sys.syscall.close(fd.cast()))) { - .BADF => bun.sys.Error{ .errno = @intFromEnum(posix.E.BADF), .syscall = .close, .fd = fd }, - else => null, - }; - }, - .windows => result: { - switch (this.kind) { - .uv => { - var req: libuv.fs_t = libuv.fs_t.uninitialized; - defer req.deinit(); - const rc = libuv.uv_fs_close(libuv.Loop.get(), &req, this.value.as_uv, null); - break :result if (rc.errno()) |errno| - .{ .errno = errno, .syscall = .close, .fd = this.encode(), .from_libuv = true } - else - null; - }, - .system => { - bun.assert(this.value.as_system != 0); - const handle: System = @ptrFromInt(@as(u64, this.value.as_system)); - break :result switch (bun.windows.NtClose(handle)) { - .SUCCESS => null, - else => |rc| bun.sys.Error{ - .errno = if (bun.windows.Win32Error.fromNTStatus(rc).toSystemErrno()) |errno| @intFromEnum(errno) else 1, - .syscall = .CloseHandle, - .fd = this.encode(), - }, - }; - }, - } - }, - else => @compileError("FD.close() not implemented for this platform"), - }; - - if (environment.isDebug) { - if (result) |err| { - if (err.errno == @intFromEnum(posix.E.BADF)) { - bun.Output.debugWarn("close({s}) = EBADF. This is an indication of a file descriptor UAF", .{this_fmt}); - } else { - log("close({s}) = {}", .{ this_fmt, err }); - } - } else { - log("close({s})", .{this_fmt}); - } - } - - return result; - } - - /// This "fails" if not given an int32, returning null in that case - pub fn fromJS(value: JSValue) ?FDImpl { - if (!value.isAnyInt()) return null; - const fd64 = value.toInt64(); - if (fd64 < 0 or fd64 > std.math.maxInt(i32)) { - return null; - } - const fd: i32 = @intCast(fd64); - if (comptime environment.isWindows) { - return switch (bun.FDTag.get(fd)) { - .stdin => FDImpl.decode(bun.STDIN_FD), - .stdout => FDImpl.decode(bun.STDOUT_FD), - .stderr => FDImpl.decode(bun.STDERR_FD), - else => FDImpl.fromUV(fd), - }; - } - return FDImpl.fromUV(fd); - } - - // If a non-number is given, returns null. - // If the given number is not an fd (negative), an error is thrown and error.JSException is returned. - pub fn fromJSValidated(value: JSValue, global: *JSC.JSGlobalObject) bun.JSError!?FDImpl { - if (!value.isNumber()) { - return null; - } - - const float = value.asNumber(); - if (@mod(float, 1) != 0) { - return global.throwRangeError(float, .{ .field_name = "fd", .msg = "an integer" }); - } - - const int: i64 = @intFromFloat(float); - if (int < 0 or int > std.math.maxInt(i32)) { - return global.throwRangeError(int, .{ .field_name = "fd", .min = 0, .max = std.math.maxInt(i32) }); - } - - const fd: c_int = @intCast(int); - - if (comptime environment.isWindows) { - return switch (bun.FDTag.get(fd)) { - .stdin => FDImpl.decode(bun.STDIN_FD), - .stdout => FDImpl.decode(bun.STDOUT_FD), - .stderr => FDImpl.decode(bun.STDERR_FD), - else => FDImpl.fromUV(fd), - }; - } - return FDImpl.fromUV(fd); - } - - /// After calling, the input file descriptor is no longer valid and must not be used. - /// If an error is thrown, the file descriptor is cleaned up for you. - pub fn toJS(value: FDImpl, global: *JSC.JSGlobalObject) JSValue { - const fd = value.makeLibUVOwned() catch { - _ = value.close(); - return global.throwValue((JSC.SystemError{ - .message = bun.String.static("EMFILE, too many open files"), - .code = bun.String.static("EMFILE"), - }).toErrorInstance(global)) catch .zero; - }; - return JSValue.jsNumberFromInt32(fd.uv()); - } - - pub fn format(this: FDImpl, comptime fmt: []const u8, _: std.fmt.FormatOptions, writer: anytype) !void { - if (!this.isValid()) { - try writer.writeAll("[invalid_fd]"); - return; - } - - if (fmt.len != 0) { - // The reason for this error is because formatting FD as an integer on windows is - // ambiguous and almost certainly a mistake. You probably meant to format fd.cast(). - // - // Remember this formatter will - // - on posix, print the number - // - on windows, print if it is a handle or a libuv file descriptor - // - in debug on all platforms, print the path of the file descriptor - // - // Not having this error caused a linux+debug only crash in bun.sys.getFdPath because - // we forgot to change the thing being printed to "fd.cast()" when FDImpl was introduced. - @compileError("invalid format string for FDImpl.format. must be empty like '{}'"); - } - - switch (environment.os) { - else => { - const fd = this.system(); - try writer.print("{d}", .{fd}); - if (environment.isDebug and fd >= 3) print_with_path: { - var path_buf: bun.PathBuffer = undefined; - const path = std.os.getFdPath(fd, &path_buf) catch break :print_with_path; - try writer.print("[{s}]", .{path}); - } - }, - .windows => { - switch (this.kind) { - .system => { - if (environment.isDebug) { - const peb = std.os.windows.peb(); - const handle = this.system(); - if (handle == peb.ProcessParameters.hStdInput) { - return try writer.print("{d}[stdin handle]", .{this.value.as_system}); - } else if (handle == peb.ProcessParameters.hStdOutput) { - return try writer.print("{d}[stdout handle]", .{this.value.as_system}); - } else if (handle == peb.ProcessParameters.hStdError) { - return try writer.print("{d}[stderr handle]", .{this.value.as_system}); - } else if (handle == peb.ProcessParameters.CurrentDirectory.Handle) { - return try writer.print("{d}[cwd handle]", .{this.value.as_system}); - } else print_with_path: { - var fd_path: bun.WPathBuffer = undefined; - const path = std.os.windows.GetFinalPathNameByHandle(handle, .{ .volume_name = .Nt }, &fd_path) catch break :print_with_path; - return try writer.print("{d}[{}]", .{ - this.value.as_system, - bun.fmt.utf16(path), - }); - } - } - - try writer.print("{d}[handle]", .{this.value.as_system}); - }, - .uv => try writer.print("{d}[libuv]", .{this.value.as_uv}), - } - }, - } - } - - pub fn assertValid(this: FDImpl) void { - bun.assert(this.isValid()); - } +const JSC = bun.JSC; +const JSValue = JSC.JSValue; +const libuv = bun.windows.libuv; +const libuv_private = struct { + extern fn uv_get_osfhandle(fd: c_int) fd_t; + extern fn uv_open_osfhandle(os_fd: fd_t) c_int; }; +const allow_assert = Environment.allow_assert; + +const log = bun.sys.syslog; diff --git a/src/feature_flags.zig b/src/feature_flags.zig index edeb2c2db8..918c0fdf90 100644 --- a/src/feature_flags.zig +++ b/src/feature_flags.zig @@ -1,5 +1,5 @@ const env = @import("env.zig"); -const bun = @import("root").bun; +const bun = @import("bun"); /// Enable breaking changes for the next major release of Bun // TODO: Make this a CLI flag / runtime var so that we can verify disabled code paths can compile diff --git a/src/fmt.zig b/src/fmt.zig index 8082b2adb0..32c43d2552 100644 --- a/src/fmt.zig +++ b/src/fmt.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Output = bun.Output; const strings = bun.strings; const string = bun.string; diff --git a/src/fs.zig b/src/fs.zig index 1878b97d72..35d3c707bb 100644 --- a/src/fs.zig +++ b/src/fs.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; @@ -20,6 +20,7 @@ const path_handler = @import("./resolver/resolve_path.zig"); const PathString = bun.PathString; const allocators = bun.allocators; const OOM = bun.OOM; +const FD = bun.FD; const MAX_PATH_BYTES = bun.MAX_PATH_BYTES; const PathBuffer = bun.PathBuffer; @@ -136,8 +137,9 @@ pub const FileSystem = struct { pub const DirEntry = struct { pub const EntryMap = bun.StringHashMapUnmanaged(*Entry); pub const EntryStore = allocators.BSSList(Entry, Preallocate.Counts.files); + dir: string, - fd: StoredFileDescriptorType = .zero, + fd: FD = .invalid, generation: bun.Generation = 0, data: EntryMap, @@ -390,7 +392,7 @@ pub const FileSystem = struct { symlink: PathString = PathString.empty, /// Too much code expects this to be 0 /// don't make it bun.invalid_fd - fd: StoredFileDescriptorType = .zero, + fd: FD = .invalid, kind: Kind = .file, }; @@ -616,7 +618,7 @@ pub const FileSystem = struct { // we will not delete the temp directory .can_rename_or_delete = false, .read_only = true, - }).unwrap()).asDir(); + }).unwrap()).stdDir(); } return try bun.openDirAbsolute(tmpdir_path); @@ -668,26 +670,24 @@ pub const FileSystem = struct { dir_fd: bun.FileDescriptor = bun.invalid_fd, pub inline fn dir(this: *TmpfilePosix) std.fs.Dir { - return this.dir_fd.asDir(); + return this.dir_fd.stdDir(); } pub inline fn file(this: *TmpfilePosix) std.fs.File { - return this.fd.asFile(); + return this.fd.stdFile(); } pub fn close(this: *TmpfilePosix) void { - if (this.fd != bun.invalid_fd) _ = bun.sys.close(this.fd); + if (this.fd.isValid()) this.fd.close(); } pub fn create(this: *TmpfilePosix, _: *RealFS, name: [:0]const u8) !void { // We originally used a temporary directory, but it caused EXDEV. - const dir_fd = std.fs.cwd().fd; + const dir_fd = bun.FD.cwd(); + this.dir_fd = dir_fd; const flags = bun.O.CREAT | bun.O.RDWR | bun.O.CLOEXEC; - this.dir_fd = bun.toFD(dir_fd); - - const result = try bun.sys.openat(bun.toFD(dir_fd), name, flags, std.posix.S.IRWXU).unwrap(); - this.fd = bun.toFD(result); + this.fd = try bun.sys.openat(dir_fd, name, flags, std.posix.S.IRWXU).unwrap(); } pub fn promoteToCWD(this: *TmpfilePosix, from_name: [*:0]const u8, name: [*:0]const u8) !void { @@ -718,19 +718,19 @@ pub const FileSystem = struct { } pub inline fn file(this: *TmpfileWindows) std.fs.File { - return this.fd.asFile(); + return this.fd.stdFile(); } pub fn close(this: *TmpfileWindows) void { - if (this.fd != bun.invalid_fd) _ = bun.sys.close(this.fd); + if (this.fd.isValid()) this.fd.close(); } pub fn create(this: *TmpfileWindows, rfs: *RealFS, name: [:0]const u8) !void { - const tmpdir_ = try rfs.openTmpDir(); + const tmp_dir = try rfs.openTmpDir(); const flags = bun.O.CREAT | bun.O.WRONLY | bun.O.CLOEXEC; - this.fd = try bun.sys.openat(bun.toFD(tmpdir_.fd), name, flags, 0).unwrap(); + this.fd = try bun.sys.openat(.fromStdDir(tmp_dir), name, flags, 0).unwrap(); var buf: bun.PathBuffer = undefined; const existing_path = try bun.getFdPath(this.fd, &buf); this.existing_path = try bun.default_allocator.dupe(u8, existing_path); @@ -986,7 +986,7 @@ pub const FileSystem = struct { 0, ); const fd = try dirfd.unwrap(); - return fd.asDir(); + return fd.stdDir(); } fn readdir( @@ -1008,7 +1008,7 @@ pub const FileSystem = struct { if (store_fd) { FileSystem.setMaxFd(handle.fd); - dir.fd = bun.toFD(handle.fd); + dir.fd = .fromStdDir(handle); } while (try iter.next().unwrap()) |*_entry| { @@ -1133,8 +1133,8 @@ pub const FileSystem = struct { if (in_place) |original| { original.data.clearAndFree(bun.fs_allocator); } - if (store_fd and entries.fd == .zero) - entries.fd = bun.toFD(handle.fd); + if (store_fd and !entries.fd.isValid()) + entries.fd = .fromStdDir(handle); entries_ptr.* = entries; const result = EntriesOption{ @@ -1441,36 +1441,34 @@ pub const FileSystem = struct { const stat = try C.lstat_absolute(absolute_path_c); const is_symlink = stat.kind == std.fs.File.Kind.sym_link; - var _kind = stat.kind; + var file_kind = stat.kind; var symlink: []const u8 = ""; if (is_symlink) { - var file = try if (existing_fd != .zero) - std.fs.File{ .handle = existing_fd.int() } + var file: bun.FD = if (existing_fd.unwrapValid()) |valid| + valid else if (store_fd) - std.fs.openFileAbsoluteZ(absolute_path_c, .{ .mode = .read_only }) + .fromStdFile(try std.fs.openFileAbsoluteZ(absolute_path_c, .{ .mode = .read_only })) else - bun.openFileForPath(absolute_path_c); - setMaxFd(file.handle); + .fromStdFile(try bun.openFileForPath(absolute_path_c)); + setMaxFd(file.native()); defer { - if ((!store_fd or fs.needToCloseFiles()) and existing_fd == .zero) { + if ((!store_fd or fs.needToCloseFiles()) and !existing_fd.isValid()) { file.close(); } else if (comptime FeatureFlags.store_file_descriptors) { - cache.fd = bun.toFD(file.handle); + cache.fd = file; } } - const _stat = try file.stat(); - - symlink = try bun.getFdPath(file.handle, &outpath); - - _kind = _stat.kind; + const file_stat = try file.stdFile().stat(); + symlink = try file.getFdPath(&outpath); + file_kind = file_stat.kind; } - bun.assert(_kind != .sym_link); + bun.assert(file_kind != .sym_link); - if (_kind == .directory) { + if (file_kind == .directory) { cache.kind = .dir; } else { cache.kind = .file; diff --git a/src/futex.zig b/src/futex.zig index 546fd51547..76ae3ab0ff 100644 --- a/src/futex.zig +++ b/src/futex.zig @@ -15,7 +15,7 @@ const Futex = @This(); const windows = std.os.windows; const linux = std.os.linux; const c = std.c; -const bun = @import("root").bun; +const bun = @import("bun"); const assert = bun.assert; const atomic = std.atomic; diff --git a/src/glob/GlobWalker.zig b/src/glob/GlobWalker.zig index e30476f086..f659b2a705 100644 --- a/src/glob/GlobWalker.zig +++ b/src/glob/GlobWalker.zig @@ -21,7 +21,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const eqlComptime = @import("../string_immutable.zig").eqlComptime; const expect = std.testing.expect; @@ -144,10 +144,10 @@ pub const SyscallAccessor = struct { const Handle = struct { value: bun.FileDescriptor, - const zero = Handle{ .value = bun.FileDescriptor.zero }; + const empty: Handle = .{ .value = .invalid }; - pub fn isZero(this: Handle) bool { - return this.value == bun.FileDescriptor.zero; + pub fn isEmpty(this: Handle) bool { + return !this.value.isValid(); } pub fn eql(this: Handle, other: Handle) bool { @@ -163,7 +163,7 @@ pub const SyscallAccessor = struct { } pub inline fn iterate(dir: Handle) DirIter { - return .{ .value = DirIterator.WrappedIterator.init(dir.value.asDir()) }; + return .{ .value = DirIterator.WrappedIterator.init(dir.value.stdDir()) }; } }; @@ -190,7 +190,7 @@ pub const SyscallAccessor = struct { } pub fn close(handle: Handle) ?Syscall.Error { - return Syscall.close(handle.value); + return handle.value.closeAllowingBadFileDescriptor(@returnAddress()); } pub fn getcwd(path_buf: *bun.PathBuffer) Maybe([]const u8) { @@ -206,9 +206,9 @@ pub const DirEntryAccessor = struct { const Handle = struct { value: ?*FS.DirEntry, - const zero = Handle{ .value = null }; + const empty: Handle = .{ .value = null }; - pub fn isZero(this: Handle) bool { + pub fn isEmpty(this: Handle) bool { return this.value == null; } @@ -276,7 +276,7 @@ pub const DirEntryAccessor = struct { } pub fn open(path: [:0]const u8) !Maybe(Handle) { - return openat(Handle.zero, path); + return openat(.empty, path); } pub fn openat(handle: Handle, path_: [:0]const u8) !Maybe(Handle) { @@ -296,7 +296,7 @@ pub const DirEntryAccessor = struct { }; switch (res.*) { .entries => |entry| { - return .{ .result = Handle{ .value = entry } }; + return .{ .result = .{ .value = entry } }; }, .err => |err| { return err.original_err; @@ -434,7 +434,7 @@ pub fn GlobWalker_( pub const Iterator = struct { walker: *GlobWalker, iter_state: IterState = .get_next, - cwd_fd: Accessor.Handle = Accessor.Handle.zero, + cwd_fd: Accessor.Handle = .empty, empty_dir_path: [0:0]u8 = [0:0]u8{}, /// This is to make sure in debug/tests that we are closing file descriptors /// We should only have max 2 open at a time. One for the cwd, and one for the @@ -561,13 +561,13 @@ pub fn GlobWalker_( } pub fn closeCwdFd(this: *Iterator) void { - if (this.cwd_fd.isZero()) return; + if (this.cwd_fd.isEmpty()) return; _ = Accessor.close(this.cwd_fd); if (comptime count_fds) this.fds_open -= 1; } pub fn closeDisallowingCwd(this: *Iterator, fd: Accessor.Handle) void { - if (fd.isZero() or fd.eql(this.cwd_fd)) return; + if (fd.isEmpty() or fd.eql(this.cwd_fd)) return; _ = Accessor.close(fd); if (comptime count_fds) this.fds_open -= 1; } @@ -587,7 +587,7 @@ pub fn GlobWalker_( ) !Maybe(void) { log("transition => {s}", .{work_item.path}); this.iter_state = .{ .directory = .{ - .fd = Accessor.Handle.zero, + .fd = .empty, .iter = undefined, .path = undefined, .dir_path = undefined, @@ -693,7 +693,7 @@ pub fn GlobWalker_( this.iter_state.directory.next_pattern = if (component_idx + 1 < this.walker.patternComponents.items.len) &this.walker.patternComponents.items[component_idx + 1] else null; this.iter_state.directory.is_last = component_idx == this.walker.patternComponents.items.len - 1; this.iter_state.directory.at_cwd = false; - this.iter_state.directory.fd = Accessor.Handle.zero; + this.iter_state.directory.fd = .empty; log("Transition(dirpath={s}, fd={}, component_idx={d})", .{ dir_path, fd, component_idx }); diff --git a/src/glob/match.zig b/src/glob/match.zig index 27f14ee960..efec84d616 100644 --- a/src/glob/match.zig +++ b/src/glob/match.zig @@ -23,7 +23,7 @@ // THE SOFTWARE. const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Allocator = std.mem.Allocator; diff --git a/src/heap_breakdown.zig b/src/heap_breakdown.zig index 5a225871d0..b8de737a28 100644 --- a/src/heap_breakdown.zig +++ b/src/heap_breakdown.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const std = @import("std"); const Environment = bun.Environment; const Allocator = std.mem.Allocator; diff --git a/src/hive_array.zig b/src/hive_array.zig index 0175012b40..042c4d2387 100644 --- a/src/hive_array.zig +++ b/src/hive_array.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const assert = bun.assert; const mem = std.mem; const testing = std.testing; diff --git a/src/hmac.zig b/src/hmac.zig index 790cbfb9fc..1c3ee51947 100644 --- a/src/hmac.zig +++ b/src/hmac.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const std = @import("std"); const boring = bun.BoringSSL.c; diff --git a/src/http.zig b/src/http.zig index a47fe32534..8d6a0f0d3d 100644 --- a/src/http.zig +++ b/src/http.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const picohttp = bun.picohttp; const JSC = bun.JSC; const string = bun.string; diff --git a/src/http/header_builder.zig b/src/http/header_builder.zig index 965a15119f..eb365bb8e8 100644 --- a/src/http/header_builder.zig +++ b/src/http/header_builder.zig @@ -5,7 +5,7 @@ const string = bun.string; const HTTPClient = @import("../http.zig"); const Api = @import("../api/schema.zig").Api; const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); content: StringBuilder = .{}, header_count: u64 = 0, diff --git a/src/http/method.zig b/src/http/method.zig index 2be3af24ce..e6391c3242 100644 --- a/src/http/method.zig +++ b/src/http/method.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/src/http/mime_type.zig b/src/http/mime_type.zig index 8cf8b1ac88..67d75b5fa7 100644 --- a/src/http/mime_type.zig +++ b/src/http/mime_type.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/src/http/url_path.zig b/src/http/url_path.zig index d1e50072b3..5085c87d55 100644 --- a/src/http/url_path.zig +++ b/src/http/url_path.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/src/http/websocket.zig b/src/http/websocket.zig index 78dde7706e..5029c3090b 100644 --- a/src/http/websocket.zig +++ b/src/http/websocket.zig @@ -3,7 +3,7 @@ const std = @import("std"); const posix = std.posix; -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/src/http/websocket_http_client.zig b/src/http/websocket_http_client.zig index 91965c3567..57f38e0e71 100644 --- a/src/http/websocket_http_client.zig +++ b/src/http/websocket_http_client.zig @@ -2,7 +2,7 @@ // Thank you @frmdstryr. const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/src/http/zlib.zig b/src/http/zlib.zig index c492ce743a..f4eb16f231 100644 --- a/src/http/zlib.zig +++ b/src/http/zlib.zig @@ -4,7 +4,7 @@ const MutableString = bun.MutableString; const getAllocator = @import("../http.zig").getAllocator; const ZlibPool = @This(); const Zlib = @import("../zlib.zig"); -const bun = @import("root").bun; +const bun = @import("bun"); fn initMutableString(allocator: std.mem.Allocator) anyerror!MutableString { return MutableString.initEmpty(allocator); diff --git a/src/import_record.zig b/src/import_record.zig index 89622aaa97..9372ae5532 100644 --- a/src/import_record.zig +++ b/src/import_record.zig @@ -1,5 +1,5 @@ const fs = bun.fs; -const bun = @import("root").bun; +const bun = @import("bun"); const logger = bun.logger; const std = @import("std"); const Ref = @import("ast/base.zig").Ref; diff --git a/src/ini.zig b/src/ini.zig index f1e472a8e1..008dcc7c63 100644 --- a/src/ini.zig +++ b/src/ini.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Allocator = std.mem.Allocator; const E = bun.JSAst.E; const Expr = bun.JSAst.Expr; diff --git a/src/install/bin.zig b/src/install/bin.zig index 4da91e8a0b..97a5315379 100644 --- a/src/install/bin.zig +++ b/src/install/bin.zig @@ -11,7 +11,7 @@ const C = @import("../c.zig"); const Fs = @import("../fs.zig"); const stringZ = bun.stringZ; const Resolution = @import("./resolution.zig").Resolution; -const bun = @import("root").bun; +const bun = @import("bun"); const path = bun.path; const string = bun.string; const Install = @import("./install.zig"); @@ -456,7 +456,7 @@ pub const Bin = extern struct { done: bool = false, dir_iterator: ?std.fs.Dir.Iterator = null, package_name: String, - destination_node_modules: std.fs.Dir = bun.invalid_fd.asDir(), + destination_node_modules: std.fs.Dir = bun.invalid_fd.stdDir(), buf: bun.PathBuffer = undefined, string_buffer: []const u8, extern_string_buf: []const ExternalString, @@ -647,7 +647,7 @@ pub const Bin = extern struct { } return; }; - defer _ = bun.sys.close(target); + defer target.close(); this.createWindowsShim(target, abs_target, abs_dest, global); } @@ -672,7 +672,7 @@ pub const Bin = extern struct { if (strings.indexOfChar(chunk, '\n')) |newline| { if (newline > 0 and chunk[newline - 1] == '\r') { const pos = newline - 1; - bin.handle.asFile().seekTo(pos) catch return; + bin.handle.stdFile().seekTo(pos) catch return; bin.writeAll("\n").unwrap() catch return; } } @@ -698,7 +698,7 @@ pub const Bin = extern struct { return; } - bun.makePath(this.node_modules.asDir(), ".bin") catch {}; + bun.makePath(this.node_modules.stdDir(), ".bin") catch {}; break :bunx_file bun.sys.File.openatOSPath(bun.invalid_fd, abs_bunx_file, bun.O.WRONLY | bun.O.CREAT | bun.O.TRUNC, 0o664).unwrap() catch |real_err| { this.err = real_err; return; @@ -713,7 +713,7 @@ pub const Bin = extern struct { const shebang = shebang: { const first_content_chunk = contents: { - const reader = target.asFile().reader(); + const reader = target.stdFile().reader(); const read = reader.read(&read_in_buf) catch break :contents null; if (read == 0) break :contents null; break :contents read_in_buf[0..read]; @@ -791,7 +791,7 @@ pub const Bin = extern struct { return; } - bun.makePath(this.node_modules.asDir(), ".bin") catch {}; + bun.makePath(this.node_modules.stdDir(), ".bin") catch {}; switch (bun.sys.symlink(rel_target, abs_dest)) { .err => |real_error| { // It was just created, no need to delete destination and symlink again diff --git a/src/install/bun.lock.zig b/src/install/bun.lock.zig index 552b42c02a..36be553942 100644 --- a/src/install/bun.lock.zig +++ b/src/install/bun.lock.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const stringZ = bun.stringZ; const strings = bun.strings; diff --git a/src/install/dependency.zig b/src/install/dependency.zig index 29b017b94a..114d4c6e80 100644 --- a/src/install/dependency.zig +++ b/src/install/dependency.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const logger = bun.logger; const Environment = @import("../env.zig"); const Install = @import("./install.zig"); diff --git a/src/install/extract_tarball.zig b/src/install/extract_tarball.zig index 1c39805991..21c8cb9aeb 100644 --- a/src/install/extract_tarball.zig +++ b/src/install/extract_tarball.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const default_allocator = bun.default_allocator; const Global = bun.Global; const json_parser = bun.JSON; @@ -327,7 +327,7 @@ fn extract(this: *const ExtractTarball, tgz_bytes: []const u8) !Install.ExtractD const path_to_use = path2; while (true) { - const dir_to_move = bun.sys.openDirAtWindowsA(bun.toFD(this.temp_dir.fd), bun.span(tmpname), .{ + const dir_to_move = bun.sys.openDirAtWindowsA(.fromStdDir(this.temp_dir), bun.span(tmpname), .{ .can_rename_or_delete = true, .create = false, .iterable = false, @@ -344,14 +344,14 @@ fn extract(this: *const ExtractTarball, tgz_bytes: []const u8) !Install.ExtractD return error.InstallFailed; }; - switch (bun.C.moveOpenedFileAt(dir_to_move, bun.toFD(cache_dir.fd), path_to_use, true)) { + switch (bun.C.moveOpenedFileAt(dir_to_move, .fromStdDir(cache_dir), path_to_use, true)) { .err => |err| { if (!did_retry) { switch (err.getErrno()) { .NOTEMPTY, .PERM, .BUSY, .EXIST => { // before we attempt to delete the destination, let's close the source dir. - _ = bun.sys.close(dir_to_move); + dir_to_move.close(); // We tried to move the folder over // but it didn't work! @@ -365,9 +365,9 @@ fn extract(this: *const ExtractTarball, tgz_bytes: []const u8) !Install.ExtractD tmpname_bytes[tmpname_len..][0..4].* = .{ 't', 'm', 'p', 0 }; const tempdest = tmpname_bytes[0 .. tmpname_len + 3 :0]; switch (bun.sys.renameat( - bun.toFD(cache_dir.fd), + .fromStdDir(cache_dir), folder_name, - bun.toFD(tmpdir.fd), + .fromStdDir(tmpdir), tempdest, )) { .err => {}, @@ -382,7 +382,7 @@ fn extract(this: *const ExtractTarball, tgz_bytes: []const u8) !Install.ExtractD else => {}, } } - _ = bun.sys.close(dir_to_move); + dir_to_move.close(); this.package_manager.log.addErrorFmt( null, logger.Loc.Empty, @@ -393,7 +393,7 @@ fn extract(this: *const ExtractTarball, tgz_bytes: []const u8) !Install.ExtractD return error.InstallFailed; }, .result => { - _ = bun.sys.close(dir_to_move); + dir_to_move.close(); }, } @@ -417,9 +417,9 @@ fn extract(this: *const ExtractTarball, tgz_bytes: []const u8) !Install.ExtractD } if (bun.sys.renameatConcurrently( - bun.toFD(tmpdir.fd), + .fromStdDir(tmpdir), src, - bun.toFD(cache_dir.fd), + .fromStdDir(cache_dir), folder_name, .{ .move_fallback = true }, ).asErr()) |err| { @@ -449,7 +449,7 @@ fn extract(this: *const ExtractTarball, tgz_bytes: []const u8) !Install.ExtractD defer final_dir.close(); // and get the fd path const final_path = bun.getFdPathZ( - final_dir.fd, + .fromStdDir(final_dir), &final_path_buf, ) catch |err| { this.package_manager.log.addErrorFmt( @@ -473,7 +473,7 @@ fn extract(this: *const ExtractTarball, tgz_bytes: []const u8) !Install.ExtractD this.package_manager.lockfile.trusted_dependencies.?.contains(@truncate(Semver.String.Builder.stringHash(name))), }) { const json_file, json_buf = bun.sys.File.readFileFrom( - bun.toFD(cache_dir.fd), + bun.FD.fromStdDir(cache_dir), bun.path.joinZ(&[_]string{ folder_name, "package.json" }, .auto), bun.default_allocator, ).unwrap() catch |err| { @@ -536,10 +536,10 @@ fn extract(this: *const ExtractTarball, tgz_bytes: []const u8) !Install.ExtractD break :create_index; }; } else { - var index_dir = bun.MakePath.makeOpenPath(cache_dir, name, .{}) catch break :create_index; + var index_dir = bun.FD.fromStdDir(bun.MakePath.makeOpenPath(cache_dir, name, .{}) catch break :create_index); defer index_dir.close(); - bun.sys.symlinkat(final_path, bun.toFD(index_dir), dest_name).unwrap() catch break :create_index; + bun.sys.symlinkat(final_path, index_dir, dest_name).unwrap() catch break :create_index; } } diff --git a/src/install/install.zig b/src/install/install.zig index 43a4f82997..d410ca96ff 100644 --- a/src/install/install.zig +++ b/src/install/install.zig @@ -6,7 +6,7 @@ const default_max_simultaneous_requests_for_bun_install = 64; const default_max_simultaneous_requests_for_bun_install_for_proxies = 64; -const bun = @import("root").bun; +const bun = @import("bun"); const FeatureFlags = bun.FeatureFlags; const string = bun.string; const Output = bun.Output; @@ -839,9 +839,7 @@ pub const Task = struct { return; }; - this.data = .{ - .git_clone = bun.toFD(dir.fd), - }; + this.data = .{ .git_clone = .fromStdDir(dir) }; this.status = Status.success; }, .git_checkout => { @@ -851,7 +849,7 @@ pub const Task = struct { this.request.git_checkout.env, manager.log, manager.getCacheDirectory(), - git_checkout.repo_dir.asDir(), + git_checkout.repo_dir.stdDir(), git_checkout.name.slice(), git_checkout.url.slice(), git_checkout.resolved.slice(), @@ -1003,6 +1001,7 @@ pub fn NewPackageInstall(comptime kind: PkgInstallKind) type { const do_progress = kind != .patch; const ProgressT = if (do_progress) *Progress else struct {}; return struct { + /// TODO: Change to bun.FD.Dir cache_dir: std.fs.Dir, cache_dir_subpath: stringZ = "", destination_dir_subpath: stringZ = "", @@ -1132,11 +1131,11 @@ pub fn NewPackageInstall(comptime kind: PkgInstallKind) type { } if (comptime bun.Environment.isPosix) { - _ = bun.sys.fstatat(bun.toFD(destination_dir.fd), patch_tag_path).unwrap() catch return false; + _ = bun.sys.fstatat(.fromStdDir(destination_dir), patch_tag_path).unwrap() catch return false; } else { - switch (bun.sys.openat(bun.toFD(destination_dir.fd), patch_tag_path, bun.O.RDONLY, 0)) { + switch (bun.sys.openat(.fromStdDir(destination_dir), patch_tag_path, bun.O.RDONLY, 0)) { .err => return false, - .result => |fd| _ = bun.sys.close(fd), + .result => |fd| fd.close(), } } @@ -1405,7 +1404,7 @@ pub fn NewPackageInstall(comptime kind: PkgInstallKind) type { while (try walker.next()) |entry| { switch (entry.kind) { .directory => { - _ = bun.sys.mkdirat(bun.toFD(destination_dir_.fd), entry.path, 0o755); + _ = bun.sys.mkdirat(.fromStdDir(destination_dir_), entry.path, 0o755); }, .file => { bun.copy(u8, &stackpath, entry.path); @@ -1514,7 +1513,7 @@ pub fn NewPackageInstall(comptime kind: PkgInstallKind) type { state.cached_package_dir = (if (comptime Environment.isWindows) if (method == .symlink) - bun.openDirNoRenamingOrDeletingWindows(bun.toFD(this.cache_dir), this.cache_dir_subpath) + bun.openDirNoRenamingOrDeletingWindows(.fromStdDir(this.cache_dir), this.cache_dir_subpath) else bun.openDir(this.cache_dir, this.cache_dir_subpath) else @@ -1689,7 +1688,7 @@ pub fn NewPackageInstall(comptime kind: PkgInstallKind) type { _ = C.fchmod(outfile.handle, @intCast(stat.mode)); } - bun.copyFileWithState(in_file.handle, outfile.handle, ©_file_state).unwrap() catch |err| { + bun.copyFileWithState(.fromStdFile(in_file), .fromStdFile(outfile), ©_file_state).unwrap() catch |err| { if (do_progress) { progress_.root.end(); progress_.refresh(); @@ -1973,7 +1972,7 @@ pub fn NewPackageInstall(comptime kind: PkgInstallKind) type { var buf2: bun.PathBuffer = undefined; var to_copy_buf2: []u8 = undefined; if (Environment.isPosix) { - const cache_dir_path = try bun.getFdPath(state.cached_package_dir.fd, &buf2); + const cache_dir_path = try bun.FD.fromStdDir(state.cached_package_dir).getFdPath(&buf2); if (cache_dir_path.len > 0 and cache_dir_path[cache_dir_path.len - 1] != std.fs.path.sep) { buf2[cache_dir_path.len] = std.fs.path.sep; to_copy_buf2 = buf2[cache_dir_path.len + 1 ..]; @@ -2111,7 +2110,12 @@ pub fn NewPackageInstall(comptime kind: PkgInstallKind) type { pub fn uninstallBeforeInstall(this: *@This(), destination_dir: std.fs.Dir) void { var rand_path_buf: [48]u8 = undefined; const temp_path = std.fmt.bufPrintZ(&rand_path_buf, ".old-{}", .{std.fmt.fmtSliceHexUpper(std.mem.asBytes(&bun.fastRandom()))}) catch unreachable; - switch (bun.sys.renameat(bun.toFD(destination_dir), this.destination_dir_subpath, bun.toFD(destination_dir), temp_path)) { + switch (bun.sys.renameat( + .fromStdDir(destination_dir), + this.destination_dir_subpath, + .fromStdDir(destination_dir), + temp_path, + )) { .err => { // if it fails, that means the directory doesn't exist or was inaccessible }, @@ -2166,7 +2170,7 @@ pub fn NewPackageInstall(comptime kind: PkgInstallKind) type { } return; }; - defer _ = bun.sys.close(bun.toFD(dir.fd)); + defer bun.FD.fromStdDir(dir).close(); dir.deleteTree(basename) catch |err| { if (comptime Environment.isDebug) { @@ -2199,7 +2203,7 @@ pub fn NewPackageInstall(comptime kind: PkgInstallKind) type { switch (Syscall.open(path, bun.O.PATH, @as(u32, 0))) { .err => return true, .result => |fd| { - _ = bun.sys.close(fd); + fd.close(); return false; }, } @@ -2209,7 +2213,7 @@ pub fn NewPackageInstall(comptime kind: PkgInstallKind) type { return true; }, .result => |fd| { - _ = bun.sys.close(fd); + fd.close(); return false; }, } @@ -2217,7 +2221,7 @@ pub fn NewPackageInstall(comptime kind: PkgInstallKind) type { switch (Syscall.open(path, bun.O.PATH, @as(u32, 0))) { .err => return true, .result => |fd| { - _ = bun.sys.close(fd); + fd.close(); return false; }, } @@ -2228,8 +2232,8 @@ pub fn NewPackageInstall(comptime kind: PkgInstallKind) type { const WinBinLinkingShim = @import("./windows-shim/BinLinkingShim.zig"); const bin_path = bin_path: { const fd = bun.sys.openatWindows(node_mod_fd, path, bun.O.RDONLY).unwrap() catch return true; - defer _ = bun.sys.close(fd); - const size = fd.asFile().readAll(temp_buffer) catch return true; + defer fd.close(); + const size = fd.stdFile().readAll(temp_buffer) catch return true; const decoded = WinBinLinkingShim.looseDecode(temp_buffer[0..size]) orelse return true; bun.assert(decoded.flags.isValid()); // looseDecode ensures valid flags break :bin_path decoded.bin_path; @@ -2237,7 +2241,7 @@ pub fn NewPackageInstall(comptime kind: PkgInstallKind) type { { const fd = bun.sys.openatWindows(node_mod_fd, bin_path, bun.O.RDONLY).unwrap() catch return true; - _ = bun.sys.close(fd); + fd.close(); } return false; @@ -2306,7 +2310,7 @@ pub fn NewPackageInstall(comptime kind: PkgInstallKind) type { .err => |err_| brk: { var err = err_; if (err.getErrno() == .EXIST) { - _ = bun.sys.rmdirat(bun.toFD(destination_dir), this.destination_dir_subpath); + _ = bun.sys.rmdirat(.fromStdDir(destination_dir), this.destination_dir_subpath); switch (bun.sys.symlinkOrJunction(dest_z, target_z)) { .err => |e| err = e, .result => break :brk, @@ -2325,7 +2329,7 @@ pub fn NewPackageInstall(comptime kind: PkgInstallKind) type { if (subdir != null) dest_dir.close(); } - const dest_dir_path = bun.getFdPath(dest_dir.fd, &dest_buf) catch |err| return Result.fail(err, .linking_dependency, @errorReturnTrace()); + const dest_dir_path = bun.getFdPath(.fromStdDir(dest_dir), &dest_buf) catch |err| return Result.fail(err, .linking_dependency, @errorReturnTrace()); const target = Path.relative(dest_dir_path, to_path); std.posix.symlinkat(target, dest_dir.fd, dest) catch |err| return Result.fail(err, .linking_dependency, null); @@ -2362,9 +2366,9 @@ pub fn NewPackageInstall(comptime kind: PkgInstallKind) type { defer buf[subpath_len] = 0; @memcpy(buf[subpath_len + 1 ..][0.."package.json\x00".len], "package.json\x00"); const subpath = buf[0 .. subpath_len + 1 + "package.json".len :0]; - break :package_json_exists Syscall.existsAt(bun.toFD(this.cache_dir.fd), subpath); + break :package_json_exists Syscall.existsAt(.fromStdDir(this.cache_dir), subpath); }, - else => Syscall.directoryExistsAt(this.cache_dir.fd, this.cache_dir_subpath).unwrap() catch false, + else => Syscall.directoryExistsAt(.fromStdDir(this.cache_dir), this.cache_dir_subpath).unwrap() catch false, }; if (exists) manager.setPreinstallState(package_id, manager.lockfile, .done); break :brk !exists; @@ -2372,7 +2376,7 @@ pub fn NewPackageInstall(comptime kind: PkgInstallKind) type { const cache_dir_subpath_without_patch_hash = this.cache_dir_subpath[0 .. std.mem.lastIndexOf(u8, this.cache_dir_subpath, "_patch_hash=") orelse @panic("Patched dependency cache dir subpath does not have the \"_patch_hash=HASH\" suffix. This is a bug, please file a GitHub issue.")]; @memcpy(bun.path.join_buf[0..cache_dir_subpath_without_patch_hash.len], cache_dir_subpath_without_patch_hash); bun.path.join_buf[cache_dir_subpath_without_patch_hash.len] = 0; - const exists = Syscall.directoryExistsAt(this.cache_dir.fd, bun.path.join_buf[0..cache_dir_subpath_without_patch_hash.len :0]).unwrap() catch false; + const exists = Syscall.directoryExistsAt(.fromStdDir(this.cache_dir), bun.path.join_buf[0..cache_dir_subpath_without_patch_hash.len :0]).unwrap() catch false; if (exists) manager.setPreinstallState(package_id, manager.lockfile, .done); break :brk !exists; }, @@ -2389,7 +2393,7 @@ pub fn NewPackageInstall(comptime kind: PkgInstallKind) type { // @memcpy(bun.path.join_buf[this.cache_dir_subpath.len .. this.cache_dir_subpath.len + patch_hash_part.len], patch_hash_part); // bun.path.join_buf[this.cache_dir_subpath.len + patch_hash_part.len] = 0; // const patch_cache_dir_subpath = bun.path.join_buf[0 .. this.cache_dir_subpath.len + patch_hash_part.len :0]; - const exists = Syscall.directoryExistsAt(this.cache_dir.fd, this.cache_dir_subpath).unwrap() catch false; + const exists = Syscall.directoryExistsAt(.fromStdDir(this.cache_dir), this.cache_dir_subpath).unwrap() catch false; if (exists) manager.setPreinstallState(package_id, manager.lockfile, .done); return !exists; } @@ -2407,14 +2411,15 @@ pub fn NewPackageInstall(comptime kind: PkgInstallKind) type { const result = this.installImpl(skip_delete, destination_dir, this.getInstallMethod(), resolution_tag); if (result == .fail) return result; - const fd = bun.toFD(destination_dir.fd); + const fd = bun.FD.fromStdDir(destination_dir); const subpath = bun.path.joinZ(&[_][]const u8{ this.destination_dir_subpath, ".bun-patch-tag" }); - const tag_fd = switch (bun.sys.openat(fd, subpath, bun.O.CREAT | bun.O.WRONLY, 0o666)) { - .err => |e| return .fail(bun.errnoToZigErr(e.getErrno()), .patching, @errorReturnTrace()), + const tag_fd = switch (fd.openat(subpath, bun.O.CREAT | bun.O.WRONLY, 0o666)) { .result => |f| f, + .err => |e| return .fail(bun.errnoToZigErr(e.getErrno()), .patching, @errorReturnTrace()), }; - defer _ = bun.sys.close(tag_fd); - if (bun.sys.File.writeAll(.{ .handle = tag_fd }, this.package_version).asErr()) |e| return .fail(bun.errnoToZigErr(e.getErrno()), .patching, @errorReturnTrace()); + defer tag_fd.close(); + if (bun.sys.File.writeAll(.{ .handle = tag_fd }, this.package_version).asErr()) |e| + return .fail(bun.errnoToZigErr(e.getErrno()), .patching, @errorReturnTrace()); return result; }, } @@ -3383,7 +3388,7 @@ pub const PackageManager = struct { this.global_dir = global_dir; this.global_link_dir = try global_dir.makeOpenPath("node_modules", .{}); var buf: bun.PathBuffer = undefined; - const _path = try bun.getFdPath(this.global_link_dir.?.fd, &buf); + const _path = try bun.getFdPath(.fromStdDir(this.global_link_dir.?), &buf); this.global_link_dir_path = try Fs.FileSystem.DirnameStore.instance.append([]const u8, _path); break :brk this.global_link_dir.?; }; @@ -3582,7 +3587,7 @@ pub const PackageManager = struct { return this.temp_dir_ orelse brk: { this.temp_dir_ = this.ensureTemporaryDirectory(); var pathbuf: bun.PathBuffer = undefined; - const temp_dir_path = bun.getFdPathZ(bun.toFD(this.temp_dir_.?), &pathbuf) catch Output.panic("Unable to read temporary directory path", .{}); + const temp_dir_path = bun.getFdPathZ(.fromStdDir(this.temp_dir_.?), &pathbuf) catch Output.panic("Unable to read temporary directory path", .{}); this.temp_dir_path = bun.default_allocator.dupeZ(u8, temp_dir_path) catch bun.outOfMemory(); break :brk this.temp_dir_.?; }; @@ -3695,7 +3700,7 @@ pub const PackageManager = struct { const elapsed = timer.read(); if (elapsed > std.time.ns_per_ms * 100) { var path_buf: bun.PathBuffer = undefined; - const cache_dir_path = bun.getFdPath(cache_directory.fd, &path_buf) catch "it"; + const cache_dir_path = bun.getFdPath(.fromStdDir(cache_directory), &path_buf) catch "it"; Output.prettyErrorln( "warn: Slow filesystem detected. If {s} is a network drive, consider setting $BUN_INSTALL_CACHE_DIR to a local folder.", .{cache_dir_path}, @@ -4039,7 +4044,7 @@ pub const PackageManager = struct { } pub fn isFolderInCache(this: *PackageManager, folder_path: stringZ) bool { - return bun.sys.directoryExistsAt(this.getCacheDirectory(), folder_path).unwrap() catch false; + return bun.sys.directoryExistsAt(.fromStdDir(this.getCacheDirectory()), folder_path).unwrap() catch false; } pub fn pathForCachedNPMPath( @@ -4058,7 +4063,7 @@ pub const PackageManager = struct { cache_path_buf[package_name.len] = std.fs.path.sep; - const cache_dir = bun.toFD(this.getCacheDirectory()); + const cache_dir: bun.FD = .fromStdDir(this.getCacheDirectory()); if (comptime Environment.isWindows) { var path_buf: bun.PathBuffer = undefined; @@ -4069,10 +4074,10 @@ pub const PackageManager = struct { }; } - return bun.sys.readlinkat(cache_dir, cache_path, buf).unwrap() catch |err| { + return cache_dir.readlinkat(cache_path, buf).unwrap() catch |err| { // if we run into an error, delete the symlink // so that we don't repeatedly try to read it - _ = bun.sys.unlinkat(cache_dir, cache_path); + _ = cache_dir.unlinkat(cache_path); return err; }; } @@ -5517,7 +5522,7 @@ pub const PackageManager = struct { this.allocator, this.env, this.log, - repo_fd.asDir(), + repo_fd.stdDir(), alias, this.lockfile.str(&dep.committish), clone_id, @@ -7006,7 +7011,7 @@ pub const PackageManager = struct { manager.allocator, manager.env, manager.log, - task.data.git_clone.asDir(), + task.data.git_clone.stdDir(), dep_name, committish, task.id, @@ -7139,7 +7144,7 @@ pub const PackageManager = struct { log_level: LogLevel = .default, global: bool = false, - global_bin_dir: std.fs.Dir = bun.invalid_fd.asDir(), + global_bin_dir: std.fs.Dir = bun.FD.invalid.stdDir(), explicit_global_directory: string = "", /// destination directory to link bins into // must be a variable due to global installs and bunx @@ -8838,7 +8843,7 @@ pub const PackageManager = struct { const json_buf = try ctx.allocator.alloc(u8, json_stat_size + 64); defer ctx.allocator.free(json_buf); const json_len = try json_file.preadAll(json_buf, 0); - const json_path = try bun.getFdPath(json_file.handle, &package_json_cwd_buf); + const json_path = try bun.getFdPath(.fromStdFile(json_file), &package_json_cwd_buf); const json_source = logger.Source.initPathString(json_path, json_buf[0..json_len]); initializeStore(); const json = try JSON.parsePackageJSONUTF8(&json_source, ctx.log, ctx.allocator); @@ -8903,7 +8908,7 @@ pub const PackageManager = struct { bun.copy(u8, &cwd_buf, fs.top_level_dir); cwd_buf[fs.top_level_dir.len] = 0; fs.top_level_dir = cwd_buf[0..fs.top_level_dir.len :0]; - package_json_cwd = try bun.getFdPath(root_package_json_file.handle, &package_json_cwd_buf); + package_json_cwd = try bun.getFdPath(.fromStdFile(root_package_json_file), &package_json_cwd_buf); const entries_option = try fs.fs.readDirectory(fs.top_level_dir, null, 0, true); @@ -9420,8 +9425,8 @@ pub const PackageManager = struct { var node_modules_path_buf: bun.PathBuffer = undefined; var bin_linker = Bin.Linker{ .bin = package.bin, - .node_modules = bun.toFD(node_modules.fd), - .node_modules_path = bun.getFdPath(node_modules, &node_modules_path_buf) catch |err| { + .node_modules = .fromStdDir(node_modules), + .node_modules_path = bun.getFdPath(.fromStdDir(node_modules), &node_modules_path_buf) catch |err| { if (manager.options.log_level != .silent) { Output.err(err, "failed to link binary", .{}); } @@ -9565,8 +9570,8 @@ pub const PackageManager = struct { var bin_linker = Bin.Linker{ .bin = package.bin, - .node_modules = bun.toFD(node_modules.fd), - .node_modules_path = bun.getFdPath(node_modules, &node_modules_path_buf) catch |err| { + .node_modules = .fromStdDir(node_modules), + .node_modules_path = bun.getFdPath(.fromStdDir(node_modules), &node_modules_path_buf) catch |err| { if (manager.options.log_level != .silent) { Output.err(err, "failed to link binary", .{}); } @@ -11188,7 +11193,7 @@ pub const PackageManager = struct { path, bun.O.RDWR, 0, - ).unwrap()).handle.asFile(); + ).unwrap()).handle.stdFile(); try workspace_package_json_file.pwriteAll(source, 0); std.posix.ftruncate(workspace_package_json_file.handle, source.len) catch {}; @@ -11687,9 +11692,9 @@ pub const PackageManager = struct { const entrypathZ = pathbuf[0..entrypath.len :0]; if (bun.sys.renameatConcurrently( - bun.toFD(destination_dir_.fd), + .fromStdDir(destination_dir_), entrypathZ, - bun.toFD(tmpdir_in_node_modules.fd), + .fromStdDir(tmpdir_in_node_modules), tmpname, .{ .move_fallback = true }, ).asErr()) |e| { @@ -11718,7 +11723,7 @@ pub const PackageManager = struct { pathbuf[entry.path.len] = 0; if (bun.sys.unlinkat( - bun.toFD(destination_dir_.fd), + .fromStdDir(destination_dir_), pathbuf[0..entry.path.len :0], ).asErr()) |e| { Output.prettyError("error: copying file {}", .{e.withPath(entry.path)}); @@ -11731,7 +11736,7 @@ pub const PackageManager = struct { const stat = in_file.stat() catch continue; _ = C.fchmod(outfile.handle, @intCast(stat.mode)); - bun.copyFileWithState(in_file.handle, outfile.handle, ©_file_state).unwrap() catch |err| { + bun.copyFileWithState(.fromStdFile(in_file), .fromStdFile(outfile), ©_file_state).unwrap() catch |err| { Output.prettyError("{s}: copying file {}", .{ @errorName(err), bun.fmt.fmtOSPath(entry.path, .{}) }); Global.crash(); }; @@ -11996,7 +12001,7 @@ pub const PackageManager = struct { var buf2: bun.PathBuffer = undefined; var buf3: bun.PathBuffer = undefined; const old_folder = old_folder: { - const cache_dir_path = switch (bun.sys.getFdPath(bun.toFD(cache_dir.fd), &buf2)) { + const cache_dir_path = switch (bun.sys.getFdPath(.fromStdDir(cache_dir), &buf2)) { .result => |s| s, .err => |e| { Output.err(e, "failed to read from cache", .{}); @@ -12027,9 +12032,9 @@ pub const PackageManager = struct { defer new_folder_handle.close(); if (bun.sys.renameatConcurrently( - bun.toFD(new_folder_handle.fd), + .fromStdDir(new_folder_handle), "node_modules", - bun.toFD(root_node_modules.fd), + .fromStdDir(root_node_modules), random_tempdir, .{ .move_fallback = true }, ).asErr()) |_| break :has_nested_node_modules false; @@ -12062,9 +12067,9 @@ pub const PackageManager = struct { defer new_folder_handle.close(); if (bun.sys.renameatConcurrently( - bun.toFD(new_folder_handle.fd), + .fromStdDir(new_folder_handle), patch_tag, - bun.toFD(root_node_modules.fd), + .fromStdDir(root_node_modules), patch_tag_tmpname, .{ .move_fallback = true }, ).asErr()) |e| { @@ -12086,9 +12091,9 @@ pub const PackageManager = struct { if (has_nested_node_modules) { if (bun.sys.renameatConcurrently( - bun.toFD(root_node_modules.fd), + .fromStdDir(root_node_modules), random_tempdir, - bun.toFD(new_folder_handle.fd), + .fromStdDir(new_folder_handle), "node_modules", .{ .move_fallback = true }, ).asErr()) |e| { @@ -12098,9 +12103,9 @@ pub const PackageManager = struct { if (bun_patch_tag) |patch_tag| { if (bun.sys.renameatConcurrently( - bun.toFD(root_node_modules.fd), + .fromStdDir(root_node_modules), patch_tag_tmpname, - bun.toFD(new_folder_handle.fd), + .fromStdDir(new_folder_handle), patch_tag, .{ .move_fallback = true }, ).asErr()) |e| { @@ -12200,7 +12205,7 @@ pub const PackageManager = struct { const tempfile_name = bun.span(try bun.fs.FileSystem.instance.tmpname("tmp", &tmpname_buf, bun.fastRandom())); const tmpdir = manager.getTemporaryDirectory(); const tmpfd = switch (bun.sys.openat( - bun.toFD(tmpdir.fd), + .fromStdDir(tmpdir), tempfile_name, bun.O.RDWR | bun.O.CREAT, 0o666, @@ -12211,7 +12216,7 @@ pub const PackageManager = struct { Global.crash(); }, }; - defer _ = bun.sys.close(tmpfd); + defer tmpfd.close(); if (bun.sys.File.writeAll(.{ .handle = tmpfd }, patchfile_contents.items).asErr()) |e| { Output.err(e, "failed to write patch to temp file", .{}); @@ -12246,7 +12251,7 @@ pub const PackageManager = struct { // rename to patches dir if (bun.sys.renameatConcurrently( - bun.toFD(tmpdir.fd), + .fromStdDir(tmpdir), tempfile_name, bun.FD.cwd(), path_in_patches_dir, @@ -12276,7 +12281,7 @@ pub const PackageManager = struct { .err => |e| return .{ .err = e }, }; defer { - _ = bun.sys.close(patch_tag_fd); + patch_tag_fd.close(); // we actually need to delete this _ = bun.sys.unlink(patch_tag_path); } @@ -12468,7 +12473,7 @@ pub const PackageManager = struct { noinline fn directoryExistsAtWithoutOpeningDirectories(this: *const NodeModulesFolder, root_node_modules_dir: std.fs.Dir, file_path: [:0]const u8) bool { var path_buf: bun.PathBuffer = undefined; const parts: [2][]const u8 = .{ this.path.items, file_path }; - return bun.sys.directoryExistsAt(bun.toFD(root_node_modules_dir), bun.path.joinZBuf(&path_buf, &parts, .auto)).unwrapOr(false); + return bun.sys.directoryExistsAt(.fromStdDir(root_node_modules_dir), bun.path.joinZBuf(&path_buf, &parts, .auto)).unwrapOr(false); } pub fn directoryExistsAt(this: *const NodeModulesFolder, root_node_modules_dir: std.fs.Dir, file_path: [:0]const u8) bool { @@ -12476,19 +12481,16 @@ pub const PackageManager = struct { return this.directoryExistsAtWithoutOpeningDirectories(root_node_modules_dir, file_path); } - const dir = this.openDir(root_node_modules_dir) catch return false; - defer { - _ = bun.sys.close(bun.toFD(dir)); - } - - return bun.sys.directoryExistsAt(bun.toFD(dir), file_path).unwrapOr(false); + const dir = FD.fromStdDir(this.openDir(root_node_modules_dir) catch return false); + defer dir.close(); + return dir.directoryExistsAt(file_path).unwrapOr(false); } // Since the stack size of these functions are rather large, let's not let them be inlined. noinline fn openFileWithoutOpeningDirectories(this: *const NodeModulesFolder, root_node_modules_dir: std.fs.Dir, file_path: [:0]const u8) bun.sys.Maybe(bun.sys.File) { var path_buf: bun.PathBuffer = undefined; const parts: [2][]const u8 = .{ this.path.items, file_path }; - return bun.sys.File.openat(bun.toFD(root_node_modules_dir), bun.path.joinZBuf(&path_buf, &parts, .auto), bun.O.RDONLY, 0); + return bun.sys.File.openat(.fromStdDir(root_node_modules_dir), bun.path.joinZBuf(&path_buf, &parts, .auto), bun.O.RDONLY, 0); } pub fn readFile(this: *const NodeModulesFolder, root_node_modules_dir: std.fs.Dir, file_path: [:0]const u8, allocator: std.mem.Allocator) !bun.sys.File.ReadToEndResult { @@ -12520,24 +12522,22 @@ pub const PackageManager = struct { } } - const dir = try this.openDir(root_node_modules_dir); - defer { - _ = bun.sys.close(bun.toFD(dir)); - } + const dir = bun.FD.fromStdDir(try this.openDir(root_node_modules_dir)); + defer dir.close(); - return try bun.sys.File.openat(bun.toFD(dir), file_path, bun.O.RDONLY, 0).unwrap(); + return try bun.sys.File.openat(dir, file_path, bun.O.RDONLY, 0).unwrap(); } pub fn openDir(this: *const NodeModulesFolder, root: std.fs.Dir) !std.fs.Dir { if (comptime Environment.isPosix) { - return (try bun.sys.openat(bun.toFD(root), &try std.posix.toPosixPath(this.path.items), bun.O.DIRECTORY, 0).unwrap()).asDir(); + return (try bun.sys.openat(.fromStdDir(root), &try std.posix.toPosixPath(this.path.items), bun.O.DIRECTORY, 0).unwrap()).stdDir(); } - return (try bun.sys.openDirAtWindowsA(bun.toFD(root), this.path.items, .{ + return (try bun.sys.openDirAtWindowsA(.fromStdDir(root), this.path.items, .{ .can_rename_or_delete = false, .create = false, .read_only = false, - }).unwrap()).asDir(); + }).unwrap()).stdDir(); } pub fn makeAndOpenDir(this: *NodeModulesFolder, root: std.fs.Dir) !std.fs.Dir { @@ -12548,11 +12548,11 @@ pub const PackageManager = struct { // TODO: is this `makePath` necessary with `.create = true` below try bun.MakePath.makePath(u8, root, this.path.items); - break :brk (try bun.sys.openDirAtWindowsA(bun.toFD(root), this.path.items, .{ + break :brk (try bun.sys.openDirAtWindowsA(.fromStdDir(root), this.path.items, .{ .can_rename_or_delete = false, .create = true, .read_only = false, - }).unwrap()).asDir(); + }).unwrap()).stdDir(); }; return out; } @@ -12712,7 +12712,7 @@ pub const PackageManager = struct { .extern_string_buf = lockfile.buffers.extern_strings.items, .seen = &this.seen_bin_links, .node_modules_path = this.node_modules.path.items, - .node_modules = bun.toFD(destination_dir), + .node_modules = .fromStdDir(destination_dir), .abs_target_buf = link_target_buf, .abs_dest_buf = link_dest_buf, .rel_buf = link_rel_buf, @@ -13654,7 +13654,7 @@ pub const PackageManager = struct { }; if (!Singleton.node_modules_is_ok) { if (!Environment.isWindows) { - const stat = bun.sys.fstat(bun.toFD(lazy_package_dir.getDir() catch |err| { + const stat = bun.sys.fstat(.fromStdDir(lazy_package_dir.getDir() catch |err| { Output.err("EACCES", "Permission denied while installing {s}", .{ this.names[package_id].slice(this.lockfile.buffers.string_bytes.items), }); @@ -14101,10 +14101,10 @@ pub const PackageManager = struct { // we want to check lazily though // no need to download packages you've already installed!! var new_node_modules = false; - const cwd = std.fs.cwd(); + const cwd = bun.FD.cwd(); const node_modules_folder = brk: { // Attempt to open the existing node_modules folder - switch (bun.sys.openatOSPath(bun.toFD(cwd), bun.OSPathLiteral("node_modules"), bun.O.DIRECTORY | bun.O.RDONLY, 0o755)) { + switch (bun.sys.openatOSPath(cwd, bun.OSPathLiteral("node_modules"), bun.O.DIRECTORY | bun.O.RDONLY, 0o755)) { .result => |fd| break :brk std.fs.Dir{ .fd = fd.cast() }, .err => {}, } @@ -14118,7 +14118,7 @@ pub const PackageManager = struct { Global.crash(); } } - break :brk bun.openDir(cwd, "node_modules") catch |err| { + break :brk bun.openDir(cwd.stdDir(), "node_modules") catch |err| { Output.err(err, "could not open the \"node_modules\" directory", .{}); Global.crash(); }; @@ -14456,7 +14456,7 @@ pub const PackageManager = struct { pub fn setupGlobalDir(manager: *PackageManager, ctx: Command.Context) !void { manager.options.global_bin_dir = try Options.openGlobalBinDir(ctx.install); var out_buffer: bun.PathBuffer = undefined; - const result = try bun.getFdPathZ(manager.options.global_bin_dir.fd, &out_buffer); + const result = try bun.getFdPathZ(.fromStdDir(manager.options.global_bin_dir), &out_buffer); const path = try FileSystem.instance.dirname_store.append([:0]u8, result); manager.options.bin_path = path.ptr[0..path.len :0]; } @@ -15710,7 +15710,7 @@ pub const bun_install_js_bindings = struct { // as long as we aren't migration from `package-lock.json`, leaving this undefined is okay const manager = globalObject.bunVM().transpiler.resolver.getPackageManager(); - const load_result: Lockfile.LoadResult = lockfile.loadFromDir(bun.toFD(dir), manager, allocator, &log, true); + const load_result: Lockfile.LoadResult = lockfile.loadFromDir(.fromStdDir(dir), manager, allocator, &log, true); switch (load_result) { .err => |err| { diff --git a/src/install/integrity.zig b/src/install/integrity.zig index 4e8f47d90e..6ae2ae1304 100644 --- a/src/install/integrity.zig +++ b/src/install/integrity.zig @@ -1,7 +1,7 @@ const std = @import("std"); const strings = @import("../string_immutable.zig"); const Crypto = @import("../sha.zig").Hashers; -const bun = @import("root").bun; +const bun = @import("bun"); pub const Integrity = extern struct { const empty_digest_buf: [Integrity.digest_buf_len]u8 = [_]u8{0} ** Integrity.digest_buf_len; diff --git a/src/install/lifecycle_script_runner.zig b/src/install/lifecycle_script_runner.zig index be630172f8..835da7fd29 100644 --- a/src/install/lifecycle_script_runner.zig +++ b/src/install/lifecycle_script_runner.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const Lockfile = @import("./lockfile.zig"); const std = @import("std"); const Async = bun.Async; diff --git a/src/install/lockfile.zig b/src/install/lockfile.zig index f2c84a7c7d..1a35ca8e3e 100644 --- a/src/install/lockfile.zig +++ b/src/install/lockfile.zig @@ -1,6 +1,6 @@ const std = @import("std"); const Allocator = std.mem.Allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const FeatureFlags = bun.FeatureFlags; const string = bun.string; const Output = bun.Output; @@ -2556,7 +2556,7 @@ pub fn saveToDisk(this: *Lockfile, load_result: *const LoadResult, options: *con else std.fmt.bufPrintZ(&tmpname_buf, ".lockb-{s}.tmp", .{std.fmt.fmtSliceHexLower(&base64_bytes)}) catch unreachable; - const file = switch (File.openat(std.fs.cwd(), tmpname, bun.O.CREAT | bun.O.WRONLY, 0o777)) { + const file = switch (File.openat(.cwd(), tmpname, bun.O.CREAT | bun.O.WRONLY, 0o777)) { .err => |err| { Output.err(err, "failed to create temporary file to save lockfile", .{}); Global.crash(); diff --git a/src/install/migration.zig b/src/install/migration.zig index fff4faad73..2cc4e9acd9 100644 --- a/src/install/migration.zig +++ b/src/install/migration.zig @@ -1,7 +1,7 @@ const std = @import("std"); const Allocator = std.mem.Allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/src/install/npm.zig b/src/install/npm.zig index 87160eaf94..b8e8c7be57 100644 --- a/src/install/npm.zig +++ b/src/install/npm.zig @@ -1,5 +1,5 @@ const URL = @import("../url.zig").URL; -const bun = @import("root").bun; +const bun = @import("bun"); const std = @import("std"); const MutableString = bun.MutableString; const Semver = bun.Semver; @@ -1077,9 +1077,10 @@ pub const PackageManifest = struct { scope: *const Registry.Scope, tmp_path: [:0]const u8, tmpdir: std.fs.Dir, - cache_dir: std.fs.Dir, + cache_dir_std: std.fs.Dir, outpath: [:0]const u8, ) !void { + const cache_dir: bun.FD = .fromStdDir(cache_dir_std); // 64 KB sounds like a lot but when you consider that this is only about 6 levels deep in the stack, it's not that much. var stack_fallback = std.heap.stackFallback(64 * 1024, bun.default_allocator); @@ -1148,7 +1149,7 @@ pub const PackageManifest = struct { } break :brk try bun.sys.File.openat( - tmpdir, + .fromStdDir(tmpdir), path_to_use_for_opening_file, flags | bun.O.CREAT | bun.O.TRUNC, if (Environment.isPosix) 0o664 else 0, @@ -1172,24 +1173,24 @@ pub const PackageManifest = struct { } else if (Environment.isLinux and is_using_o_tmpfile) { defer file.close(); // Attempt #1. - bun.sys.linkatTmpfile(file.handle, bun.toFD(cache_dir), outpath).unwrap() catch { + bun.sys.linkatTmpfile(file.handle, cache_dir, outpath).unwrap() catch { // Attempt #2: the file may already exist. Let's unlink and try again. - bun.sys.unlinkat(bun.toFD(cache_dir), outpath).unwrap() catch {}; - try bun.sys.linkatTmpfile(file.handle, bun.toFD(cache_dir), outpath).unwrap(); + bun.sys.unlinkat(cache_dir, outpath).unwrap() catch {}; + try bun.sys.linkatTmpfile(file.handle, cache_dir, outpath).unwrap(); // There is no attempt #3. This is a cache, so it's not essential. }; } else { defer file.close(); // Attempt #1. Rename the file. - const rc = bun.sys.renameat(bun.toFD(tmpdir), tmp_path, bun.toFD(cache_dir), outpath); + const rc = bun.sys.renameat(.fromStdDir(tmpdir), tmp_path, cache_dir, outpath); switch (rc) { .err => |err| { // Fallback path: atomically swap from /*.npm -> /*.npm, then unlink the temporary file. defer { // If atomically swapping fails, then we should still unlink the temporary file as a courtesy. - bun.sys.unlinkat(bun.toFD(tmpdir), tmp_path).unwrap() catch {}; + bun.sys.unlinkat(.fromStdDir(tmpdir), tmp_path).unwrap() catch {}; } if (switch (err.getErrno()) { @@ -1198,9 +1199,15 @@ pub const PackageManifest = struct { }) { // Atomically swap the old file with the new file. - try bun.sys.renameat2(bun.toFD(tmpdir.fd), tmp_path, bun.toFD(cache_dir.fd), outpath, .{ - .exchange = true, - }).unwrap(); + try bun.sys.renameat2( + .fromStdDir(tmpdir), + tmp_path, + cache_dir, + outpath, + .{ + .exchange = true, + }, + ).unwrap(); // Success. return; @@ -1283,7 +1290,7 @@ pub const PackageManifest = struct { pub fn loadByFileID(allocator: std.mem.Allocator, scope: *const Registry.Scope, cache_dir: std.fs.Dir, file_id: u64) !?PackageManifest { var file_path_buf: [512 + 64]u8 = undefined; const file_name = try manifestFileName(&file_path_buf, file_id, scope); - const cache_file = File.openat(cache_dir, file_name, bun.O.RDONLY, 0).unwrap() catch return null; + const cache_file = File.openat(.fromStdDir(cache_dir), file_name, bun.O.RDONLY, 0).unwrap() catch return null; defer cache_file.close(); delete: { @@ -1291,7 +1298,7 @@ pub const PackageManifest = struct { } // delete the outdated/invalid manifest - try bun.sys.unlinkat(bun.toFD(cache_dir), file_name).unwrap(); + try bun.sys.unlinkat(.fromStdDir(cache_dir), file_name).unwrap(); return null; } diff --git a/src/install/patch_install.zig b/src/install/patch_install.zig index 1688b99139..b4c0fa2f35 100644 --- a/src/install/patch_install.zig +++ b/src/install/patch_install.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const std = @import("std"); const string = bun.string; @@ -350,7 +350,7 @@ pub const PatchTask = struct { { const patch_pkg_dir = switch (bun.sys.openat( - bun.toFD(system_tmpdir.fd), + .fromStdDir(system_tmpdir), tempdir_name, bun.O.RDONLY | bun.O.DIRECTORY, 0, @@ -363,7 +363,7 @@ pub const PatchTask = struct { .{resolution_label}, ), }; - defer _ = bun.sys.close(patch_pkg_dir); + defer patch_pkg_dir.close(); // 4. apply patch if (patchfile.apply(this.manager.allocator, patch_pkg_dir)) |e| { @@ -397,7 +397,7 @@ pub const PatchTask = struct { ); }, }; - _ = bun.sys.close(buntagfd); + buntagfd.close(); } // 6. rename to cache dir @@ -412,9 +412,9 @@ pub const PatchTask = struct { ); if (bun.sys.renameatConcurrently( - bun.toFD(system_tmpdir.fd), + .fromStdDir(system_tmpdir), path_in_tmpdir, - bun.toFD(this.callback.apply.cache_dir.fd), + .fromStdDir(this.callback.apply.cache_dir), this.callback.apply.cache_dir_subpath, .{ .move_fallback = true }, ).asErr()) |e| return try log.addErrorFmtOpts( @@ -490,7 +490,7 @@ pub const PatchTask = struct { }, .result => |fd| fd, }; - defer _ = bun.sys.close(fd); + defer fd.close(); var hasher = bun.Wyhash11.init(0); diff --git a/src/install/repository.zig b/src/install/repository.zig index 3ca3c3c79d..4a41120cac 100644 --- a/src/install/repository.zig +++ b/src/install/repository.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const Global = bun.Global; const logger = bun.logger; const Dependency = @import("./dependency.zig"); @@ -582,7 +582,7 @@ pub const Repository = extern struct { "-c core.longpaths=true", "--quiet", "--no-checkout", - try bun.getFdPath(repo_dir.fd, &final_path_buf), + try bun.getFdPath(.fromStdDir(repo_dir), &final_path_buf), target, }) catch |err| { log.addErrorFmt( diff --git a/src/install/resolution.zig b/src/install/resolution.zig index 46d4100874..c409660eac 100644 --- a/src/install/resolution.zig +++ b/src/install/resolution.zig @@ -8,7 +8,7 @@ const string = @import("../string_types.zig").string; const ExtractTarball = @import("./extract_tarball.zig"); const strings = @import("../string_immutable.zig"); const VersionedURL = @import("./versioned_url.zig").VersionedURL; -const bun = @import("root").bun; +const bun = @import("bun"); const Path = bun.path; const JSON = bun.JSON; const OOM = bun.OOM; diff --git a/src/install/resolvers/folder_resolver.zig b/src/install/resolvers/folder_resolver.zig index 5b5d27a785..42d0dd252d 100644 --- a/src/install/resolvers/folder_resolver.zig +++ b/src/install/resolvers/folder_resolver.zig @@ -16,7 +16,7 @@ const strings = bun.strings; const Resolution = @import("../resolution.zig").Resolution; const String = bun.Semver.String; const Semver = bun.Semver; -const bun = @import("root").bun; +const bun = @import("bun"); const Dependency = @import("../dependency.zig"); pub const FolderResolution = union(Tag) { package_id: PackageID, diff --git a/src/install/versioned_url.zig b/src/install/versioned_url.zig index 917c03ee30..1bde2c93cd 100644 --- a/src/install/versioned_url.zig +++ b/src/install/versioned_url.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const Semver = bun.Semver; const String = Semver.String; diff --git a/src/install/windows-shim/BinLinkingShim.zig b/src/install/windows-shim/BinLinkingShim.zig index a76bad79ff..b73532f945 100644 --- a/src/install/windows-shim/BinLinkingShim.zig +++ b/src/install/windows-shim/BinLinkingShim.zig @@ -12,7 +12,7 @@ //! See 'bun_shim_impl.zig' for more details on how this file is consumed. const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const simdutf = bun.simdutf; const lastIndexOfScalar = std.mem.lastIndexOfScalar; diff --git a/src/install/windows-shim/bun_shim_impl.zig b/src/install/windows-shim/bun_shim_impl.zig index 31205915e6..0bcb77c211 100644 --- a/src/install/windows-shim/bun_shim_impl.zig +++ b/src/install/windows-shim/bun_shim_impl.zig @@ -47,7 +47,7 @@ const assert = std.debug.assert; const fmt16 = std.unicode.fmtUtf16Le; const is_standalone = @import("root") == @This(); -const bun = if (!is_standalone) @import("root").bun else @compileError("cannot use 'bun' in standalone build of bun_shim_impl"); +const bun = if (!is_standalone) @import("bun") else @compileError("cannot use 'bun' in standalone build of bun_shim_impl"); const bunDebugMessage = bun.Output.scoped(.bun_shim_impl, true); const callmod_inline = if (is_standalone) std.builtin.CallModifier.always_inline else bun.callmod_inline; @@ -771,9 +771,9 @@ fn launcher(comptime mode: LauncherMode, bun_ctx: anytype) mode.RetType() { .cbReserved2 = 0, .lpReserved2 = null, // The standard handles outside of standalone may be tampered with. - .hStdInput = if (is_standalone) ProcessParameters.hStdInput else bun.win32.STDIN_FD.cast(), - .hStdOutput = if (is_standalone) ProcessParameters.hStdOutput else bun.win32.STDOUT_FD.cast(), - .hStdError = if (is_standalone) ProcessParameters.hStdError else bun.win32.STDERR_FD.cast(), + .hStdInput = if (is_standalone) ProcessParameters.hStdInput else bun.FD.stdin().native(), + .hStdOutput = if (is_standalone) ProcessParameters.hStdOutput else bun.FD.stdout().native(), + .hStdError = if (is_standalone) ProcessParameters.hStdError else bun.FD.stderr().native(), }; inline for (.{ 0, 1 }) |attempt_number| iteration: { diff --git a/src/io/MaxBuf.zig b/src/io/MaxBuf.zig index b6b545cfde..b797225998 100644 --- a/src/io/MaxBuf.zig +++ b/src/io/MaxBuf.zig @@ -79,7 +79,7 @@ pub const Kind = enum { stderr, }; -const bun = @import("root").bun; +const bun = @import("bun"); const std = @import("std"); const Subprocess = bun.JSC.Subprocess; const MaxBuf = @This(); diff --git a/src/io/PipeReader.zig b/src/io/PipeReader.zig index 8111df38f7..74b857b066 100644 --- a/src/io/PipeReader.zig +++ b/src/io/PipeReader.zig @@ -917,7 +917,7 @@ pub const WindowsBufferedReader = struct { fn onFileRead(fs: *uv.fs_t) callconv(.C) void { const result = fs.result; const nread_int = result.int(); - bun.sys.syslog("onFileRead({}) = {d}", .{ bun.toFD(fs.file.fd), nread_int }); + bun.sys.syslog("onFileRead({}) = {d}", .{ bun.FD.fromUV(fs.file.fd), nread_int }); if (nread_int == uv.UV_ECANCELED) { fs.deinit(); return; @@ -1125,7 +1125,7 @@ else if (bun.Environment.isWindows) else @compileError("Unsupported platform"); -const bun = @import("root").bun; +const bun = @import("bun"); const std = @import("std"); const uv = bun.windows.libuv; const Source = @import("./source.zig").Source; diff --git a/src/io/PipeWriter.zig b/src/io/PipeWriter.zig index 0d81d90468..57f6555963 100644 --- a/src/io/PipeWriter.zig +++ b/src/io/PipeWriter.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const std = @import("std"); const Async = bun.Async; const JSC = bun.JSC; @@ -1382,10 +1382,10 @@ pub fn WindowsStreamingWriter( return .{ .err = bun.sys.Error.oom }; }; const initial_len = remain.len; - const fd = bun.toFD(this.source.?.sync_file.file); + const fd: bun.FD = .fromUV(this.source.?.sync_file.file); while (remain.len > 0) { - switch (bun.sys.write(fd, remain)) { + switch (fd.write(remain)) { .err => |err| { return .{ .err = err }; }, diff --git a/src/io/heap.zig b/src/io/heap.zig index 086ce022e4..8eec43bbdf 100644 --- a/src/io/heap.zig +++ b/src/io/heap.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const assert = bun.assert; /// An intrusive heap implementation backed by a pairing heap[1] implementation. diff --git a/src/io/io.zig b/src/io/io.zig index 12f14b11ba..9e493b9387 100644 --- a/src/io/io.zig +++ b/src/io/io.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const std = @import("std"); const sys = bun.sys; const linux = std.os.linux; @@ -16,7 +16,7 @@ pub const Source = @import("./source.zig").Source; pub const Loop = struct { pending: Request.Queue = .{}, waker: bun.Async.Waker, - epoll_fd: if (Environment.isLinux) bun.FileDescriptor else u0 = if (Environment.isLinux) .zero else 0, + epoll_fd: if (Environment.isLinux) bun.FileDescriptor else void = if (Environment.isLinux) .invalid, cached_now: posix.timespec = .{ .nsec = 0, @@ -31,7 +31,7 @@ pub const Loop = struct { .waker = bun.Async.Waker.init() catch @panic("failed to initialize waker"), }; if (comptime Environment.isLinux) { - loop.epoll_fd = bun.toFD(std.posix.epoll_create1(std.os.linux.EPOLL.CLOEXEC | 0) catch @panic("Failed to create epoll file descriptor")); + loop.epoll_fd = .fromNative(std.posix.epoll_create1(std.os.linux.EPOLL.CLOEXEC | 0) catch @panic("Failed to create epoll file descriptor")); { var epoll = std.mem.zeroes(std.os.linux.epoll_event); @@ -526,7 +526,7 @@ pub const Poll = struct { kqueue_event.* = switch (comptime action) { .readable => .{ - .ident = @as(u64, @intCast(fd.int())), + .ident = @as(u64, @intCast(fd.native())), .filter = std.posix.system.EVFILT.READ, .data = 0, .fflags = 0, @@ -535,7 +535,7 @@ pub const Poll = struct { .ext = .{ generation_number_monotonic, 0 }, }, .writable => .{ - .ident = @as(u64, @intCast(fd.int())), + .ident = @as(u64, @intCast(fd.native())), .filter = std.posix.system.EVFILT.WRITE, .data = 0, .fflags = 0, @@ -544,7 +544,7 @@ pub const Poll = struct { .ext = .{ generation_number_monotonic, 0 }, }, .cancel => if (poll.flags.contains(.poll_readable)) .{ - .ident = @as(u64, @intCast(fd.int())), + .ident = @as(u64, @intCast(fd.native())), .filter = std.posix.system.EVFILT.READ, .data = 0, .fflags = 0, @@ -552,7 +552,7 @@ pub const Poll = struct { .flags = std.c.EV.DELETE, .ext = .{ poll.generation_number, 0 }, } else if (poll.flags.contains(.poll_writable)) .{ - .ident = @as(u64, @intCast(fd.int())), + .ident = @as(u64, @intCast(fd.native())), .filter = std.posix.system.EVFILT.WRITE, .data = 0, .fflags = 0, diff --git a/src/io/pipes.zig b/src/io/pipes.zig index f6fb46053a..5919a1d4aa 100644 --- a/src/io/pipes.zig +++ b/src/io/pipes.zig @@ -1,5 +1,5 @@ const Async = bun.Async; -const bun = @import("root").bun; +const bun = @import("bun"); const Environment = bun.Environment; pub const PollOrFd = union(enum) { @@ -59,11 +59,11 @@ pub const PollOrFd = union(enum) { //TODO: We should make this call compatible using bun.FileDescriptor if (Environment.isWindows) { - bun.Async.Closer.close(bun.uvfdcast(fd), bun.windows.libuv.Loop.get()); + bun.Async.Closer.close(fd, bun.windows.libuv.Loop.get()); } else if (close_async and close_fd) { bun.Async.Closer.close(fd, {}); } else { - if (close_fd) _ = bun.sys.close(fd); + if (close_fd) _ = fd.closeAllowingBadFileDescriptor(null); } if (comptime @TypeOf(onCloseFn) != void) onCloseFn(@alignCast(@ptrCast(ctx.?))); diff --git a/src/io/source.zig b/src/io/source.zig index 99447a44b8..a37c62ac95 100644 --- a/src/io/source.zig +++ b/src/io/source.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const uv = bun.windows.libuv; const log = bun.Output.scoped(.PipeSource, true); @@ -58,7 +58,7 @@ pub const Source = union(enum) { return switch (this) { .pipe => |pipe| pipe.fd(), .tty => |tty| tty.fd(), - .sync_file, .file => |file| bun.FDImpl.fromUV(file.file).encode(), + .sync_file, .file => |file| .fromUV(file.file), }; } @@ -129,7 +129,7 @@ pub const Source = union(enum) { pub fn openTty(loop: *uv.Loop, fd: bun.FileDescriptor) bun.JSC.Maybe(*Source.Tty) { log("openTTY (fd = {})", .{fd}); - const uv_fd = bun.uvfdcast(fd); + const uv_fd = fd.uv(); if (uv_fd == 0) { if (!stdin_tty_init) { @@ -151,17 +151,17 @@ pub const Source = union(enum) { } pub fn openFile(fd: bun.FileDescriptor) *Source.File { - bun.assert(fd.isValid() and bun.uvfdcast(fd) != -1); + bun.assert(fd.isValid() and fd.uv() != -1); log("openFile (fd = {})", .{fd}); const file = bun.default_allocator.create(Source.File) catch bun.outOfMemory(); file.* = std.mem.zeroes(Source.File); - file.file = bun.uvfdcast(fd); + file.file = fd.uv(); return file; } pub fn open(loop: *uv.Loop, fd: bun.FileDescriptor) bun.JSC.Maybe(Source) { - const rc = bun.windows.libuv.uv_guess_handle(bun.uvfdcast(fd)); + const rc = bun.windows.libuv.uv_guess_handle(fd.uv()); log("open(fd: {}, type: {d})", .{ fd, @tagName(rc) }); switch (rc) { @@ -224,7 +224,7 @@ pub const Source = union(enum) { }; export fn Source__setRawModeStdin(raw: bool) c_int { - const tty = switch (Source.openTty(bun.JSC.VirtualMachine.get().uvLoop(), bun.STDIN_FD)) { + const tty = switch (Source.openTty(bun.JSC.VirtualMachine.get().uvLoop(), .stdin())) { .result => |tty| tty, .err => |e| return e.errno, }; diff --git a/src/io/time.zig b/src/io/time.zig index 4d58360f01..b8cd57766e 100644 --- a/src/io/time.zig +++ b/src/io/time.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const assert = bun.assert; const is_darwin = @import("builtin").target.isDarwin(); diff --git a/src/js_ast.zig b/src/js_ast.zig index 11da3a4ae3..d94460d931 100644 --- a/src/js_ast.zig +++ b/src/js_ast.zig @@ -2,7 +2,7 @@ const std = @import("std"); const logger = bun.logger; const JSXRuntime = @import("options.zig").JSX.Runtime; const Runtime = @import("runtime.zig").Runtime; -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; @@ -1566,7 +1566,7 @@ pub const E = struct { pub const Boolean = struct { value: bool, - pub fn toJS(this: @This(), ctx: JSC.C.JSContextRef) JSC.C.JSValueRef { + pub fn toJS(this: @This(), ctx: *JSC.JSGlobalObject) JSC.C.JSValueRef { return JSC.C.JSValueMakeBoolean(ctx, this.value); } }; diff --git a/src/js_lexer.zig b/src/js_lexer.zig index 264d80dea8..408e44c98f 100644 --- a/src/js_lexer.zig +++ b/src/js_lexer.zig @@ -4,7 +4,7 @@ const tables = @import("js_lexer_tables.zig"); const build_options = @import("build_options"); const js_ast = bun.JSAst; -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/src/js_lexer_tables.zig b/src/js_lexer_tables.zig index bb01d4112f..33d194a5bb 100644 --- a/src/js_lexer_tables.zig +++ b/src/js_lexer_tables.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const expectString = std.testing.expectEqualStrings; const expect = std.testing.expect; const logger = bun.logger; diff --git a/src/js_parser.zig b/src/js_parser.zig index 8142510c48..14bf169d24 100644 --- a/src/js_parser.zig +++ b/src/js_parser.zig @@ -3,7 +3,7 @@ /// ** you must also increment the `expected_version` in RuntimeTranspilerCache.zig ** /// ** IMPORTANT ** pub const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); pub const logger = bun.logger; pub const js_lexer = bun.js_lexer; pub const importRecord = @import("./import_record.zig"); diff --git a/src/js_printer.zig b/src/js_printer.zig index 5348d09f65..a94951f00e 100644 --- a/src/js_printer.zig +++ b/src/js_printer.zig @@ -9,7 +9,7 @@ const runtime = @import("runtime.zig"); const Lock = bun.Mutex; const Api = @import("./api/schema.zig").Api; const fs = @import("fs.zig"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/src/jsc.zig b/src/jsc.zig index 718f26fca8..59477eaafd 100644 --- a/src/jsc.zig +++ b/src/jsc.zig @@ -101,12 +101,18 @@ pub const Subprocess = API.Bun.Subprocess; /// 1. `bun src/bun.js/scripts/generate-classes.ts` /// 2. Scan for **/*.classes.ts files in src/bun.js/src /// 3. Generate a JS wrapper for each class in: -/// - Zig: generated_classes.zig -/// - C++: ZigGeneratedClasses.h, ZigGeneratedClasses.cpp +/// - Zig: generated_classes.zig +/// - C++: ZigGeneratedClasses.h, ZigGeneratedClasses.cpp /// 4. For the Zig code to successfully compile: -/// - Add it to generated_classes_list.zig -/// - pub usingnamespace JSC.Codegen.JSMyClassName; -/// 5. make clean-bindings && make bindings -j10 +/// - Add it to generated_classes_list.zig +/// - Expose the generated methods: +/// ```zig +/// pub const js = JSC.Codegen.JSMyClassName; +/// pub const toJS = js.toJS; +/// pub const fromJS = js.fromJS; +/// pub const fromJSDirect = js.fromJSDirect; +/// ``` +/// 5. `bun run build` /// pub const Codegen = @import("ZigGeneratedClasses"); pub const GeneratedClassesList = @import("./bun.js/bindings/generated_classes_list.zig").Classes; @@ -114,7 +120,7 @@ pub const GeneratedClassesList = @import("./bun.js/bindings/generated_classes_li pub const RuntimeTranspilerCache = @import("./bun.js/RuntimeTranspilerCache.zig").RuntimeTranspilerCache; /// The calling convention used for JavaScript functions <> Native -const bun = @import("root").bun; +const bun = @import("bun"); pub const conv = if (bun.Environment.isWindows and bun.Environment.isX64) std.builtin.CallingConvention.SysV else diff --git a/src/json_parser.zig b/src/json_parser.zig index 7bfb63d935..92176f447a 100644 --- a/src/json_parser.zig +++ b/src/json_parser.zig @@ -6,7 +6,7 @@ const js_ast = bun.JSAst; const options = @import("options.zig"); const BabyList = @import("./baby_list.zig").BabyList; const fs = @import("fs.zig"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/src/libarchive/libarchive-bindings.zig b/src/libarchive/libarchive-bindings.zig index f8ec3f8f79..dbf7e5dc1c 100644 --- a/src/libarchive/libarchive-bindings.zig +++ b/src/libarchive/libarchive-bindings.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const wchar_t = u16; const la_int64_t = i64; const la_ssize_t = isize; diff --git a/src/libarchive/libarchive.zig b/src/libarchive/libarchive.zig index d64b2284fc..1c20f2cff2 100644 --- a/src/libarchive/libarchive.zig +++ b/src/libarchive/libarchive.zig @@ -1,7 +1,7 @@ // @link "../deps/libarchive.a" pub const lib = @import("./libarchive-bindings.zig"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; @@ -213,12 +213,13 @@ pub const Archiver = struct { contents: MutableString, filename_hash: u64 = 0, found: bool = false, - fd: FileDescriptorType = .zero, + fd: FileDescriptorType, + pub fn init(filepath: bun.OSPathSlice, estimated_size: usize, allocator: std.mem.Allocator) !Plucker { return Plucker{ .contents = try MutableString.init(allocator, estimated_size), .filename_hash = bun.hash(std.mem.sliceAsBytes(filepath)), - .fd = .zero, + .fd = .invalid, .found = false, }; } @@ -450,11 +451,11 @@ pub const Archiver = struct { .sym_link => { const link_target = entry.symlink(); if (Environment.isPosix) { - bun.sys.symlinkat(link_target, bun.toFD(dir_fd), path).unwrap() catch |err| brk: { + bun.sys.symlinkat(link_target, .fromNative(dir_fd), path).unwrap() catch |err| brk: { switch (err) { error.EPERM, error.ENOENT => { dir.makePath(std.fs.path.dirname(path_slice) orelse return err) catch {}; - break :brk try bun.sys.symlinkat(link_target, bun.toFD(dir_fd), path).unwrap(); + break :brk try bun.sys.symlinkat(link_target, .fromNative(dir_fd), path).unwrap(); }, else => return err, } @@ -470,41 +471,39 @@ pub const Archiver = struct { // we simplify and turn it into `entry.mode || 0o666` because we aren't accepting a umask or fmask option. const mode: bun.Mode = if (comptime Environment.isWindows) 0 else @intCast(entry.perm() | 0o666); - const file_handle_native = brk: { - if (Environment.isWindows) { - const flags = bun.O.WRONLY | bun.O.CREAT | bun.O.TRUNC; - switch (bun.sys.openatWindows(bun.toFD(dir_fd), path, flags, 0)) { - .result => |fd| break :brk fd, - .err => |e| switch (e.errno) { - @intFromEnum(bun.C.E.PERM), @intFromEnum(bun.C.E.NOENT) => { - bun.MakePath.makePath(u16, dir, bun.Dirname.dirname(u16, path_slice) orelse return bun.errnoToZigErr(e.errno)) catch {}; - break :brk try bun.sys.openatWindows(bun.toFD(dir_fd), path, flags, 0).unwrap(); - }, - else => { - return bun.errnoToZigErr(e.errno); - }, + const flags = bun.O.WRONLY | bun.O.CREAT | bun.O.TRUNC; + const file_handle_native: bun.FD = if (Environment.isWindows) + switch (bun.sys.openatWindows(.fromNative(dir_fd), path, flags, 0)) { + .result => |fd| fd, + .err => |e| switch (e.errno) { + @intFromEnum(bun.C.E.PERM), + @intFromEnum(bun.C.E.NOENT), + => brk: { + bun.MakePath.makePath(u16, dir, bun.Dirname.dirname(u16, path_slice) orelse return bun.errnoToZigErr(e.errno)) catch {}; + break :brk try bun.sys.openatWindows(.fromNative(dir_fd), path, flags, 0).unwrap(); }, - } - } else { - break :brk (dir.createFileZ(path, .{ .truncate = true, .mode = mode }) catch |err| { - switch (err) { - error.AccessDenied, error.FileNotFound => { - dir.makePath(std.fs.path.dirname(path_slice) orelse return err) catch {}; - break :brk (try dir.createFileZ(path, .{ - .truncate = true, - .mode = mode, - })).handle; - }, - else => { - return err; - }, - } - }).handle; + else => return bun.errnoToZigErr(e.errno), + }, } - }; + else + .fromStdFile(dir.createFileZ(path, .{ + .truncate = true, + .mode = mode, + }) catch |err| + switch (err) { + error.AccessDenied, error.FileNotFound => brk: { + dir.makePath(std.fs.path.dirname(path_slice) orelse return err) catch {}; + break :brk try dir.createFileZ(path, .{ + .truncate = true, + .mode = mode, + }); + }, + else => return err, + }); + const file_handle = brk: { - errdefer _ = bun.sys.close(file_handle_native); - break :brk try bun.toLibUVOwnedFD(file_handle_native); + errdefer _ = file_handle_native.close(); + break :brk try file_handle_native.makeLibUVOwned(); }; var plucked_file = false; @@ -522,7 +521,7 @@ pub const Archiver = struct { // But this approach does not actually solve the problem, it just // defers the close to a different thread. And since we are already // on a worker thread, that doesn't help us. - _ = bun.sys.close(file_handle); + file_handle.close(); }; const size: usize = @intCast(@max(entry.size(), 0)); @@ -567,7 +566,7 @@ pub const Archiver = struct { var retries_remaining: u8 = 5; possibly_retry: while (retries_remaining != 0) : (retries_remaining -= 1) { - switch (archive.readDataIntoFd(bun.uvfdcast(file_handle))) { + switch (archive.readDataIntoFd(file_handle.uv())) { .eof => break :loop, .ok => break :possibly_retry, .retry => { diff --git a/src/linear_fifo.zig b/src/linear_fifo.zig index 00ceeeb5b5..10d67aec97 100644 --- a/src/linear_fifo.zig +++ b/src/linear_fifo.zig @@ -11,7 +11,7 @@ const Allocator = mem.Allocator; const debug = std.debug; const assert = debug.assert; const testing = std.testing; -const bun = @import("root").bun; +const bun = @import("bun"); pub const LinearFifoBufferType = union(enum) { /// The buffer is internal to the fifo; it is of the specified size. diff --git a/src/linker.zig b/src/linker.zig index 6997bc3e8b..0579796cdb 100644 --- a/src/linker.zig +++ b/src/linker.zig @@ -1,5 +1,5 @@ // This file is the old linker, used by Bun.Transpiler. -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; @@ -101,7 +101,7 @@ pub const Linker = struct { file_path: Fs.Path, fd: ?FileDescriptorType, ) !Fs.FileSystem.RealFS.ModKey { - var file: std.fs.File = if (fd) |_fd| _fd.asFile() else try std.fs.openFileAbsolute(file_path.text, .{ .mode = .read_only }); + var file: std.fs.File = if (fd) |_fd| _fd.stdFile() else try std.fs.openFileAbsolute(file_path.text, .{ .mode = .read_only }); Fs.FileSystem.setMaxFd(file.handle); const modkey = try Fs.FileSystem.RealFS.ModKey.generate(&this.fs.fs, file_path.text, file); diff --git a/src/linux_c.zig b/src/linux_c.zig index 52588080ed..57638ecc2e 100644 --- a/src/linux_c.zig +++ b/src/linux_c.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); pub extern "c" fn memmem(haystack: [*]const u8, haystacklen: usize, needle: [*]const u8, needlelen: usize) ?[*]const u8; pub const SystemErrno = enum(u8) { SUCCESS = 0, @@ -547,7 +547,7 @@ pub const linux_fs = bun.c; /// /// Support for FICLONE is dependent on the filesystem driver. pub fn ioctl_ficlone(dest_fd: bun.FileDescriptor, srcfd: bun.FileDescriptor) usize { - return std.os.linux.ioctl(dest_fd.cast(), bun.c.FICLONE, @intCast(srcfd.int())); + return std.os.linux.ioctl(dest_fd.cast(), bun.c.FICLONE, @intCast(srcfd.native())); } pub const RWFFlagSupport = enum(u8) { diff --git a/src/logger.zig b/src/logger.zig index 4d83d1c411..e9315e5d04 100644 --- a/src/logger.zig +++ b/src/logger.zig @@ -2,7 +2,7 @@ const std = @import("std"); const Api = @import("./api/schema.zig").Api; const js = bun.JSC; const ImportKind = @import("./import_record.zig").ImportKind; -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/src/macho.zig b/src/macho.zig index c5bbca81d2..f147dfe72f 100644 --- a/src/macho.zig +++ b/src/macho.zig @@ -4,7 +4,7 @@ const fs = std.fs; const io = std.io; const macho = std.macho; const Allocator = mem.Allocator; -const bun = @import("root").bun; +const bun = @import("bun"); pub const SEGNAME_BUN = "__BUN\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".*; pub const SECTNAME = "__bun\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".*; diff --git a/src/main.zig b/src/main.zig index 07bf7dd81b..93d75179f3 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1,6 +1,6 @@ const std = @import("std"); const builtin = @import("builtin"); -pub const bun = @import("./bun.zig"); +pub const bun = @import("bun"); const Output = bun.Output; const Environment = bun.Environment; @@ -54,7 +54,7 @@ pub fn main() void { Output.Source.Stdio.init(); defer Output.flush(); if (Environment.isX64 and Environment.enableSIMD and Environment.isPosix) { - bun_warn_avx_missing(@import("./cli/upgrade_command.zig").Version.Bun__githubBaselineURL.ptr); + bun_warn_avx_missing(bun.CLI.UpgradeCommand.Bun__githubBaselineURL.ptr); } bun.StackCheck.configureThread(); diff --git a/src/main_wasm.zig b/src/main_wasm.zig index 41f5374fc9..ec8971dc98 100644 --- a/src/main_wasm.zig +++ b/src/main_wasm.zig @@ -1,10 +1,10 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const JSParser = bun.js_parser; const JSPrinter = bun.js_printer; const JSAst = bun.JSAst; const Api = @import("./api/schema.zig").Api; const Logger = bun.logger; -const global = @import("root").bun; +const global = @import("bun"); const default_allocator = global.default_allocator; const std = @import("std"); const Define = @import("./defines.zig"); diff --git a/src/meta.zig b/src/meta.zig index 95573ec620..49d5b794dc 100644 --- a/src/meta.zig +++ b/src/meta.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); pub fn OptionalChild(comptime T: type) type { const tyinfo = @typeInfo(T); @@ -284,6 +284,7 @@ pub fn isSimpleEqlType(comptime T: type) bool { .int => true, .float => true, .@"enum" => true, + .@"struct" => |struct_info| struct_info.layout == .@"packed", else => false, }; } diff --git a/src/multi_array_list.zig b/src/multi_array_list.zig index c6bd265ea7..1224a5338d 100644 --- a/src/multi_array_list.zig +++ b/src/multi_array_list.zig @@ -1,6 +1,6 @@ const std = @import("std"); const builtin = @import("builtin"); -const bun = @import("root").bun; +const bun = @import("bun"); const assert = bun.assert; const meta = std.meta; const mem = std.mem; diff --git a/src/napi/napi.zig b/src/napi/napi.zig index 0b85f55a52..897e19f623 100644 --- a/src/napi/napi.zig +++ b/src/napi/napi.zig @@ -1,7 +1,7 @@ const std = @import("std"); const JSC = bun.JSC; const strings = bun.strings; -const bun = @import("root").bun; +const bun = @import("bun"); const Lock = bun.Mutex; const JSValue = JSC.JSValue; const ZigString = JSC.ZigString; diff --git a/src/node_fallbacks.zig b/src/node_fallbacks.zig index 3f1bb0d9ba..eeecaac261 100644 --- a/src/node_fallbacks.zig +++ b/src/node_fallbacks.zig @@ -3,7 +3,7 @@ const string = @import("./string_types.zig").string; const PackageJSON = @import("./resolver/package_json.zig").PackageJSON; const logger = bun.logger; const Fs = @import("./fs.zig"); -const bun = @import("root").bun; +const bun = @import("bun"); const Environment = bun.Environment; pub const import_path = "/bun-vfs$$/node_modules/"; diff --git a/src/open.zig b/src/open.zig index e954892080..250e187b72 100644 --- a/src/open.zig +++ b/src/open.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/src/options.zig b/src/options.zig index 5b4b76cc18..0a508aed16 100644 --- a/src/options.zig +++ b/src/options.zig @@ -10,7 +10,7 @@ const Api = api.Api; const resolve_path = @import("./resolver/resolve_path.zig"); const URL = @import("./url.zig").URL; const ConditionsMap = @import("./resolver/package_json.zig").ESModule.ConditionsMap; -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; @@ -2032,7 +2032,7 @@ pub const BundleOptions = struct { if (opts.write and opts.output_dir.len > 0) { opts.output_dir_handle = try openOutputDir(opts.output_dir); - opts.output_dir = try fs.getFdPath(bun.toFD(opts.output_dir_handle.?.fd)); + opts.output_dir = try fs.getFdPath(.fromStdDir(opts.output_dir_handle.?)); } opts.polyfill_node_globals = opts.target == .browser; @@ -2351,12 +2351,6 @@ pub const RouteConfig = struct { extensions: []const string = &[_]string{}, routes_enabled: bool = false, - static_dir: string = "", - static_dir_handle: ?std.fs.Dir = null, - static_dir_enabled: bool = false, - single_page_app_routing: bool = false, - single_page_app_fd: StoredFileDescriptorType = .zero, - pub fn toAPI(this: *const RouteConfig) Api.LoadedRouteConfig { return .{ .asset_prefix = this.asset_prefix_path, diff --git a/src/output.zig b/src/output.zig index b9b3e429ab..9a4d4acba3 100644 --- a/src/output.zig +++ b/src/output.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const std = @import("std"); const Environment = @import("./env.zig"); const string = bun.string; @@ -188,11 +188,14 @@ pub const Source = struct { const stdout = std.os.windows.GetStdHandle(std.os.windows.STD_OUTPUT_HANDLE) catch w.INVALID_HANDLE_VALUE; const stderr = std.os.windows.GetStdHandle(std.os.windows.STD_ERROR_HANDLE) catch w.INVALID_HANDLE_VALUE; - bun.win32.STDERR_FD = if (stderr != std.os.windows.INVALID_HANDLE_VALUE) bun.toFD(stderr) else bun.invalid_fd; - bun.win32.STDOUT_FD = if (stdout != std.os.windows.INVALID_HANDLE_VALUE) bun.toFD(stdout) else bun.invalid_fd; - bun.win32.STDIN_FD = if (stdin != std.os.windows.INVALID_HANDLE_VALUE) bun.toFD(stdin) else bun.invalid_fd; + const fd_internals = @import("fd.zig"); + const INVALID_HANDLE_VALUE = std.os.windows.INVALID_HANDLE_VALUE; + fd_internals.windows_cached_stderr = if (stderr != INVALID_HANDLE_VALUE) .fromSystem(stderr) else .invalid; + fd_internals.windows_cached_stdout = if (stdout != INVALID_HANDLE_VALUE) .fromSystem(stdout) else .invalid; + fd_internals.windows_cached_stdin = if (stdin != INVALID_HANDLE_VALUE) .fromSystem(stdin) else .invalid; + if (Environment.isDebug) fd_internals.windows_cached_fd_set = true; - buffered_stdin.unbuffered_reader.context.handle = bun.win32.STDIN_FD; + buffered_stdin.unbuffered_reader.context.handle = .stdin(); // https://learn.microsoft.com/en-us/windows/console/setconsoleoutputcp const CP_UTF8 = 65001; @@ -1201,13 +1204,13 @@ pub fn initScopedDebugWriterAtStartup() void { const path_fmt = std.mem.replaceOwned(u8, bun.default_allocator, path, "{pid}", pid) catch @panic("failed to allocate path"); defer bun.default_allocator.free(path_fmt); - const fd = std.fs.cwd().createFile(path_fmt, .{ + const fd: bun.FD = .fromStdFile(std.fs.cwd().createFile(path_fmt, .{ .mode = if (Environment.isPosix) 0o644 else 0, }) catch |open_err| { panic("Failed to open file for debug output: {s} ({s})", .{ @errorName(open_err), path }); - }; - _ = bun.sys.ftruncate(bun.toFD(fd), 0); // windows - ScopedDebugWriter.scoped_file_writer = File.from(fd).quietWriter(); + }); + _ = fd.truncate(0); // windows + ScopedDebugWriter.scoped_file_writer = fd.quietWriter(); return; } } @@ -1232,8 +1235,6 @@ pub inline fn errFmt(formatter: anytype) void { return errGeneric("{}", .{formatter}); } -/// This struct is a workaround a Windows terminal bug. -/// TODO: when https://github.com/microsoft/terminal/issues/16606 is resolved, revert this commit. pub var buffered_stdin = std.io.BufferedReader(4096, File.Reader){ - .unbuffered_reader = File.Reader{ .context = .{ .handle = if (Environment.isWindows) undefined else bun.toFD(0) } }, + .unbuffered_reader = .{ .context = .{ .handle = if (Environment.isWindows) undefined else .stdin() } }, }; diff --git a/src/patch.zig b/src/patch.zig index f00e929736..a5c9263f02 100644 --- a/src/patch.zig +++ b/src/patch.zig @@ -1,7 +1,7 @@ const Output = bun.Output; const Global = bun.Global; const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const Allocator = std.mem.Allocator; const List = std.ArrayListUnmanaged; @@ -120,7 +120,7 @@ pub const PatchFile = struct { .result => |fd| fd, .err => |e| return e.withoutPath(), }; - defer _ = bun.sys.close(newfile_fd); + defer newfile_fd.close(); const hunk = part.file_creation.hunk orelse { continue; @@ -192,7 +192,7 @@ pub const PatchFile = struct { .err => |e| return e.withoutPath(), .result => |f| f, }; - defer _ = bun.sys.close(fd); + defer fd.close(); if (bun.sys.fchmod(fd, newmode.toBunMode()).asErr()) |e| { return e.withoutPath(); } @@ -242,7 +242,7 @@ pub const PatchFile = struct { // to use the arena const use_arena: bool = stat.size <= PAGE_SIZE; const file_alloc = if (use_arena) arena.allocator() else bun.default_allocator; - const filebuf = patch_dir.asDir().readFileAlloc(file_alloc, file_path, 1024 * 1024 * 1024 * 4) catch return .{ .err = bun.sys.Error.fromCode(.INVAL, .read).withPath(file_path) }; + const filebuf = patch_dir.stdDir().readFileAlloc(file_alloc, file_path, 1024 * 1024 * 1024 * 4) catch return .{ .err = bun.sys.Error.fromCode(.INVAL, .read).withPath(file_path) }; defer file_alloc.free(filebuf); var file_line_count: usize = 0; @@ -323,9 +323,7 @@ pub const PatchFile = struct { .err => |e| return .{ .err = e.withPath(file_path) }, .result => |fd| fd, }; - defer { - _ = bun.sys.close(file_fd); - } + defer file_fd.close(); const contents = std.mem.join(bun.default_allocator, "\n", lines.items) catch bun.outOfMemory(); defer bun.default_allocator.free(contents); @@ -1121,8 +1119,9 @@ pub const TestingAPIs = struct { pub fn deinit(this: *ApplyArgs) void { this.patchfile_txt.deinit(); this.patchfile.deinit(bun.default_allocator); - if (bun.FileDescriptor.cwd().eq(this.dirfd)) { - _ = bun.sys.close(this.dirfd); + // TODO: HAVE @zackradisic REVIEW THIS DIFF + if (bun.FileDescriptor.cwd() != this.dirfd) { + this.dirfd.close(); } } }; @@ -1193,8 +1192,9 @@ pub const TestingAPIs = struct { const patchfile_src = patchfile_bunstr.toUTF8(bun.default_allocator); const patch_file = parsePatchFile(patchfile_src.slice()) catch |e| { - if (bun.FileDescriptor.cwd().eq(dir_fd)) { - _ = bun.sys.close(dir_fd); + // TODO: HAVE @zackradisic REVIEW THIS DIFF + if (bun.FileDescriptor.cwd() != dir_fd) { + dir_fd.close(); } patchfile_src.deinit(); diff --git a/src/perf.zig b/src/perf.zig index 196f1a83a9..c717486f1f 100644 --- a/src/perf.zig +++ b/src/perf.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const std = @import("std"); pub const Ctx = union(enum) { diff --git a/src/pool.zig b/src/pool.zig index 30e5d3e31f..4f82af19da 100644 --- a/src/pool.zig +++ b/src/pool.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); fn SinglyLinkedList(comptime T: type, comptime Parent: type) type { return struct { diff --git a/src/ptr/CowSlice.zig b/src/ptr/CowSlice.zig index 409363e69d..7172d5ee99 100644 --- a/src/ptr/CowSlice.zig +++ b/src/ptr/CowSlice.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Allocator = std.mem.Allocator; const Environment = bun.Environment; const AllocationScope = bun.AllocationScope; diff --git a/src/ptr/ref_count.zig b/src/ptr/ref_count.zig index d7be1a085e..a1bc5d96a5 100644 --- a/src/ptr/ref_count.zig +++ b/src/ptr/ref_count.zig @@ -129,10 +129,9 @@ pub fn RefCount(T: type, field_name: []const u8, destructor: fn (*T) void, optio // utility functions - pub fn hasOneRef(self: *T) bool { - const counter = getCounter(self); - counter.assertNonThreadSafeCountIsSingleThreaded(); - return counter.active_counts == 1; + pub fn hasOneRef(count: *const @This()) bool { + count.assertNonThreadSafeCountIsSingleThreaded(); + return count.active_counts == 1; } pub fn dumpActiveRefs(count: *@This()) void { @@ -234,9 +233,8 @@ pub fn ThreadSafeRefCount(T: type, field_name: []const u8, destructor: fn (*T) v // utility functions - pub fn hasOneRef(self: *T) bool { - if (enable_debug) getCounter(self).debug.assertValid(); - const counter = getCounter(self); + pub fn hasOneRef(counter: *const @This()) bool { + if (enable_debug) counter.debug.assertValid(); return counter.active_counts.load(.seq_cst) == 1; } @@ -316,9 +314,9 @@ pub fn RefPtr(T: type) type { pub fn adoptRef(raw_ptr: *T) @This() { if (enable_debug) { bun.assert(raw_ptr.ref_count.hasOneRef()); - bun.assert(!raw_ptr.ref_count.debug.isEmpty()); + raw_ptr.ref_count.debug.assertValid(); } - return uncheckedAndUnsafeInit(raw_ptr); + return uncheckedAndUnsafeInit(raw_ptr, @returnAddress()); } /// This will assert that ALL references are cleaned up by the time the allocation scope ends. @@ -392,7 +390,7 @@ pub fn DebugData(thread_safe: bool) type { .count_pointer = null, }; - fn assertValid(debug: *@This()) void { + fn assertValid(debug: *const @This()) void { bun.assert(debug.magic == .valid); } @@ -501,6 +499,6 @@ pub fn maybeAssertNoRefs(T: type, ptr: *const T) void { } const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const assert = bun.assert; const AllocationScope = bun.AllocationScope; diff --git a/src/ptr/tagged_pointer.zig b/src/ptr/tagged_pointer.zig index b01cd725d0..b573dfed6a 100644 --- a/src/ptr/tagged_pointer.zig +++ b/src/ptr/tagged_pointer.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/src/ptr/weak_ptr.zig b/src/ptr/weak_ptr.zig index cf2da36f13..eeff343d76 100644 --- a/src/ptr/weak_ptr.zig +++ b/src/ptr/weak_ptr.zig @@ -66,5 +66,5 @@ pub fn WeakPtr(comptime T: type, data_field: []const u8) type { }; } -pub const bun = @import("root").bun; +pub const bun = @import("bun"); const std = @import("std"); diff --git a/src/renamer.zig b/src/renamer.zig index 5526bf4b24..628ac2d9dc 100644 --- a/src/renamer.zig +++ b/src/renamer.zig @@ -1,5 +1,5 @@ const js_ast = bun.JSAst; -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/src/resolver/data_url.zig b/src/resolver/data_url.zig index 991967286c..f8b1116f86 100644 --- a/src/resolver/data_url.zig +++ b/src/resolver/data_url.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/src/resolver/dir_info.zig b/src/resolver/dir_info.zig index 5ff0767b54..bffa2ff06e 100644 --- a/src/resolver/dir_info.zig +++ b/src/resolver/dir_info.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const std = @import("std"); const string = bun.string; const Output = bun.Output; @@ -77,15 +77,10 @@ pub fn hasParentPackage(this: *const DirInfo) bool { } pub fn getFileDescriptor(dirinfo: *const DirInfo) StoredFileDescriptorType { - if (!FeatureFlags.store_file_descriptors) { - return .zero; - } - - if (dirinfo.getEntries(0)) |entries| { - return entries.fd; - } else { - return .zero; - } + if (FeatureFlags.store_file_descriptors) + if (dirinfo.getEntries(0)) |entries| + return entries.fd; + return .invalid; } pub fn getEntries(dirinfo: *const DirInfo, generation: bun.Generation) ?*Fs.FileSystem.DirEntry { diff --git a/src/resolver/package_json.zig b/src/resolver/package_json.zig index e59ff37d57..4162430543 100644 --- a/src/resolver/package_json.zig +++ b/src/resolver/package_json.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/src/resolver/resolve_path.zig b/src/resolver/resolve_path.zig index f5d6326bbd..1b80d7fbaa 100644 --- a/src/resolver/resolve_path.zig +++ b/src/resolver/resolve_path.zig @@ -1,7 +1,7 @@ const std = @import("std"); const strings = @import("../string_immutable.zig"); const FeatureFlags = @import("../feature_flags.zig"); -const bun = @import("root").bun; +const bun = @import("bun"); const Fs = @import("../fs.zig"); threadlocal var parser_join_input_buffer: [4096]u8 = undefined; diff --git a/src/resolver/resolver.zig b/src/resolver/resolver.zig index b8ca0c66aa..cdce9d1625 100644 --- a/src/resolver/resolver.zig +++ b/src/resolver/resolver.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; @@ -9,7 +9,7 @@ const FeatureFlags = bun.FeatureFlags; const PathString = bun.PathString; const stringZ = bun.stringZ; const default_allocator = bun.default_allocator; -const StoredFileDescriptorType = bun.StoredFileDescriptorType; +const FD = bun.FD; const C = bun.C; const ast = @import("../import_record.zig"); const logger = bun.logger; @@ -211,8 +211,8 @@ pub const Result = struct { debug_meta: ?DebugMeta = null, - dirname_fd: StoredFileDescriptorType = .zero, - file_fd: StoredFileDescriptorType = .zero, + dirname_fd: FD = .invalid, + file_fd: FD = .invalid, import_kind: ast.ImportKind = undefined, pub const Union = union(enum) { @@ -317,7 +317,7 @@ pub const DirEntryResolveQueueItem = struct { result: allocators.Result, unsafe_path: string, safe_path: string = "", - fd: StoredFileDescriptorType = .zero, + fd: FD = .invalid, }; pub const DebugLogs = struct { @@ -373,8 +373,8 @@ pub const DebugLogs = struct { pub const MatchResult = struct { path_pair: PathPair, - dirname_fd: StoredFileDescriptorType = .zero, - file_fd: StoredFileDescriptorType = .zero, + dirname_fd: FD = .invalid, + file_fd: FD = .invalid, is_node_module: bool = false, package_json: ?*PackageJSON = null, diff_case: ?Fs.FileSystem.Entry.Lookup.DifferentCase = null, @@ -442,8 +442,8 @@ pub const PendingResolution = struct { pub const LoadResult = struct { path: string, diff_case: ?Fs.FileSystem.Entry.Lookup.DifferentCase, - dirname_fd: StoredFileDescriptorType = .zero, - file_fd: StoredFileDescriptorType = .zero, + dirname_fd: FD = .invalid, + file_fd: FD = .invalid, dir_info: ?*DirInfo = null, }; @@ -460,9 +460,9 @@ const Timer = @import("../system_timer.zig").Timer; pub const AnyResolveWatcher = struct { context: *anyopaque, - callback: *const (fn (*anyopaque, dir_path: string, dir_fd: StoredFileDescriptorType) void) = undefined, + callback: *const (fn (*anyopaque, dir_path: string, dir_fd: FD) void) = undefined, - pub fn watch(this: @This(), dir_path: string, fd: StoredFileDescriptorType) void { + pub fn watch(this: @This(), dir_path: string, fd: FD) void { return this.callback(this.context, dir_path, fd); } }; @@ -475,7 +475,7 @@ pub fn ResolveWatcher(comptime Context: type, comptime onWatch: anytype) type { .callback = watch, }; } - pub fn watch(this: *anyopaque, dir_path: string, fd: StoredFileDescriptorType) void { + pub fn watch(this: *anyopaque, dir_path: string, fd: FD) void { onWatch(bun.cast(Context, this), dir_path, fd); } }; @@ -1024,7 +1024,7 @@ pub const Resolver = struct { const symlink_path = query.entry.symlink(&r.fs.fs, r.store_fd); if (symlink_path.len > 0) { path.setRealpath(symlink_path); - if (result.file_fd == .zero) result.file_fd = query.entry.cache.fd; + if (!result.file_fd.isValid()) result.file_fd = query.entry.cache.fd; if (r.debug_logs) |*debug| { debug.addNoteFmt("Resolved symlink \"{s}\" to \"{s}\"", .{ path.text, symlink_path }); @@ -1037,31 +1037,31 @@ pub const Resolver = struct { const store_fd = r.store_fd; - if (query.entry.cache.fd == .zero) { + if (!query.entry.cache.fd.isValid()) { buf[out.len] = 0; const span = buf[0..out.len :0]; - var file = try if (store_fd) - std.fs.openFileAbsoluteZ(span, .{ .mode = .read_only }) + var file: bun.FD = if (store_fd) + .fromStdFile(try std.fs.openFileAbsoluteZ(span, .{ .mode = .read_only })) else - bun.openFileForPath(span); + .fromStdFile(try bun.openFileForPath(span)); if (!store_fd) { - assert(bun.FDTag.get(file.handle) == .none); - out = try bun.getFdPath(file.handle, &buf); + assert(file.stdioTag() == null); + out = try file.getFdPath(&buf); file.close(); - query.entry.cache.fd = .zero; + query.entry.cache.fd = .invalid; } else { - query.entry.cache.fd = bun.toFD(file.handle); - Fs.FileSystem.setMaxFd(file.handle); + query.entry.cache.fd = file; + Fs.FileSystem.setMaxFd(file.native()); } } defer { if (r.fs.fs.needToCloseFiles()) { - if (query.entry.cache.fd != .zero) { - var file = query.entry.cache.fd.asFile(); + if (query.entry.cache.fd.isValid()) { + var file = query.entry.cache.fd.stdFile(); file.close(); - query.entry.cache.fd = .zero; + query.entry.cache.fd = .invalid; } } } @@ -1075,7 +1075,7 @@ pub const Resolver = struct { debug.addNoteFmt("Resolved symlink \"{s}\" to \"{s}\"", .{ symlink, path.text }); } query.entry.cache.symlink = PathString.init(symlink); - if (result.file_fd == .zero and store_fd) result.file_fd = query.entry.cache.fd; + if (!result.file_fd.isValid() and store_fd) result.file_fd = query.entry.cache.fd; path.setRealpath(symlink); } @@ -1888,7 +1888,7 @@ pub const Resolver = struct { .success = .{ .path_pair = .{ .primary = package_json.source.path }, .dirname_fd = pkg_dir_info.getFileDescriptor(), - .file_fd = .zero, + .file_fd = .invalid, .is_node_module = package_json.source.path.isNodeModule(), .package_json = package_json, .dir_info = dir_info, @@ -2169,7 +2169,7 @@ pub const Resolver = struct { .success = .{ .path_pair = .{ .primary = package_json.source.path }, .dirname_fd = pkg_dir_info.getFileDescriptor(), - .file_fd = .zero, + .file_fd = .invalid, .is_node_module = package_json.source.path.isNodeModule(), .package_json = package_json, .dir_info = dir_info, @@ -2270,10 +2270,10 @@ pub const Resolver = struct { dir_entries_ptr.* = new_entry; if (r.store_fd) { - dir_entries_ptr.fd = bun.toFD(open_dir.fd); + dir_entries_ptr.fd = .fromStdDir(open_dir); } - bun.fs.debug("readdir({}, {s}) = {d}", .{ bun.toFD(open_dir.fd), dir_path, dir_entries_ptr.data.count() }); + bun.fs.debug("readdir({}, {s}) = {d}", .{ bun.FD.fromStdDir(open_dir), dir_path, dir_entries_ptr.data.count() }); dir_entries_option = rfs.entries.put(&cached_dir_entry_result, .{ .entries = dir_entries_ptr, @@ -2294,7 +2294,7 @@ pub const Resolver = struct { // to check for a parent package.json null, allocators.NotFound, - bun.toFD(open_dir.fd), + .fromStdDir(open_dir), package_id, ); return dir_info_ptr; @@ -2561,7 +2561,7 @@ pub const Resolver = struct { pub fn parseTSConfig( r: *ThisResolver, file: string, - dirname_fd: StoredFileDescriptorType, + dirname_fd: FD, ) !?*TSConfigJSON { // Since tsconfig.json is cached permanently, in our DirEntries cache // we must use the global allocator @@ -2611,7 +2611,7 @@ pub const Resolver = struct { pub fn parsePackageJSON( r: *ThisResolver, file: string, - dirname_fd: StoredFileDescriptorType, + dirname_fd: FD, package_id: ?Install.PackageID, comptime allow_dependencies: bool, ) !?*PackageJSON { @@ -2737,7 +2737,7 @@ pub const Resolver = struct { bufs(.dir_entry_paths_to_resolve)[@as(usize, @intCast(i))] = DirEntryResolveQueueItem{ .unsafe_path = top, .result = result, - .fd = .zero, + .fd = .invalid, }; if (rfs.entries.get(top)) |top_entry| { @@ -2763,7 +2763,7 @@ pub const Resolver = struct { bufs(.dir_entry_paths_to_resolve)[@as(usize, @intCast(i))] = DirEntryResolveQueueItem{ .unsafe_path = root_path, .result = result, - .fd = .zero, + .fd = .invalid, }; if (rfs.entries.get(top)) |top_entry| { switch (top_entry.*) { @@ -2790,8 +2790,8 @@ pub const Resolver = struct { defer { if (open_dir_count > 0 and (!r.store_fd or r.fs.fs.needToCloseFiles())) { const open_dirs: []std.fs.Dir = bufs(.open_dirs)[0..open_dir_count]; - for (open_dirs) |*open_dir| { - _ = bun.sys.close(bun.toFD(open_dir.fd)); + for (open_dirs) |open_dir| { + bun.FD.fromStdDir(open_dir).close(); } } } @@ -2816,8 +2816,8 @@ pub const Resolver = struct { defer top_parent = queue_top.result; queue_slice.len -= 1; - const open_dir = if (queue_top.fd != .zero) - queue_top.fd.asDir() + const open_dir: std.fs.Dir = if (queue_top.fd.isValid()) + queue_top.fd.stdDir() else open_dir: { // This saves us N copies of .toPosixPath // which was likely the perf gain from resolving directories relative to the parent directory, anyway. @@ -2838,7 +2838,7 @@ pub const Resolver = struct { .read_only = true, }); if (dirfd_result.unwrap()) |result| { - break :open_req result.asDir(); + break :open_req result.stdDir(); } else |err| { break :open_req err; } @@ -2884,7 +2884,7 @@ pub const Resolver = struct { }; }; - if (queue_top.fd == .zero) { + if (!queue_top.fd.isValid()) { Fs.FileSystem.setMaxFd(open_dir.fd); // these objects mostly just wrap the file descriptor, so it's fine to keep it. bufs(.open_dirs)[open_dir_count] = open_dir; @@ -2951,13 +2951,13 @@ pub const Resolver = struct { if (in_place) |existing| { existing.data.clearAndFree(allocator); } - new_entry.fd = if (r.store_fd) bun.toFD(open_dir.fd) else .zero; + new_entry.fd = if (r.store_fd) .fromStdDir(open_dir) else .invalid; var dir_entries_ptr = in_place orelse allocator.create(Fs.FileSystem.DirEntry) catch unreachable; dir_entries_ptr.* = new_entry; dir_entries_option = try rfs.entries.put(&cached_dir_entry_result, .{ .entries = dir_entries_ptr, }); - bun.fs.debug("readdir({}, {s}) = {d}", .{ bun.toFD(open_dir.fd), dir_path, dir_entries_ptr.data.count() }); + bun.fs.debug("readdir({}, {s}) = {d}", .{ bun.FD.fromStdDir(open_dir), dir_path, dir_entries_ptr.data.count() }); } // We must initialize it as empty so that the result index is correct. @@ -2972,7 +2972,7 @@ pub const Resolver = struct { cached_dir_entry_result.index, r.dir_cache.atIndex(top_parent.index), top_parent.index, - bun.toFD(open_dir.fd), + .fromStdDir(open_dir), null, ); @@ -4038,10 +4038,11 @@ pub const Resolver = struct { bin_folders = BinFolderArray.init(0) catch unreachable; } - const this_dir = fd.asDir(); - var file = this_dir.openDirZ(bun.pathLiteral("node_modules/.bin"), .{ .iterate = true }) catch break :append_bin_dir; + const this_dir = fd.stdDir(); + var file = bun.FD.fromStdDir(this_dir.openDirZ(bun.pathLiteral("node_modules/.bin"), .{}) catch + break :append_bin_dir); defer file.close(); - const bin_path = bun.getFdPath(file.fd, bufs(.node_bin_path)) catch break :append_bin_dir; + const bin_path = file.getFdPath(bufs(.node_bin_path)) catch break :append_bin_dir; bin_folders_lock.lock(); defer bin_folders_lock.unlock(); @@ -4063,10 +4064,10 @@ pub const Resolver = struct { bin_folders = BinFolderArray.init(0) catch unreachable; } - const this_dir = fd.asDir(); + const this_dir = fd.stdDir(); var file = this_dir.openDirZ(".bin", .{}) catch break :append_bin_dir; defer file.close(); - const bin_path = bun.getFdPath(file.fd, bufs(.node_bin_path)) catch break :append_bin_dir; + const bin_path = bun.getFdPath(.fromStdDir(file), bufs(.node_bin_path)) catch break :append_bin_dir; bin_folders_lock.lock(); defer bin_folders_lock.unlock(); @@ -4108,7 +4109,7 @@ pub const Resolver = struct { if (!r.opts.preserve_symlinks) { if (parent_.getEntries(r.generation)) |parent_entries| { if (parent_entries.get(base)) |lookup| { - if (entries.fd != .zero and lookup.entry.cache.fd == .zero and r.store_fd) lookup.entry.cache.fd = entries.fd; + if (entries.fd.isValid() and !lookup.entry.cache.fd.isValid() and r.store_fd) lookup.entry.cache.fd = entries.fd; const entry = lookup.entry; var symlink = entry.symlink(rfs, r.store_fd); @@ -4142,9 +4143,9 @@ pub const Resolver = struct { const entry = lookup.entry; if (entry.kind(rfs, r.store_fd) == .file) { info.package_json = if (r.usePackageManager() and !info.hasNodeModules() and !info.isNodeModules()) - r.parsePackageJSON(path, if (FeatureFlags.store_file_descriptors) fd else .zero, package_id, true) catch null + r.parsePackageJSON(path, if (FeatureFlags.store_file_descriptors) fd else .invalid, package_id, true) catch null else - r.parsePackageJSON(path, if (FeatureFlags.store_file_descriptors) fd else .zero, null, false) catch null; + r.parsePackageJSON(path, if (FeatureFlags.store_file_descriptors) fd else .invalid, null, false) catch null; if (info.package_json) |pkg| { if (pkg.browser_map.count() > 0) { diff --git a/src/resolver/tsconfig_json.zig b/src/resolver/tsconfig_json.zig index 34ffa02c86..d757fd9b0b 100644 --- a/src/resolver/tsconfig_json.zig +++ b/src/resolver/tsconfig_json.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/src/router.zig b/src/router.zig index 095478a033..e4968f7009 100644 --- a/src/router.zig +++ b/src/router.zig @@ -7,7 +7,7 @@ const Router = @This(); const Api = @import("./api/schema.zig").Api; const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; @@ -38,7 +38,7 @@ pub const Param = struct { pub const List = std.MultiArrayList(Param); }; -dir: StoredFileDescriptorType = .zero, +dir: StoredFileDescriptorType = .invalid, routes: Routes, loaded_routes: bool = false, allocator: std.mem.Allocator, @@ -756,8 +756,8 @@ pub const Route = struct { var file: std.fs.File = undefined; var needs_close = false; defer if (needs_close) file.close(); - if (entry.cache.fd != .zero) { - file = entry.cache.fd.asFile(); + if (entry.cache.fd.unwrapValid()) |valid| { + file = valid.stdFile(); } else { var parts = [_]string{ entry.dir, entry.base() }; abs_path_str = FileSystem.instance.absBuf(&parts, &route_file_buf); @@ -770,10 +770,10 @@ pub const Route = struct { FileSystem.setMaxFd(file.handle); needs_close = FileSystem.instance.fs.needToCloseFiles(); - if (!needs_close) entry.cache.fd = bun.toFD(file.handle); + if (!needs_close) entry.cache.fd = .fromStdFile(file); } - const _abs = bun.getFdPath(file.handle, &route_file_buf) catch |err| { + const _abs = bun.getFdPath(.fromStdFile(file), &route_file_buf) catch |err| { log.addErrorFmt(null, Logger.Loc.Empty, allocator, "{s} resolving route: {s}", .{ @errorName(err), abs_path_str }) catch unreachable; return null; }; diff --git a/src/runtime.zig b/src/runtime.zig index 7fa0c80049..6b14f42651 100644 --- a/src/runtime.zig +++ b/src/runtime.zig @@ -1,5 +1,5 @@ const options = @import("./options.zig"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; @@ -15,7 +15,6 @@ const Fs = @import("./fs.zig"); const Schema = @import("./api/schema.zig"); const Ref = @import("ast/base.zig").Ref; const JSAst = bun.JSAst; -const content = @import("root").content; const Api = Schema.Api; fn embedDebugFallback(comptime msg: []const u8, comptime code: []const u8) []const u8 { diff --git a/src/s3/acl.zig b/src/s3/acl.zig index 2d69bed30d..20dec7793f 100644 --- a/src/s3/acl.zig +++ b/src/s3/acl.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); pub const ACL = enum { /// Owner gets FULL_CONTROL. No one else has access rights (default). diff --git a/src/s3/client.zig b/src/s3/client.zig index e516db2007..cbf52173d7 100644 --- a/src/s3/client.zig +++ b/src/s3/client.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const picohttp = bun.picohttp; diff --git a/src/s3/credentials.zig b/src/s3/credentials.zig index 9f2120b711..8cc70f78fa 100644 --- a/src/s3/credentials.zig +++ b/src/s3/credentials.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const picohttp = bun.picohttp; const std = @import("std"); diff --git a/src/s3/download_stream.zig b/src/s3/download_stream.zig index 113a191a52..50e0789fde 100644 --- a/src/s3/download_stream.zig +++ b/src/s3/download_stream.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const picohttp = JSC.WebCore.picohttp; const S3Error = @import("./error.zig").S3Error; diff --git a/src/s3/error.zig b/src/s3/error.zig index fd8f732e84..a9d9c4c6aa 100644 --- a/src/s3/error.zig +++ b/src/s3/error.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; pub const ErrorCodeAndMessage = struct { code: []const u8, diff --git a/src/s3/list_objects.zig b/src/s3/list_objects.zig index 066a3e6e4b..9286b7aa57 100644 --- a/src/s3/list_objects.zig +++ b/src/s3/list_objects.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const JSValue = JSC.JSValue; const JSGlobalObject = JSC.JSGlobalObject; diff --git a/src/s3/multipart.zig b/src/s3/multipart.zig index 8f515b1971..a90468e252 100644 --- a/src/s3/multipart.zig +++ b/src/s3/multipart.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const strings = bun.strings; const S3Credentials = @import("./credentials.zig").S3Credentials; const ACL = @import("./acl.zig").ACL; diff --git a/src/s3/simple_request.zig b/src/s3/simple_request.zig index ec84f64071..9610955b95 100644 --- a/src/s3/simple_request.zig +++ b/src/s3/simple_request.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const strings = bun.strings; const SignResult = @import("./credentials.zig").S3Credentials.SignResult; diff --git a/src/s3/storage_class.zig b/src/s3/storage_class.zig index 1ba9a1a7be..d37e5629ff 100644 --- a/src/s3/storage_class.zig +++ b/src/s3/storage_class.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); pub const StorageClass = enum { STANDARD, diff --git a/src/semver/ExternalString.zig b/src/semver/ExternalString.zig index a389a401dc..5f143456c1 100644 --- a/src/semver/ExternalString.zig +++ b/src/semver/ExternalString.zig @@ -47,7 +47,7 @@ pub const ExternalString = extern struct { const assert = bun.assert; const std = @import("std"); const Allocator = std.mem.Allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/src/semver/SemverObject.zig b/src/semver/SemverObject.zig index 6c0ccf6dbb..df73920dd5 100644 --- a/src/semver/SemverObject.zig +++ b/src/semver/SemverObject.zig @@ -127,7 +127,7 @@ pub fn satisfies(globalThis: *JSC.JSGlobalObject, callFrame: *JSC.CallFrame) bun const std = @import("std"); const Allocator = std.mem.Allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/src/semver/SemverQuery.zig b/src/semver/SemverQuery.zig index 55a7772578..a5961f0b77 100644 --- a/src/semver/SemverQuery.zig +++ b/src/semver/SemverQuery.zig @@ -778,7 +778,7 @@ const Query = @This(); const std = @import("std"); const Allocator = std.mem.Allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/src/semver/SemverRange.zig b/src/semver/SemverRange.zig index 5a9c138710..b766e69fef 100644 --- a/src/semver/SemverRange.zig +++ b/src/semver/SemverRange.zig @@ -250,7 +250,7 @@ const Range = @This(); const std = @import("std"); const Allocator = std.mem.Allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/src/semver/SemverString.zig b/src/semver/SemverString.zig index c1e7e0aee1..0bb43c9e0e 100644 --- a/src/semver/SemverString.zig +++ b/src/semver/SemverString.zig @@ -609,7 +609,7 @@ pub const String = extern struct { const assert = bun.assert; const std = @import("std"); const Allocator = std.mem.Allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/src/semver/SlicedString.zig b/src/semver/SlicedString.zig index 960c20a8b8..7cc66a91d2 100644 --- a/src/semver/SlicedString.zig +++ b/src/semver/SlicedString.zig @@ -39,7 +39,7 @@ const SlicedString = @This(); const assert = bun.assert; const std = @import("std"); const Allocator = std.mem.Allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/src/semver/Version.zig b/src/semver/Version.zig index 2073f98148..a5725f4659 100644 --- a/src/semver/Version.zig +++ b/src/semver/Version.zig @@ -987,7 +987,7 @@ pub const Version = extern struct { const std = @import("std"); const Allocator = std.mem.Allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/src/sha.zig b/src/sha.zig index b82dcaa2d3..c56bea3c02 100644 --- a/src/sha.zig +++ b/src/sha.zig @@ -1,6 +1,6 @@ const BoringSSL = bun.BoringSSL.c; const std = @import("std"); -pub const bun = @import("root").bun; +pub const bun = @import("bun"); fn NewHasher(comptime digest_size: comptime_int, comptime ContextType: type, comptime Full: anytype, comptime Init: anytype, comptime Update: anytype, comptime Final: anytype) type { return struct { diff --git a/src/shell/Builtin.zig b/src/shell/Builtin.zig index 05335241bb..f0caaf533d 100644 --- a/src/shell/Builtin.zig +++ b/src/shell/Builtin.zig @@ -150,9 +150,7 @@ pub const BuiltinIO = struct { pub fn needsIO(this: *Output) ?OutputNeedsIOSafeGuard { return switch (this.*) { - .fd => OutputNeedsIOSafeGuard{ - .__i_know_what_i_am_doing_it_needs_io_yes = 0, - }, + .fd => .output_needs_io, else => null, }; } @@ -674,7 +672,7 @@ pub const Mv = @import("./builtin/mv.zig"); // --- End Shell Builtin Commands --- const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const shell = bun.shell; const Interpreter = shell.interpret.Interpreter; diff --git a/src/shell/EnvMap.zig b/src/shell/EnvMap.zig index dbee99cce7..eeeba042d3 100644 --- a/src/shell/EnvMap.zig +++ b/src/shell/EnvMap.zig @@ -99,7 +99,7 @@ fn derefStrings(this: *EnvMap) void { } const EnvMap = @This(); -const bun = @import("root").bun; +const bun = @import("bun"); const Allocator = std.mem.Allocator; const std = @import("std"); const EnvStr = bun.shell.EnvStr; diff --git a/src/shell/EnvStr.zig b/src/shell/EnvStr.zig index 61457be3df..0504ca9693 100644 --- a/src/shell/EnvStr.zig +++ b/src/shell/EnvStr.zig @@ -85,7 +85,7 @@ pub const EnvStr = packed struct(u128) { } }; -const bun = @import("root").bun; +const bun = @import("bun"); const interpreter = @import("./interpreter.zig"); const shell = bun.shell; const RefCountedStr = interpreter.RefCountedStr; diff --git a/src/shell/IOWriter.zig b/src/shell/IOWriter.zig index 270759ecfd..873fc19f85 100644 --- a/src/shell/IOWriter.zig +++ b/src/shell/IOWriter.zig @@ -461,7 +461,7 @@ pub fn deinitOnMainThread(this: *IOWriter) void { this.writer.handle.closeImpl(null, {}, false); } } else this.winbuf.deinit(bun.default_allocator); - if (this.fd != bun.invalid_fd) _ = bun.sys.close(this.fd); + if (this.fd.isValid()) this.fd.close(); this.writer.disableKeepingProcessAlive(this.evtloop); bun.destroy(this); } @@ -478,7 +478,7 @@ pub inline fn setWriting(this: *IOWriter, writing: bool) void { } } -const bun = @import("root").bun; +const bun = @import("bun"); const shell = bun.shell; const Interpreter = shell.Interpreter; const EnvMap = shell.EnvMap; diff --git a/src/shell/ParsedShellScript.zig b/src/shell/ParsedShellScript.zig index 4aeac11bb0..1bb37137e9 100644 --- a/src/shell/ParsedShellScript.zig +++ b/src/shell/ParsedShellScript.zig @@ -1,4 +1,7 @@ -pub usingnamespace JSC.Codegen.JSParsedShellScript; +pub const js = JSC.Codegen.JSParsedShellScript; +pub const toJS = js.toJS; +pub const fromJS = js.fromJS; +pub const fromJSDirect = js.fromJSDirect; args: ?*ShellArgs = null, /// allocated with arena in jsobjs @@ -161,7 +164,7 @@ pub fn createParsedShellScript(globalThis: *JSC.JSGlobalObject, callframe: *JSC. } const ParsedShellScript = @This(); -const bun = @import("root").bun; +const bun = @import("bun"); const shell = bun.shell; const Interpreter = shell.Interpreter; const interpreter = @import("./interpreter.zig"); diff --git a/src/shell/RefCountedStr.zig b/src/shell/RefCountedStr.zig index d4c5ef7e27..705353baa3 100644 --- a/src/shell/RefCountedStr.zig +++ b/src/shell/RefCountedStr.zig @@ -43,4 +43,4 @@ fn freeStr(this: *RefCountedStr) void { } const RefCountedStr = @This(); -const bun = @import("root").bun; +const bun = @import("bun"); diff --git a/src/shell/braces.zig b/src/shell/braces.zig index 0e4d9fb569..d739140ccc 100644 --- a/src/shell/braces.zig +++ b/src/shell/braces.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const std = @import("std"); const builtin = @import("builtin"); const ArrayList = std.ArrayList; diff --git a/src/shell/builtin/basename.zig b/src/shell/builtin/basename.zig index eef5599a33..6e982c1d6f 100644 --- a/src/shell/builtin/basename.zig +++ b/src/shell/builtin/basename.zig @@ -67,7 +67,7 @@ pub inline fn bltn(this: *@This()) *Builtin { return @fieldParentPtr("impl", impl); } -const bun = @import("root").bun; +const bun = @import("bun"); const shell = bun.shell; const interpreter = @import("../interpreter.zig"); const Interpreter = interpreter.Interpreter; diff --git a/src/shell/builtin/cat.zig b/src/shell/builtin/cat.zig index 4162ab8386..c1643a37c6 100644 --- a/src/shell/builtin/cat.zig +++ b/src/shell/builtin/cat.zig @@ -341,7 +341,7 @@ const Opts = struct { }; const debug = bun.Output.scoped(.ShellCat, true); -const bun = @import("root").bun; +const bun = @import("bun"); const shell = bun.shell; const interpreter = @import("../interpreter.zig"); const Interpreter = interpreter.Interpreter; diff --git a/src/shell/builtin/cd.zig b/src/shell/builtin/cd.zig index e10c8e7eaf..6ae4448aac 100644 --- a/src/shell/builtin/cd.zig +++ b/src/shell/builtin/cd.zig @@ -122,7 +122,7 @@ pub fn deinit(this: *Cd) void { // -- const log = bun.Output.scoped(.Cd, true); -const bun = @import("root").bun; +const bun = @import("bun"); const shell = bun.shell; const interpreter = @import("../interpreter.zig"); const Interpreter = interpreter.Interpreter; diff --git a/src/shell/builtin/cp.zig b/src/shell/builtin/cp.zig index 2acc8d5a3f..736947b73c 100644 --- a/src/shell/builtin/cp.zig +++ b/src/shell/builtin/cp.zig @@ -741,7 +741,7 @@ const Opts = packed struct(u16) { const log = bun.Output.scoped(.cp, true); const ArrayList = std.ArrayList; const Syscall = bun.sys; -const bun = @import("root").bun; +const bun = @import("bun"); const shell = bun.shell; const interpreter = @import("../interpreter.zig"); const Interpreter = interpreter.Interpreter; diff --git a/src/shell/builtin/dirname.zig b/src/shell/builtin/dirname.zig index a61ef308a9..e55c1ad93e 100644 --- a/src/shell/builtin/dirname.zig +++ b/src/shell/builtin/dirname.zig @@ -69,7 +69,7 @@ pub inline fn bltn(this: *@This()) *Builtin { // -- const debug = bun.Output.scoped(.ShellCat, true); -const bun = @import("root").bun; +const bun = @import("bun"); const shell = bun.shell; const interpreter = @import("../interpreter.zig"); const Interpreter = interpreter.Interpreter; diff --git a/src/shell/builtin/echo.zig b/src/shell/builtin/echo.zig index 4eb9fc5b6e..75f9d06a5f 100644 --- a/src/shell/builtin/echo.zig +++ b/src/shell/builtin/echo.zig @@ -65,7 +65,7 @@ pub inline fn bltn(this: *Echo) *Builtin { // -- const log = bun.Output.scoped(.echo, true); -const bun = @import("root").bun; +const bun = @import("bun"); const shell = bun.shell; const interpreter = @import("../interpreter.zig"); const Interpreter = interpreter.Interpreter; diff --git a/src/shell/builtin/exit.zig b/src/shell/builtin/exit.zig index 3e5a008a38..6b5ea10979 100644 --- a/src/shell/builtin/exit.zig +++ b/src/shell/builtin/exit.zig @@ -80,7 +80,7 @@ pub inline fn bltn(this: *Exit) *Builtin { // -- const log = bun.Output.scoped(.Exit, true); -const bun = @import("root").bun; +const bun = @import("bun"); const shell = bun.shell; const interpreter = @import("../interpreter.zig"); const Interpreter = interpreter.Interpreter; diff --git a/src/shell/builtin/export.zig b/src/shell/builtin/export.zig index f15203714e..6cbca36203 100644 --- a/src/shell/builtin/export.zig +++ b/src/shell/builtin/export.zig @@ -117,7 +117,7 @@ pub inline fn bltn(this: *Export) *Builtin { // -- const debug = bun.Output.scoped(.ShellExport, true); -const bun = @import("root").bun; +const bun = @import("bun"); const shell = bun.shell; const interpreter = @import("../interpreter.zig"); const Interpreter = interpreter.Interpreter; diff --git a/src/shell/builtin/false.zig b/src/shell/builtin/false.zig index f5af97ddad..b838cd4ca0 100644 --- a/src/shell/builtin/false.zig +++ b/src/shell/builtin/false.zig @@ -17,7 +17,7 @@ pub inline fn bltn(this: *@This()) *Builtin { } // -- -const bun = @import("root").bun; +const bun = @import("bun"); const interpreter = @import("../interpreter.zig"); const Interpreter = interpreter.Interpreter; const Builtin = Interpreter.Builtin; diff --git a/src/shell/builtin/ls.zig b/src/shell/builtin/ls.zig index 70a83f1b55..19b2c98278 100644 --- a/src/shell/builtin/ls.zig +++ b/src/shell/builtin/ls.zig @@ -264,7 +264,7 @@ pub const ShellLsTask = struct { }; defer { - _ = Syscall.close(fd); + fd.close(); debug("run done", .{}); } @@ -274,7 +274,7 @@ pub const ShellLsTask = struct { std.fmt.format(writer, "{s}:\n", .{this.path}) catch bun.outOfMemory(); } - var iterator = DirIterator.iterate(fd.asDir(), .u8); + var iterator = DirIterator.iterate(fd.stdDir(), .u8); var entry = iterator.next(); while (switch (entry) { @@ -779,7 +779,7 @@ pub inline fn bltn(this: *Ls) *Builtin { const Ls = @This(); const log = bun.Output.scoped(.ls, true); -const bun = @import("root").bun; +const bun = @import("bun"); const shell = bun.shell; const interpreter = @import("../interpreter.zig"); const Interpreter = interpreter.Interpreter; diff --git a/src/shell/builtin/mkdir.zig b/src/shell/builtin/mkdir.zig index e2bd51fad0..d1095fe341 100644 --- a/src/shell/builtin/mkdir.zig +++ b/src/shell/builtin/mkdir.zig @@ -378,7 +378,7 @@ pub inline fn bltn(this: *Mkdir) *Builtin { // -- const debug = bun.Output.scoped(.ShellMkdir, true); -const bun = @import("root").bun; +const bun = @import("bun"); const shell = bun.shell; const interpreter = @import("../interpreter.zig"); const Interpreter = interpreter.Interpreter; diff --git a/src/shell/builtin/mv.zig b/src/shell/builtin/mv.zig index 04916c748a..ab7d001445 100644 --- a/src/shell/builtin/mv.zig +++ b/src/shell/builtin/mv.zig @@ -377,9 +377,7 @@ pub fn batchedMoveTaskDone(this: *Mv, task: *ShellMvBatchedTask) void { } pub fn deinit(this: *Mv) void { - if (this.args.target_fd != null and this.args.target_fd.? != bun.invalid_fd) { - _ = Syscall.close(this.args.target_fd.?); - } + if (this.args.target_fd) |fd| fd.toOptional().close(); } const Opts = struct { @@ -500,7 +498,7 @@ const Syscall = bun.sys; const ShellTask = interpreter.ShellTask; const assert = bun.assert; const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const shell = bun.shell; const ExitCode = shell.ExitCode; const IOReader = shell.IOReader; diff --git a/src/shell/builtin/pwd.zig b/src/shell/builtin/pwd.zig index de6bdc6f22..2c67d58ee0 100644 --- a/src/shell/builtin/pwd.zig +++ b/src/shell/builtin/pwd.zig @@ -84,7 +84,7 @@ pub inline fn bltn(this: *Pwd) *Builtin { // -- const debug = bun.Output.scoped(.ShellCat, true); -const bun = @import("root").bun; +const bun = @import("bun"); const shell = bun.shell; const interpreter = @import("../interpreter.zig"); const Interpreter = interpreter.Interpreter; diff --git a/src/shell/builtin/rm.zig b/src/shell/builtin/rm.zig index cd710d0c4c..cf14aff17f 100644 --- a/src/shell/builtin/rm.zig +++ b/src/shell/builtin/rm.zig @@ -862,7 +862,7 @@ pub const ShellRmTask = struct { // On posix we can close the file descriptor whenever, but on Windows // we need to close it BEFORE we delete if (close_fd) { - _ = Syscall.close(fd); + fd.close(); } } @@ -870,7 +870,7 @@ pub const ShellRmTask = struct { return Maybe(void).success; } - var iterator = DirIterator.iterate(fd.asDir(), .u8); + var iterator = DirIterator.iterate(fd.stdDir(), .u8); var entry = iterator.next(); var remove_child_vtable = RemoveFileVTable{ @@ -927,7 +927,7 @@ pub const ShellRmTask = struct { if (bun.Environment.isWindows) { close_fd = false; - _ = Syscall.close(fd); + fd.close(); } debug("[removeEntryDir] remove after children {s}", .{path}); @@ -1031,7 +1031,7 @@ pub const ShellRmTask = struct { fn removeEntryDirAfterChildren(this: *ShellRmTask, dir_task: *DirTask) Maybe(bool) { debug("remove entry after children: {s}", .{dir_task.path}); - const dirfd = bun.toFD(this.cwd); + const dirfd = this.cwd; var state = RemoveFileParent{ .task = this, .treat_as_dir = true, @@ -1090,7 +1090,7 @@ pub const ShellRmTask = struct { return Maybe(void).success; } }; - const dirfd = bun.toFD(this.cwd); + const dirfd = this.cwd; switch (ShellSyscall.unlinkatWithFlags(dirfd, path, 0)) { .result => return this.verboseDeleted(parent_dir_task, path), .err => |e| { @@ -1195,7 +1195,7 @@ inline fn fastMod(val: anytype, comptime rhs: comptime_int) @TypeOf(val) { // -- const log = bun.Output.scoped(.Rm, true); -const bun = @import("root").bun; +const bun = @import("bun"); const shell = bun.shell; const interpreter = @import("../interpreter.zig"); const Interpreter = interpreter.Interpreter; diff --git a/src/shell/builtin/seq.zig b/src/shell/builtin/seq.zig index f07c842f79..9b6a5625e9 100644 --- a/src/shell/builtin/seq.zig +++ b/src/shell/builtin/seq.zig @@ -139,7 +139,7 @@ pub inline fn bltn(this: *@This()) *Builtin { } // -- -const bun = @import("root").bun; +const bun = @import("bun"); const shell = bun.shell; const interpreter = @import("../interpreter.zig"); const Interpreter = interpreter.Interpreter; diff --git a/src/shell/builtin/touch.zig b/src/shell/builtin/touch.zig index d8cf4c4c80..10180e8058 100644 --- a/src/shell/builtin/touch.zig +++ b/src/shell/builtin/touch.zig @@ -255,7 +255,7 @@ pub const ShellTouchTask = struct { const perm = 0o664; switch (Syscall.open(filepath, bun.O.CREAT | bun.O.WRONLY, perm)) { .result => |fd| { - _ = bun.sys.close(fd); + fd.close(); break :out; }, .err => |e| { @@ -397,7 +397,7 @@ const debug = bun.Output.scoped(.ShellTouch, true); const Touch = @This(); const log = debug; const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const shell = bun.shell; const ExitCode = shell.ExitCode; const IOReader = shell.IOReader; diff --git a/src/shell/builtin/true.zig b/src/shell/builtin/true.zig index da0781b6ac..b647d50e42 100644 --- a/src/shell/builtin/true.zig +++ b/src/shell/builtin/true.zig @@ -17,7 +17,7 @@ pub inline fn bltn(this: *@This()) *Builtin { } // -- -const bun = @import("root").bun; +const bun = @import("bun"); const interpreter = @import("../interpreter.zig"); const Interpreter = interpreter.Interpreter; const Builtin = Interpreter.Builtin; diff --git a/src/shell/builtin/which.zig b/src/shell/builtin/which.zig index f48dc1673e..912b8ec7ef 100644 --- a/src/shell/builtin/which.zig +++ b/src/shell/builtin/which.zig @@ -150,7 +150,7 @@ const log = bun.Output.scoped(.which, true); const Which = @This(); const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const shell = bun.shell; const ExitCode = shell.ExitCode; const IOReader = shell.IOReader; diff --git a/src/shell/builtin/yes.zig b/src/shell/builtin/yes.zig index 2d01417501..bccdeb9b8a 100644 --- a/src/shell/builtin/yes.zig +++ b/src/shell/builtin/yes.zig @@ -72,8 +72,8 @@ pub const YesTask = struct { const yes: *Yes = @fieldParentPtr("task", this); // Manually make safeguard since this task should not be created if output does not need IO - yes.bltn().stdout.enqueue(yes, yes.expletive, OutputNeedsIOSafeGuard{ .__i_know_what_i_am_doing_it_needs_io_yes = 0 }); - yes.bltn().stdout.enqueue(yes, "\n", OutputNeedsIOSafeGuard{ .__i_know_what_i_am_doing_it_needs_io_yes = 0 }); + yes.bltn().stdout.enqueue(yes, yes.expletive, .output_needs_io); + yes.bltn().stdout.enqueue(yes, "\n", .output_needs_io); this.enqueue(); } @@ -85,7 +85,7 @@ pub const YesTask = struct { // -- const log = bun.Output.scoped(.Yes, true); -const bun = @import("root").bun; +const bun = @import("bun"); const shell = bun.shell; const interpreter = @import("../interpreter.zig"); const Interpreter = interpreter.Interpreter; diff --git a/src/shell/interpreter.zig b/src/shell/interpreter.zig index d4cc5b7ed5..96067524b4 100644 --- a/src/shell/interpreter.zig +++ b/src/shell/interpreter.zig @@ -19,7 +19,7 @@ const std = @import("std"); const builtin = @import("builtin"); const string = []const u8; -const bun = @import("root").bun; +const bun = @import("bun"); const posix = std.posix; const Arena = std.heap.ArenaAllocator; const Allocator = std.mem.Allocator; @@ -89,10 +89,7 @@ const assert = bun.assert; /// /// Functions which accept a `_: OutputNeedsIOSafeGuard` parameter can /// safely assume the stdout/stderr they are working with require IO. -pub const OutputNeedsIOSafeGuard = struct { - /// Dummy zero sized field to prevent it from being trivial to create this type (by doing `.{}`) - __i_know_what_i_am_doing_it_needs_io_yes: u0, -}; +pub const OutputNeedsIOSafeGuard = enum(u0) { output_needs_io }; pub const ExitCode = u16; @@ -174,7 +171,7 @@ const CowFd = struct { pub fn deinit(this: *CowFd) void { assert(this.refcount == 0); - _ = bun.sys.close(this.__fd); + this.__fd.close(); bun.default_allocator.destroy(this); } }; @@ -353,7 +350,11 @@ pub const ShellArgs = struct { /// This interpreter works by basically turning the AST into a state machine so /// that execution can be suspended and resumed to support async. pub const Interpreter = struct { - pub usingnamespace JSC.Codegen.JSShellInterpreter; + pub const js = JSC.Codegen.JSShellInterpreter; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; + command_ctx: bun.CLI.Command.Context, event_loop: JSC.EventLoopHandle, /// This is the allocator used to allocate interpreter state @@ -614,7 +615,7 @@ pub const Interpreter = struct { return Maybe(void).initErr(err); }, }; - _ = Syscall.close2(this.cwd_fd); + _ = this.cwd_fd.closeAllowingBadFileDescriptor(null); this.__prev_cwd.clearRetainingCapacity(); this.__prev_cwd.appendSlice(this.__cwd.items[0..]) catch bun.outOfMemory(); @@ -668,8 +669,6 @@ pub const Interpreter = struct { } }; - pub usingnamespace JSC.Codegen.JSShellInterpreter; - const ThisInterpreter = @This(); const ShellErrorKind = error{ @@ -1070,13 +1069,13 @@ pub const Interpreter = struct { const event_loop = this.event_loop; log("Duping stdout", .{}); - const stdout_fd = switch (if (bun.Output.Source.Stdio.isStdoutNull()) bun.sys.openNullDevice() else ShellSyscall.dup(bun.STDOUT_FD)) { + const stdout_fd = switch (if (bun.Output.Source.Stdio.isStdoutNull()) bun.sys.openNullDevice() else ShellSyscall.dup(.stdout())) { .result => |fd| fd, .err => |err| return .{ .err = err }, }; log("Duping stderr", .{}); - const stderr_fd = switch (if (bun.Output.Source.Stdio.isStderrNull()) bun.sys.openNullDevice() else ShellSyscall.dup(bun.STDERR_FD)) { + const stderr_fd = switch (if (bun.Output.Source.Stdio.isStderrNull()) bun.sys.openNullDevice() else ShellSyscall.dup(.stderr())) { .result => |fd| fd, .err => |err| return .{ .err = err }, }; @@ -2034,11 +2033,11 @@ pub const Interpreter = struct { fn expandVarArgv(this: *const Expansion, original_int: u8) []const u8 { var int = original_int; switch (this.base.interpreter.event_loop) { - .js => |js| { + .js => |event_loop| { if (int == 0) return bun.selfExePath() catch ""; int -= 1; - const vm = js.virtual_machine; + const vm = event_loop.virtual_machine; if (vm.main.len > 0) { if (int == 0) return vm.main; int -= 1; @@ -3086,20 +3085,18 @@ pub const Interpreter = struct { if (uv.uv_pipe(&fds, 0, 0).errEnum()) |e| { return .{ .err = Syscall.Error.fromCode(e, .pipe) }; } - pipe[0] = bun.FDImpl.fromUV(fds[0]).encode(); - pipe[1] = bun.FDImpl.fromUV(fds[1]).encode(); + pipe[0] = .fromUV(fds[0]); + pipe[1] = .fromUV(fds[1]); } else { - const fds: [2]bun.FileDescriptor = switch (bun.sys.socketpair( + switch (bun.sys.socketpair( std.posix.AF.UNIX, std.posix.SOCK.STREAM, 0, .blocking, )) { - .result => |fds| .{ bun.toFD(fds[0]), bun.toFD(fds[1]) }, + .result => |fds| pipe.* = fds, .err => |err| return .{ .err = err }, - }; - - pipe.* = fds; + } } set_count.* += 1; } @@ -4880,7 +4877,7 @@ pub const Interpreter = struct { } } else { log("IOReader(0x{x}) __deinit fd={}", .{ @intFromPtr(this), this.fd }); - _ = bun.sys.close(this.fd); + this.fd.close(); } } this.buf.deinit(bun.default_allocator); @@ -5057,7 +5054,7 @@ pub fn MaybeChild(comptime T: type) type { } fn closefd(fd: bun.FileDescriptor) void { - if (Syscall.close2(fd)) |err| { + if (fd.closeAllowingBadFileDescriptor(null)) |err| { log("ERR closefd: {}\n", .{err}); } } @@ -5334,12 +5331,12 @@ pub const ShellSyscall = struct { .err => |e| return .{ .err = e }, }; return switch (Syscall.openDirAtWindowsA(dir, p, .{ .iterable = true, .no_follow = flags & bun.O.NOFOLLOW != 0 })) { - .result => |fd| bun.sys.toLibUVOwnedFD(fd, .open, .close_on_fail), + .result => |fd| fd.makeLibUVOwnedForSyscall(.open, .close_on_fail), .err => |e| .{ .err = e.withPath(path) }, }; } return switch (Syscall.openDirAtWindowsA(dir, path, .{ .iterable = true, .no_follow = flags & bun.O.NOFOLLOW != 0 })) { - .result => |fd| bun.sys.toLibUVOwnedFD(fd, .open, .close_on_fail), + .result => |fd| fd.makeLibUVOwnedForSyscall(.open, .close_on_fail), .err => |e| .{ .err = e.withPath(path) }, }; } @@ -5357,7 +5354,7 @@ pub const ShellSyscall = struct { .err => |e| return .{ .err = e.withPath(path) }, }; if (bun.Environment.isWindows) { - return bun.sys.toLibUVOwnedFD(fd, .open, .close_on_fail); + return fd.makeLibUVOwnedForSyscall(.open, .close_on_fail); } return .{ .result = fd }; } @@ -5368,7 +5365,7 @@ pub const ShellSyscall = struct { .err => |e| return .{ .err = e }, }; if (bun.Environment.isWindows) { - return bun.sys.toLibUVOwnedFD(fd, .open, .close_on_fail); + return fd.makeLibUVOwnedForSyscall(.open, .close_on_fail); } return .{ .result = fd }; } @@ -5376,7 +5373,7 @@ pub const ShellSyscall = struct { pub fn dup(fd: bun.FileDescriptor) Maybe(bun.FileDescriptor) { if (bun.Environment.isWindows) { return switch (Syscall.dup(fd)) { - .result => |duped_fd| bun.sys.toLibUVOwnedFD(duped_fd, .dup, .close_on_fail), + .result => |duped_fd| duped_fd.makeLibUVOwnedForSyscall(.dup, .close_on_fail), .err => |e| .{ .err = e }, }; } @@ -5572,8 +5569,10 @@ pub fn FlagParser(comptime Opts: type) type { } pub fn isPollable(fd: bun.FileDescriptor, mode: bun.Mode) bool { - if (bun.Environment.isWindows) return false; - if (bun.Environment.isLinux) return posix.S.ISFIFO(mode) or posix.S.ISSOCK(mode) or posix.isatty(fd.int()); - // macos allows regular files to be pollable: ISREG(mode) == true - return posix.S.ISFIFO(mode) or posix.S.ISSOCK(mode) or posix.isatty(fd.int()) or posix.S.ISREG(mode); + return switch (bun.Environment.os) { + .windows, .wasm => false, + .linux => posix.S.ISFIFO(mode) or posix.S.ISSOCK(mode) or posix.isatty(fd.native()), + // macos allows regular files to be pollable: ISREG(mode) == true + .mac => posix.S.ISFIFO(mode) or posix.S.ISSOCK(mode) or posix.S.ISREG(mode) or posix.isatty(fd.native()), + }; } diff --git a/src/shell/shell.zig b/src/shell/shell.zig index c92fea0de6..4e203c6167 100644 --- a/src/shell/shell.zig +++ b/src/shell/shell.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const std = @import("std"); const builtin = @import("builtin"); const Arena = std.heap.ArenaAllocator; @@ -37,10 +37,10 @@ const GlobWalker = Glob.GlobWalker_(null, true); pub const SUBSHELL_TODO_ERROR = "Subshells are not implemented, please open GitHub issue!"; -/// Using these instead of `bun.STD{IN,OUT,ERR}_FD` to makesure we use uv fd -pub const STDIN_FD: bun.FileDescriptor = if (bun.Environment.isWindows) bun.FDImpl.fromUV(0).encode() else bun.STDIN_FD; -pub const STDOUT_FD: bun.FileDescriptor = if (bun.Environment.isWindows) bun.FDImpl.fromUV(1).encode() else bun.STDOUT_FD; -pub const STDERR_FD: bun.FileDescriptor = if (bun.Environment.isWindows) bun.FDImpl.fromUV(2).encode() else bun.STDERR_FD; +/// Using these instead of the file descriptor decl literals to make sure we use LivUV fds on Windows +pub const STDIN_FD: bun.FileDescriptor = .fromUV(0); +pub const STDOUT_FD: bun.FileDescriptor = .fromUV(1); +pub const STDERR_FD: bun.FileDescriptor = .fromUV(2); pub const POSIX_DEV_NULL: [:0]const u8 = "/dev/null"; pub const WINDOWS_DEV_NULL: [:0]const u8 = "NUL"; diff --git a/src/shell/subproc.zig b/src/shell/subproc.zig index 1f3f785f13..8f13ca2bb2 100644 --- a/src/shell/subproc.zig +++ b/src/shell/subproc.zig @@ -1,5 +1,5 @@ const default_allocator = bun.default_allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const Environment = bun.Environment; const NetworkThread = bun.http.NetworkThread; const Global = bun.Global; @@ -287,7 +287,7 @@ pub const ShellSubprocess = struct { this.buffer.deref(); }, .memfd => |fd| { - _ = bun.sys.close(fd); + fd.close(); this.* = .{ .ignore = {} }; }, .ignore => {}, @@ -301,7 +301,7 @@ pub const ShellSubprocess = struct { _ = pipe.end(null); }, inline .memfd, .fd => |fd| { - _ = bun.sys.close(fd); + fd.close(); this.* = .{ .ignore = {} }; }, .buffer => { @@ -419,7 +419,7 @@ pub const ShellSubprocess = struct { switch (this.*) { inline .memfd, .fd => |fd| { this.* = .{ .closed = {} }; - _ = bun.sys.close(fd); + fd.close(); }, .pipe => { this.pipe.close(); @@ -432,7 +432,7 @@ pub const ShellSubprocess = struct { switch (this.*) { inline .memfd, .fd => |fd| { this.* = .{ .closed = {} }; - _ = bun.sys.close(fd); + fd.close(); }, .pipe => |pipe| { defer pipe.detach(); @@ -797,7 +797,7 @@ pub const ShellSubprocess = struct { if (should_close_memfd) { inline for (0..spawn_args.stdio.len) |fd_index| { if (spawn_args.stdio[fd_index] == .memfd) { - _ = bun.sys.close(spawn_args.stdio[fd_index].memfd); + spawn_args.stdio[fd_index].memfd.close(); spawn_args.stdio[fd_index] = .ignore; } } diff --git a/src/shell/util.zig b/src/shell/util.zig index 48c5b5577b..25d41bacdc 100644 --- a/src/shell/util.zig +++ b/src/shell/util.zig @@ -3,7 +3,7 @@ const Allocator = std.mem.Allocator; const uws = bun.uws; const std = @import("std"); const default_allocator = bun.default_allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const Environment = bun.Environment; const Async = bun.Async; const JSC = bun.JSC; @@ -17,10 +17,11 @@ const posix = std.posix; pub const OutKind = enum { stdout, stderr, + pub fn toFd(this: OutKind) bun.FileDescriptor { return switch (this) { - .stdout => bun.STDOUT_FD, - .stderr => bun.STDERR_FD, + .stdout => .stdout(), + .stderr => .stderr(), }; } }; diff --git a/src/sourcemap/CodeCoverage.zig b/src/sourcemap/CodeCoverage.zig index 5010e35294..167f7d2ad7 100644 --- a/src/sourcemap/CodeCoverage.zig +++ b/src/sourcemap/CodeCoverage.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const std = @import("std"); const LineOffsetTable = bun.sourcemap.LineOffsetTable; const SourceMap = bun.sourcemap; diff --git a/src/sourcemap/LineOffsetTable.zig b/src/sourcemap/LineOffsetTable.zig index c9c0307532..330cb3b2db 100644 --- a/src/sourcemap/LineOffsetTable.zig +++ b/src/sourcemap/LineOffsetTable.zig @@ -222,7 +222,7 @@ pub fn generate(allocator: std.mem.Allocator, contents: []const u8, approximate_ } const LineOffsetTable = @This(); -const bun = @import("root").bun; +const bun = @import("bun"); const BabyList = bun.BabyList; const std = @import("std"); const strings = bun.strings; diff --git a/src/sourcemap/VLQ.zig b/src/sourcemap/VLQ.zig index 8b8651fd0d..40aa6454b9 100644 --- a/src/sourcemap/VLQ.zig +++ b/src/sourcemap/VLQ.zig @@ -164,4 +164,4 @@ pub fn decodeAssumeValid(encoded: []const u8, start: usize) VLQResult { } const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); diff --git a/src/sourcemap/sourcemap.zig b/src/sourcemap/sourcemap.zig index 5d3275c2ed..8a6822e656 100644 --- a/src/sourcemap/sourcemap.zig +++ b/src/sourcemap/sourcemap.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const JSAst = bun.JSAst; const BabyList = JSAst.BabyList; diff --git a/src/sql/DataCell.zig b/src/sql/DataCell.zig index 3242545d08..3d841657f4 100644 --- a/src/sql/DataCell.zig +++ b/src/sql/DataCell.zig @@ -1085,7 +1085,7 @@ pub const DataCell = extern struct { }; }; -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const std = @import("std"); diff --git a/src/sql/postgres.zig b/src/sql/postgres.zig index 4b1871b575..fc2a9d63c2 100644 --- a/src/sql/postgres.zig +++ b/src/sql/postgres.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const String = bun.String; const uws = bun.uws; @@ -281,15 +281,19 @@ pub const PostgresSQLQuery = struct { _padding: u2 = 0, } = .{}, - pub usingnamespace JSC.Codegen.JSPostgresSQLQuery; + pub const js = JSC.Codegen.JSPostgresSQLQuery; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; + pub fn getTarget(this: *PostgresSQLQuery, globalObject: *JSC.JSGlobalObject, clean_target: bool) JSC.JSValue { const thisValue = this.thisValue.get(); if (thisValue == .zero) { return .zero; } - const target = PostgresSQLQuery.targetGetCached(thisValue) orelse return .zero; + const target = js.targetGetCached(thisValue) orelse return .zero; if (clean_target) { - PostgresSQLQuery.targetSetCached(thisValue, globalObject, .zero); + js.targetSetCached(thisValue, globalObject, .zero); } return target; } @@ -500,14 +504,14 @@ pub const PostgresSQLQuery = struct { } defer thisValue.ensureStillAlive(); - PostgresSQLQuery.bindingSetCached(thisValue, globalObject, .zero); - PostgresSQLQuery.pendingValueSetCached(thisValue, globalObject, .zero); - PostgresSQLQuery.targetSetCached(thisValue, globalObject, .zero); + js.bindingSetCached(thisValue, globalObject, .zero); + js.pendingValueSetCached(thisValue, globalObject, .zero); + js.targetSetCached(thisValue, globalObject, .zero); } fn consumePendingValue(thisValue: JSC.JSValue, globalObject: *JSC.JSGlobalObject) ?JSValue { - const pending_value = PostgresSQLQuery.pendingValueGetCached(thisValue) orelse return null; - PostgresSQLQuery.pendingValueSetCached(thisValue, globalObject, .zero); + const pending_value = js.pendingValueGetCached(thisValue) orelse return null; + js.pendingValueSetCached(thisValue, globalObject, .zero); return pending_value; } @@ -540,7 +544,7 @@ pub const PostgresSQLQuery = struct { consumePendingValue(thisValue, globalObject) orelse .undefined, tag.toJSTag(globalObject), tag.toJSNumber(), - if (connection == .zero) .undefined else PostgresSQLConnection.queriesGetCached(connection) orelse .undefined, + if (connection == .zero) .undefined else PostgresSQLConnection.js.queriesGetCached(connection) orelse .undefined, JSValue.jsBoolean(is_last), }); } @@ -607,10 +611,10 @@ pub const PostgresSQLQuery = struct { }, }; - PostgresSQLQuery.bindingSetCached(this_value, globalThis, values); - PostgresSQLQuery.pendingValueSetCached(this_value, globalThis, pending_value); + js.bindingSetCached(this_value, globalThis, values); + js.pendingValueSetCached(this_value, globalThis, pending_value); if (columns != .undefined) { - PostgresSQLQuery.columnsSetCached(this_value, globalThis, columns); + js.columnsSetCached(this_value, globalThis, columns); } return this_value; @@ -628,7 +632,7 @@ pub const PostgresSQLQuery = struct { } pub fn setPendingValue(this: *PostgresSQLQuery, globalObject: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) bun.JSError!JSValue { const result = callframe.argument(0); - PostgresSQLQuery.pendingValueSetCached(this.thisValue.get(), globalObject, result); + js.pendingValueSetCached(this.thisValue.get(), globalObject, result); return .undefined; } pub fn setMode(this: *PostgresSQLQuery, globalObject: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) bun.JSError!JSValue { @@ -659,7 +663,7 @@ pub const PostgresSQLQuery = struct { } const this_value = callframe.this(); - const binding_value = PostgresSQLQuery.bindingGetCached(this_value) orelse .zero; + const binding_value = js.bindingGetCached(this_value) orelse .zero; var query_str = this.query.toUTF8(bun.default_allocator); defer query_str.deinit(); var writer = connection.writer(); @@ -694,7 +698,7 @@ pub const PostgresSQLQuery = struct { this.ref(); this.thisValue.upgrade(globalObject); - PostgresSQLQuery.targetSetCached(this_value, globalObject, query); + js.targetSetCached(this_value, globalObject, query); if (this.status == .running) { connection.flushDataAndResetTimeout(); } else { @@ -703,7 +707,7 @@ pub const PostgresSQLQuery = struct { return .undefined; } - const columns_value = PostgresSQLQuery.columnsGetCached(this_value) orelse .undefined; + const columns_value = js.columnsGetCached(this_value) orelse .undefined; var signature = Signature.generate(globalObject, query_str.slice(), binding_value, columns_value, connection.prepared_statement_id, connection.flags.use_unnamed_prepared_statements) catch |err| { if (!globalObject.hasException()) @@ -811,7 +815,7 @@ pub const PostgresSQLQuery = struct { this.ref(); this.thisValue.upgrade(globalObject); - PostgresSQLQuery.targetSetCached(this_value, globalObject, query); + js.targetSetCached(this_value, globalObject, query); if (did_write) { connection.flushDataAndResetTimeout(); } else { @@ -1357,7 +1361,10 @@ pub const PostgresSQLConnection = struct { failed, }; - pub usingnamespace JSC.Codegen.JSPostgresSQLConnection; + pub const js = JSC.Codegen.JSPostgresSQLConnection; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; fn getTimeoutInterval(this: *const PostgresSQLConnection) u32 { return switch (this.status) { @@ -1388,18 +1395,18 @@ pub const PostgresSQLConnection = struct { } pub fn getQueries(_: *PostgresSQLConnection, thisValue: JSC.JSValue, globalObject: *JSC.JSGlobalObject) JSC.JSValue { - if (PostgresSQLConnection.queriesGetCached(thisValue)) |value| { + if (js.queriesGetCached(thisValue)) |value| { return value; } const array = JSC.JSValue.createEmptyArray(globalObject, 0); - PostgresSQLConnection.queriesSetCached(thisValue, globalObject, array); + js.queriesSetCached(thisValue, globalObject, array); return array; } pub fn getOnConnect(_: *PostgresSQLConnection, thisValue: JSC.JSValue, _: *JSC.JSGlobalObject) JSC.JSValue { - if (PostgresSQLConnection.onconnectGetCached(thisValue)) |value| { + if (js.onconnectGetCached(thisValue)) |value| { return value; } @@ -1407,12 +1414,12 @@ pub const PostgresSQLConnection = struct { } pub fn setOnConnect(_: *PostgresSQLConnection, thisValue: JSC.JSValue, globalObject: *JSC.JSGlobalObject, value: JSC.JSValue) bool { - PostgresSQLConnection.onconnectSetCached(thisValue, globalObject, value); + js.onconnectSetCached(thisValue, globalObject, value); return true; } pub fn getOnClose(_: *PostgresSQLConnection, thisValue: JSC.JSValue, _: *JSC.JSGlobalObject) JSC.JSValue { - if (PostgresSQLConnection.oncloseGetCached(thisValue)) |value| { + if (js.oncloseGetCached(thisValue)) |value| { return value; } @@ -1420,7 +1427,7 @@ pub const PostgresSQLConnection = struct { } pub fn setOnClose(_: *PostgresSQLConnection, thisValue: JSC.JSValue, globalObject: *JSC.JSGlobalObject, value: JSC.JSValue) bool { - PostgresSQLConnection.oncloseSetCached(thisValue, globalObject, value); + js.oncloseSetCached(thisValue, globalObject, value); return true; } @@ -1937,8 +1944,8 @@ pub const PostgresSQLConnection = struct { js_value.ensureStillAlive(); ptr.js_value = js_value; - PostgresSQLConnection.onconnectSetCached(js_value, globalObject, on_connect); - PostgresSQLConnection.oncloseSetCached(js_value, globalObject, on_close); + js.onconnectSetCached(js_value, globalObject, on_connect); + js.oncloseSetCached(js_value, globalObject, on_close); bun.analytics.Features.postgres_connections += 1; { @@ -2268,8 +2275,8 @@ pub const PostgresSQLConnection = struct { .prepared => { const thisValue = req.thisValue.get(); bun.assert(thisValue != .zero); - const binding_value = PostgresSQLQuery.bindingGetCached(thisValue) orelse .zero; - const columns_value = PostgresSQLQuery.columnsGetCached(thisValue) orelse .zero; + const binding_value = PostgresSQLQuery.js.bindingGetCached(thisValue) orelse .zero; + const columns_value = PostgresSQLQuery.js.columnsGetCached(thisValue) orelse .zero; req.flags.binary = stmt.fields.len > 0; PostgresRequest.bindAndExecute(this.globalObject, stmt, binding_value, columns_value, PostgresSQLConnection.Writer, this.writer()) catch |err| { @@ -2293,7 +2300,7 @@ pub const PostgresSQLConnection = struct { const thisValue = req.thisValue.get(); bun.assert(thisValue != .zero); // prepareAndQueryWithSignature will write + bind + execute, it will change to running after binding is complete - const binding_value = PostgresSQLQuery.bindingGetCached(thisValue) orelse .zero; + const binding_value = PostgresSQLQuery.js.bindingGetCached(thisValue) orelse .zero; PostgresRequest.prepareAndQueryWithSignature(this.globalObject, query_str.slice(), binding_value, PostgresSQLConnection.Writer, this.writer(), &stmt.signature) catch |err| { stmt.status = .failed; stmt.error_response = .{ .postgres_error = err }; @@ -2358,7 +2365,7 @@ pub const PostgresSQLConnection = struct { } pub fn getQueriesArray(this: *const PostgresSQLConnection) JSValue { - return PostgresSQLConnection.queriesGetCached(this.js_value) orelse .zero; + return js.queriesGetCached(this.js_value) orelse .zero; } pub const DataCell = @import("./DataCell.zig").DataCell; @@ -2372,7 +2379,7 @@ pub const PostgresSQLConnection = struct { var statement = request.statement orelse return error.ExpectedStatement; var structure: JSValue = .undefined; var cached_structure: ?PostgresCachedStructure = null; - // explict use switch without else so if new modes are added, we don't forget to check for duplicate fields + // explicit use switch without else so if new modes are added, we don't forget to check for duplicate fields switch (request.flags.result_mode) { .objects => { cached_structure = statement.structure(this.js_value, this.globalObject); @@ -2405,7 +2412,7 @@ pub const PostgresSQLConnection = struct { cells = try bun.default_allocator.alloc(DataCell, statement.fields.len); free_cells = true; } - // make sure all cells are reseted if reader short breaks the fields will just be null with is better than undefined behavior + // make sure all cells are reset if reader short breaks the fields will just be null with is better than undefined behavior @memset(cells, DataCell{ .tag = .null, .value = .{ .null = 0 } }); putter.list = cells; @@ -2426,12 +2433,12 @@ pub const PostgresSQLConnection = struct { } const thisValue = request.thisValue.get(); bun.assert(thisValue != .zero); - const pending_value = PostgresSQLQuery.pendingValueGetCached(thisValue) orelse .zero; + const pending_value = PostgresSQLQuery.js.pendingValueGetCached(thisValue) orelse .zero; pending_value.ensureStillAlive(); const result = putter.toJS(this.globalObject, pending_value, structure, statement.fields_flags, request.flags.result_mode, cached_structure); if (pending_value == .zero) { - PostgresSQLQuery.pendingValueSetCached(thisValue, this.globalObject, result); + PostgresSQLQuery.js.pendingValueSetCached(thisValue, this.globalObject, result); } }, .CopyData => { @@ -2819,18 +2826,18 @@ pub const PostgresSQLConnection = struct { pub fn consumeOnConnectCallback(this: *const PostgresSQLConnection, globalObject: *JSC.JSGlobalObject) ?JSC.JSValue { debug("consumeOnConnectCallback", .{}); - const on_connect = PostgresSQLConnection.onconnectGetCached(this.js_value) orelse return null; + const on_connect = js.onconnectGetCached(this.js_value) orelse return null; debug("consumeOnConnectCallback exists", .{}); - PostgresSQLConnection.onconnectSetCached(this.js_value, globalObject, .zero); + js.onconnectSetCached(this.js_value, globalObject, .zero); return on_connect; } pub fn consumeOnCloseCallback(this: *const PostgresSQLConnection, globalObject: *JSC.JSGlobalObject) ?JSC.JSValue { debug("consumeOnCloseCallback", .{}); - const on_close = PostgresSQLConnection.oncloseGetCached(this.js_value) orelse return null; + const on_close = js.oncloseGetCached(this.js_value) orelse return null; debug("consumeOnCloseCallback exists", .{}); - PostgresSQLConnection.oncloseSetCached(this.js_value, globalObject, .zero); + js.oncloseSetCached(this.js_value, globalObject, .zero); return on_close; } }; @@ -3262,7 +3269,7 @@ const Signature = struct { pub fn createBinding(globalObject: *JSC.JSGlobalObject) JSValue { const binding = JSValue.createEmptyObjectWithNullPrototype(globalObject); - binding.put(globalObject, ZigString.static("PostgresSQLConnection"), PostgresSQLConnection.getConstructor(globalObject)); + binding.put(globalObject, ZigString.static("PostgresSQLConnection"), PostgresSQLConnection.js.getConstructor(globalObject)); binding.put(globalObject, ZigString.static("init"), JSC.JSFunction.create(globalObject, "init", PostgresSQLContext.init, 0, .{})); binding.put( globalObject, diff --git a/src/sql/postgres/postgres_protocol.zig b/src/sql/postgres/postgres_protocol.zig index 0416db70a0..57fdd8b311 100644 --- a/src/sql/postgres/postgres_protocol.zig +++ b/src/sql/postgres/postgres_protocol.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const postgres = bun.JSC.Postgres; const Data = postgres.Data; const protocol = @This(); diff --git a/src/sql/postgres/postgres_types.zig b/src/sql/postgres/postgres_types.zig index ebff7b2ed2..e9f34cf0d2 100644 --- a/src/sql/postgres/postgres_types.zig +++ b/src/sql/postgres/postgres_types.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const postgres = bun.JSC.Postgres; const Data = postgres.Data; const protocol = @This(); diff --git a/src/string.zig b/src/string.zig index 81e9b94b3d..655fc9f2a2 100644 --- a/src/string.zig +++ b/src/string.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const JSValue = bun.JSC.JSValue; const OOM = bun.OOM; diff --git a/src/string/HashedString.zig b/src/string/HashedString.zig index f14731442a..8b24ca01a6 100644 --- a/src/string/HashedString.zig +++ b/src/string/HashedString.zig @@ -1,5 +1,5 @@ const HashedString = @This(); -const bun = @import("root").bun; +const bun = @import("bun"); ptr: [*]const u8, len: u32, diff --git a/src/string/MutableString.zig b/src/string/MutableString.zig index 7f1dcc298b..489a0941c1 100644 --- a/src/string/MutableString.zig +++ b/src/string/MutableString.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Allocator = std.mem.Allocator; const strings = bun.strings; diff --git a/src/string/PathString.zig b/src/string/PathString.zig index 32d1eb1f46..650ffb3c81 100644 --- a/src/string/PathString.zig +++ b/src/string/PathString.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const PathIntLen = std.math.IntFittingRange(0, bun.MAX_PATH_BYTES); const use_small_path_string_ = @bitSizeOf(usize) - @bitSizeOf(PathIntLen) >= 53; diff --git a/src/string/StringBuilder.zig b/src/string/StringBuilder.zig index 1f570efeda..6988fd2ec5 100644 --- a/src/string/StringBuilder.zig +++ b/src/string/StringBuilder.zig @@ -1,6 +1,6 @@ const StringBuilder = @This(); const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Allocator = std.mem.Allocator; const Environment = bun.Environment; const assert = bun.assert; diff --git a/src/string/StringJoiner.zig b/src/string/StringJoiner.zig index 58e421bc8c..0ba0bb6f76 100644 --- a/src/string/StringJoiner.zig +++ b/src/string/StringJoiner.zig @@ -3,7 +3,7 @@ const StringJoiner = @This(); const std = @import("std"); const default_allocator = bun.default_allocator; -const bun = @import("root").bun; +const bun = @import("bun"); const Allocator = std.mem.Allocator; const NullableAllocator = bun.NullableAllocator; const assert = bun.assert; diff --git a/src/string/WTFStringImpl.zig b/src/string/WTFStringImpl.zig index 84d54aa669..876e5e6ba1 100644 --- a/src/string/WTFStringImpl.zig +++ b/src/string/WTFStringImpl.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const OOM = bun.OOM; diff --git a/src/string_immutable.zig b/src/string_immutable.zig index 26a48a3945..e570891bb3 100644 --- a/src/string_immutable.zig +++ b/src/string_immutable.zig @@ -4,7 +4,7 @@ const Environment = @import("./env.zig"); const string = bun.string; const stringZ = bun.stringZ; const CodePoint = bun.CodePoint; -const bun = @import("root").bun; +const bun = @import("bun"); const log = bun.Output.scoped(.STR, true); const js_lexer = @import("./js_lexer.zig"); const grapheme = @import("./grapheme.zig"); diff --git a/src/sync.zig b/src/sync.zig index 851cb1ac39..ea63c40920 100644 --- a/src/sync.zig +++ b/src/sync.zig @@ -1,6 +1,6 @@ const std = @import("std"); const system = if (bun.Environment.isWindows) std.os.windows else std.posix.system; -const bun = @import("root").bun; +const bun = @import("bun"); // https://gist.github.com/kprotty/0d2dc3da4840341d6ff361b27bdac7dc pub const ThreadPool = struct { diff --git a/src/sys.zig b/src/sys.zig index 808a2af26e..d8dc518347 100644 --- a/src/sys.zig +++ b/src/sys.zig @@ -3,7 +3,7 @@ const std = @import("std"); const builtin = @import("builtin"); -const bun = @import("root").bun; +const bun = @import("bun"); const posix = std.posix; const assertIsValidWindowsPath = bun.strings.assertIsValidWindowsPath; @@ -520,8 +520,11 @@ pub const Error = struct { err.dest = bun.String.createUTF8(this.dest); } - if (this.fd != bun.invalid_fd) { - err.fd = this.fd; + if (this.fd.unwrapValid()) |valid| { + // When the FD is a windows handle, there is no sane way to report this. + if (!Environment.isWindows or valid.kind == .uv) { + err.fd = valid.uv(); + } } return err; @@ -582,8 +585,11 @@ pub const Error = struct { err.dest = bun.String.createUTF8(this.dest); } - if (this.fd != bun.invalid_fd) { - err.fd = this.fd; + if (this.fd.unwrapValid()) |valid| { + // When the FD is a windows handle, there is no sane way to report this. + if (!Environment.isWindows or valid.kind == .uv) { + err.fd = valid.uv(); + } } return err; @@ -596,7 +602,7 @@ pub const Error = struct { return Error{ .errno = todo_errno, .syscall = .TODO }; } - pub fn toJS(this: Error, ctx: JSC.C.JSContextRef) JSC.C.JSObjectRef { + pub fn toJS(this: Error, ctx: *JSC.JSGlobalObject) JSC.C.JSObjectRef { return this.toSystemError().toErrorInstance(ctx).asObjectRef(); } @@ -838,11 +844,10 @@ pub fn lstat(path: [:0]const u8) Maybe(bun.Stat) { pub fn fstat(fd: bun.FileDescriptor) Maybe(bun.Stat) { if (Environment.isWindows) { - const dec = bun.FDImpl.decode(fd); - if (dec.kind == .system) { - const uvfd = bun.toLibUVOwnedFD(fd) catch return .{ .err = Error.fromCode(.MFILE, .uv_open_osfhandle) }; - return sys_uv.fstat(uvfd); - } else return sys_uv.fstat(fd); + // TODO: this is a bad usage of makeLibUVOwned + const uvfd = fd.makeLibUVOwned() catch + return .{ .err = Error.fromCode(.MFILE, .uv_open_osfhandle) }; + return sys_uv.fstat(uvfd); } var stat_ = mem.zeroes(bun.Stat); @@ -895,7 +900,7 @@ pub fn mkdiratW(dir_fd: bun.FileDescriptor, file_path: []const u16, _: i32) Mayb if (dir_to_make == .err) { return .{ .err = dir_to_make.err }; } - _ = close(dir_to_make.result); + dir_to_make.result.close(); return .{ .result = {} }; } @@ -903,15 +908,14 @@ pub fn fstatat(fd: bun.FileDescriptor, path: [:0]const u8) Maybe(bun.Stat) { if (Environment.isWindows) { return switch (openatWindowsA(fd, path, 0, 0)) { .result => |file| { - // :( - defer _ = close(file); + defer file.close(); return fstat(file); }, .err => |err| Maybe(bun.Stat){ .err = err }, }; } var stat_buf = mem.zeroes(bun.Stat); - const fd_valid = if (fd == bun.invalid_fd) std.posix.AT.FDCWD else fd.int(); + const fd_valid = if (fd == bun.invalid_fd) std.posix.AT.FDCWD else fd.native(); if (Maybe(bun.Stat).errnoSysFP(syscall.fstatat(fd_valid, path, &stat_buf, 0), .fstatat, fd, path)) |err| { log("fstatat({}, {s}) = {s}", .{ fd, path, @tagName(err.getErrno()) }); return err; @@ -1205,9 +1209,7 @@ fn openDirAtWindowsNtPath( switch (windows.Win32Error.fromNTStatus(rc)) { .SUCCESS => { - return .{ - .result = bun.toFD(fd), - }; + return .{ .result = .fromNative(fd) }; }, else => |code| { if (code.toSystemErrno()) |sys_err| { @@ -1253,7 +1255,7 @@ fn openWindowsDevicePath( .syscall = .open, } }; } - return .{ .result = bun.toFD(rc) }; + return .{ .result = .fromNative(rc) }; } pub const WindowsOpenDirOptions = packed struct { @@ -1440,9 +1442,7 @@ pub fn openFileAtWindowsNtPath( }; } } - return JSC.Maybe(bun.FileDescriptor){ - .result = bun.toFD(result), - }; + return .{ .result = .fromNative(result) }; }, else => |code| { if (code.toSystemErrno()) |sys_err| { @@ -1696,12 +1696,12 @@ fn openatWindowsTMaybeNormalize(comptime T: type, dir: bun.FileDescriptor, path: } pub fn openatWindows( - dir: anytype, + dir: bun.FileDescriptor, path: []const u16, flags: i32, perm: bun.Mode, ) Maybe(bun.FileDescriptor) { - return openatWindowsT(u16, bun.toFD(dir), path, flags, perm); + return openatWindowsT(u16, dir, path, flags, perm); } pub fn openatWindowsA( @@ -1720,7 +1720,7 @@ pub fn openatOSPath(dirfd: bun.FileDescriptor, file_path: bun.OSPathSliceZ, flag if (comptime Environment.allow_assert) log("openat({}, {s}, {d}) = {d}", .{ dirfd, bun.sliceTo(file_path, 0), flags, rc }); - return Maybe(bun.FileDescriptor).errnoSysFP(rc, .open, dirfd, file_path) orelse .{ .result = bun.toFD(rc) }; + return Maybe(bun.FileDescriptor).errnoSysFP(rc, .open, dirfd, file_path) orelse .{ .result = .fromNative(rc) }; } else if (comptime Environment.isWindows) { return openatWindowsT(bun.OSPathChar, dirfd, file_path, flags, perm); } @@ -1731,7 +1731,7 @@ pub fn openatOSPath(dirfd: bun.FileDescriptor, file_path: bun.OSPathSliceZ, flag log("openat({}, {s}, {d}) = {d}", .{ dirfd, bun.sliceTo(file_path, 0), flags, rc }); return switch (Syscall.getErrno(rc)) { - .SUCCESS => .{ .result = bun.toFD(@as(i32, @intCast(rc))) }, + .SUCCESS => .{ .result = .fromNative(@intCast(rc)) }, .INTR => continue, else => |err| { return .{ @@ -1813,7 +1813,7 @@ pub fn openatA(dirfd: bun.FileDescriptor, file_path: []const u8, flags: i32, per pub fn openA(file_path: []const u8, flags: i32, perm: bun.Mode) Maybe(bun.FileDescriptor) { // this is what open() does anyway. - return openatA(bun.FD.cwd(), file_path, flags, perm); + return openatA(.cwd(), file_path, flags, perm); } pub fn open(file_path: [:0]const u8, flags: i32, perm: bun.Mode) Maybe(bun.FileDescriptor) { @@ -1825,25 +1825,7 @@ pub fn open(file_path: [:0]const u8, flags: i32, perm: bun.Mode) Maybe(bun.FileD } // this is what open() does anyway. - return openat(bun.toFD(std.posix.AT.FDCWD), file_path, flags, perm); -} - -/// This function will prevent stdout and stderr from being closed. -pub fn close(fd: bun.FileDescriptor) ?Syscall.Error { - return bun.FDImpl.decode(fd).close(); -} - -pub fn close2(fd: bun.FileDescriptor) ?Syscall.Error { - if (fd == bun.STDOUT_FD or fd == bun.STDERR_FD or fd == bun.STDIN_FD) { - log("close({}) SKIPPED", .{fd}); - return null; - } - - return closeAllowingStdinStdoutAndStderr(fd); -} - -pub fn closeAllowingStdinStdoutAndStderr(fd: bun.FileDescriptor) ?Syscall.Error { - return bun.FDImpl.decode(fd).closeAllowingStdinStdoutAndStderr(); + return openat(.cwd(), file_path, flags, perm); } pub const max_count = switch (builtin.os.tag) { @@ -2175,11 +2157,11 @@ pub fn read(fd: bun.FileDescriptor, buf: []u8) Maybe(usize) { return Maybe(usize){ .result = @as(usize, @intCast(rc)) }; } }, - .windows => if (bun.FDImpl.decode(fd).kind == .uv) + .windows => if (fd.kind == .uv) sys_uv.read(fd, buf) else { var amount_read: u32 = 0; - const rc = kernel32.ReadFile(fd.cast(), buf.ptr, @as(u32, @intCast(adjusted_len)), &amount_read, null); + const rc = kernel32.ReadFile(fd.native(), buf.ptr, @as(u32, @intCast(adjusted_len)), &amount_read, null); if (rc == windows.FALSE) { const ret: Maybe(usize) = .{ .err = Syscall.Error{ @@ -2453,7 +2435,7 @@ pub fn renameatConcurrentlyWithoutFallback( // sad path: let's try to delete the folder and then rename it if (to_dir_fd.isValid()) { - var to_dir = to_dir_fd.asDir(); + var to_dir = to_dir_fd.stdDir(); to_dir.deleteTree(to) catch {}; } else { std.fs.deleteTreeAbsolute(to) catch {}; @@ -2822,11 +2804,11 @@ pub fn mmapFile(path: [:0]const u8, flags: std.c.MAP, wanted_size: ?usize, offse .result => |fd| fd, .err => |err| return .{ .err = err }, }; + defer fd.close(); var size = std.math.sub(usize, @as(usize, @intCast(switch (fstat(fd)) { .result => |result| result.size, .err => |err| { - _ = close(fd); return .{ .err = err }; }, })), offset) catch 0; @@ -2837,16 +2819,10 @@ pub fn mmapFile(path: [:0]const u8, flags: std.c.MAP, wanted_size: ?usize, offse .result => |map| map, .err => |err| { - _ = close(fd); return .{ .err = err }; }, }; - if (close(fd)) |err| { - _ = munmap(map); - return .{ .err = err }; - } - return .{ .result = map }; } @@ -2932,7 +2908,7 @@ pub fn socketpair(domain: socketpair_t, socktype: socketpair_t, protocol: socket // Set O_CLOEXEC first. inline for (0..2) |i| { - switch (setCloseOnExec(bun.toFD(fds_i[i]))) { + switch (setCloseOnExec(.fromNative(fds_i[i]))) { .err => |err| break :err err, .result => {}, } @@ -2940,7 +2916,7 @@ pub fn socketpair(domain: socketpair_t, socktype: socketpair_t, protocol: socket if (comptime Environment.isMac) { inline for (0..2) |i| { - switch (setNoSigpipe(bun.toFD(fds_i[i]))) { + switch (setNoSigpipe(.fromNative(fds_i[i]))) { .err => |err| break :err err, else => {}, } @@ -2949,7 +2925,7 @@ pub fn socketpair(domain: socketpair_t, socktype: socketpair_t, protocol: socket if (nonblocking_status == .nonblocking) { inline for (0..2) |i| { - switch (setNonblocking(bun.toFD(fds_i[i]))) { + switch (setNonblocking(.fromNative(fds_i[i]))) { .err => |err| break :err err, .result => {}, } @@ -2962,7 +2938,7 @@ pub fn socketpair(domain: socketpair_t, socktype: socketpair_t, protocol: socket // On any error after socketpair(), we need to close it. if (err) |errr| { inline for (0..2) |i| { - _ = close(bun.toFD(fds_i[i])); + bun.FD.fromNative(fds_i[i]).close(); } log("socketpair() = {d} {s}", .{ errr.errno, errr.name() }); @@ -2973,7 +2949,7 @@ pub fn socketpair(domain: socketpair_t, socktype: socketpair_t, protocol: socket log("socketpair() = [{d} {d}]", .{ fds_i[0], fds_i[1] }); - return Maybe([2]bun.FileDescriptor){ .result = .{ bun.toFD(fds_i[0]), bun.toFD(fds_i[1]) } }; + return Maybe([2]bun.FileDescriptor){ .result = .{ .fromNative(fds_i[0]), .fromNative(fds_i[1]) } }; } pub fn munmap(memory: []align(page_size_min) const u8) Maybe(void) { @@ -2990,7 +2966,7 @@ pub fn memfd_create(name: [:0]const u8, flags: u32) Maybe(bun.FileDescriptor) { log("memfd_create({s}, {d}) = {d}", .{ name, flags, rc }); return Maybe(bun.FileDescriptor).errnoSys(rc, .memfd_create) orelse - .{ .result = bun.toFD(@as(c_int, @intCast(rc))) }; + .{ .result = .fromNative(@intCast(rc)) }; } pub fn setPipeCapacityOnLinux(fd: bun.FileDescriptor, capacity: usize) Maybe(usize) { @@ -3040,7 +3016,7 @@ pub fn getMaxPipeSizeOnLinux() usize { return default_out_size; }, }; - defer _ = bun.sys.close(pipe_max_size_fd); + defer pipe_max_size_fd.close(); var max_pipe_size_buf: [128]u8 = undefined; const max_pipe_size = switch (bun.sys.read(pipe_max_size_fd, max_pipe_size_buf[0..])) { .result => |bytes_read| std.fmt.parseInt(i64, strings.trim(max_pipe_size_buf[0..bytes_read], "\n"), 10) catch |err| { @@ -3200,9 +3176,8 @@ pub fn existsZ(path: [:0]const u8) bool { } } -pub fn faccessat(dir_: anytype, subpath: anytype) JSC.Maybe(bool) { +pub fn faccessat(dir_fd: bun.FileDescriptor, subpath: anytype) JSC.Maybe(bool) { const has_sentinel = std.meta.sentinel(@TypeOf(subpath)) != null; - const dir_fd = bun.toFD(dir_); if (comptime !has_sentinel) { const path = std.os.toPosixPath(subpath) catch return JSC.Maybe(bool){ .err = Error.fromCode(.NAMETOOLONG, .access) }; @@ -3230,9 +3205,8 @@ pub fn faccessat(dir_: anytype, subpath: anytype) JSC.Maybe(bool) { return JSC.Maybe(bool){ .result = false }; } -pub fn directoryExistsAt(dir: anytype, subpath: anytype) JSC.Maybe(bool) { - const dir_fd = bun.toFD(dir); - return switch (existsAtType(dir_fd, subpath)) { +pub fn directoryExistsAt(dir: bun.FileDescriptor, subpath: anytype) JSC.Maybe(bool) { + return switch (existsAtType(dir, subpath)) { // .err => |err| if (err.getErrno() == .NOENT) .{ .result = false } @@ -3548,7 +3522,7 @@ pub fn pipe() Maybe([2]bun.FileDescriptor) { return err; } log("pipe() = [{d}, {d}]", .{ fds[0], fds[1] }); - return .{ .result = .{ bun.toFD(fds[0]), bun.toFD(fds[1]) } }; + return .{ .result = .{ .fromNative(fds[0]), .fromNative(fds[1]) } }; } pub fn openNullDevice() Maybe(bun.FileDescriptor) { @@ -3578,8 +3552,9 @@ pub fn dupWithFlags(fd: bun.FileDescriptor, _: i32) Maybe(bun.FileDescriptor) { return err; } } - log("dup({}) = {}", .{ fd, bun.toFD(target) }); - return Maybe(bun.FileDescriptor){ .result = bun.toFD(target) }; + const duplicated_fd = bun.FD.fromNative(target); + log("dup({}) = {}", .{ fd, duplicated_fd }); + return Maybe(bun.FileDescriptor){ .result = duplicated_fd }; } const ArgType = if (comptime Environment.isLinux) usize else c_int; @@ -3588,9 +3563,7 @@ pub fn dupWithFlags(fd: bun.FileDescriptor, _: i32) Maybe(bun.FileDescriptor) { .err => |err| return .{ .err = err }, }; - return Maybe(bun.FileDescriptor){ - .result = bun.toFD(@as(u32, @intCast(out))), - }; + return .initResult(.fromNative(@intCast(out))); } pub fn dup(fd: bun.FileDescriptor) Maybe(bun.FileDescriptor) { @@ -3695,7 +3668,7 @@ pub fn readNonblocking(fd: bun.FileDescriptor, buf: []u8) Maybe(usize) { var debug_timer = bun.Output.DebugTimer.start(); // Note that there is a bug on Linux Kernel 5 - const rc = C.sys_preadv2(@intCast(fd.int()), &iovec, 1, -1, std.os.linux.RWF.NOWAIT); + const rc = C.sys_preadv2(fd.native(), &iovec, 1, -1, std.os.linux.RWF.NOWAIT); if (comptime Environment.isDebug) { log("preadv2({}, {d}) = {d} ({})", .{ fd, buf.len, rc, debug_timer }); @@ -3739,7 +3712,7 @@ pub fn writeNonblocking(fd: bun.FileDescriptor, buf: []const u8) Maybe(usize) { var debug_timer = bun.Output.DebugTimer.start(); - const rc = C.sys_pwritev2(@intCast(fd.int()), &iovec, 1, -1, std.os.linux.RWF.NOWAIT); + const rc = C.sys_pwritev2(fd.native(), &iovec, 1, -1, std.os.linux.RWF.NOWAIT); if (comptime Environment.isDebug) { log("pwritev2({}, {d}) = {d} ({})", .{ fd, buf.len, rc, debug_timer }); @@ -3798,12 +3771,13 @@ pub fn isPollable(mode: mode_t) bool { const This = @This(); +/// TODO: make these all methods on `bun.FD`, and define them as methods `bun.FD` pub const File = struct { // "handle" matches std.fs.File handle: bun.FileDescriptor, - pub fn openat(other: anytype, path: [:0]const u8, flags: i32, mode: bun.Mode) Maybe(File) { - return switch (This.openat(bun.toFD(other), path, flags, mode)) { + pub fn openat(dir: bun.FileDescriptor, path: [:0]const u8, flags: i32, mode: bun.Mode) Maybe(File) { + return switch (This.openat(dir, path, flags, mode)) { .result => |fd| .{ .result = .{ .handle = fd } }, .err => |err| .{ .err = err }, }; @@ -3817,14 +3791,13 @@ pub const File = struct { return File.makeOpenat(bun.FD.cwd(), path, flags, mode); } - pub fn makeOpenat(other: anytype, path: [:0]const u8, flags: i32, mode: bun.Mode) Maybe(File) { - const dir = bun.toFD(other); - const fd = switch (This.openat(dir, path, flags, mode)) { + pub fn makeOpenat(other: bun.FD, path: [:0]const u8, flags: i32, mode: bun.Mode) Maybe(File) { + const fd = switch (This.openat(other, path, flags, mode)) { .result => |fd| fd, .err => |err| fd: { if (std.fs.path.dirname(path)) |dir_path| { - bun.makePath(dir.asDir(), dir_path) catch {}; - break :fd switch (This.openat(dir, path, flags, mode)) { + bun.makePath(other.stdDir(), dir_path) catch {}; + break :fd switch (This.openat(other, path, flags, mode)) { .result => |fd| fd, .err => |err2| return .{ .err = err2 }, }; @@ -3837,8 +3810,8 @@ pub const File = struct { return .{ .result = .{ .handle = fd } }; } - pub fn openatOSPath(other: anytype, path: bun.OSPathSliceZ, flags: i32, mode: bun.Mode) Maybe(File) { - return switch (This.openatOSPath(bun.toFD(other), path, flags, mode)) { + pub fn openatOSPath(other: bun.FD, path: bun.OSPathSliceZ, flags: i32, mode: bun.Mode) Maybe(File) { + return switch (This.openatOSPath(other, path, flags, mode)) { .result => |fd| .{ .result = .{ .handle = fd } }, .err => |err| .{ .err = err }, }; @@ -3852,30 +3825,24 @@ pub const File = struct { } if (T == std.posix.fd_t) { - return File{ .handle = bun.toFD(other) }; + return .{ .handle = .fromNative(other) }; } if (T == bun.FileDescriptor) { - return File{ .handle = other }; + return .{ .handle = other }; } if (T == std.fs.File) { - return File{ .handle = bun.toFD(other.handle) }; + return .{ .handle = .fromStdFile(other) }; } if (T == std.fs.Dir) { - return File{ .handle = bun.toFD(other.fd) }; - } - - if (comptime Environment.isWindows) { - if (T == bun.windows.HANDLE) { - return File{ .handle = bun.toFD(other) }; - } + return File{ .handle = .fromStdDir(other) }; } if (comptime Environment.isLinux) { if (T == u64) { - return File{ .handle = bun.toFD(other) }; + return File{ .handle = .fromNative(@intCast(other)) }; } } @@ -3936,7 +3903,8 @@ pub const File = struct { defer if (Environment.isPosix) this.close(); // On Windows, close the file before moving it. if (Environment.isWindows) this.close(); - try bun.C.moveFileZWithHandle(this.handle, bun.toFD(std.fs.cwd()), src, bun.toFD(std.fs.cwd()), dest); + const cwd = bun.FD.cwd(); + try bun.C.moveFileZWithHandle(this.handle, cwd, src, cwd, dest); } fn stdIoRead(this: File, buf: []u8) ReadError!usize { @@ -3979,9 +3947,9 @@ pub const File = struct { return std.posix.isatty(self.handle.cast()); } + /// Asserts in debug that this File object is valid pub fn close(self: File) void { - // TODO: probably return the error? we have a lot of code paths which do not so we are keeping for now - _ = This.close(self.handle); + self.handle.close(); } pub fn getEndPos(self: File) Maybe(usize) { @@ -4221,32 +4189,6 @@ pub const File = struct { } }; -pub inline fn toLibUVOwnedFD( - maybe_windows_fd: bun.FileDescriptor, - comptime syscall_tag: Syscall.Tag, - comptime error_case: enum { close_on_fail, leak_fd_on_fail }, -) Maybe(bun.FileDescriptor) { - if (!Environment.isWindows) { - return .{ .result = maybe_windows_fd }; - } - - return .{ - .result = bun.toLibUVOwnedFD(maybe_windows_fd) catch |err| switch (err) { - error.SystemFdQuotaExceeded => { - if (error_case == .close_on_fail) { - _ = close(maybe_windows_fd); - } - return .{ - .err = .{ - .errno = @intFromEnum(bun.C.E.MFILE), - .syscall = syscall_tag, - }, - }; - }, - }, - }; -} - pub const Dir = @import("./dir.zig"); const FILE_SHARE = w.FILE_SHARE_WRITE | w.FILE_SHARE_READ | w.FILE_SHARE_DELETE; diff --git a/src/sys_uv.zig b/src/sys_uv.zig index 9a574bd581..f96e60cb1e 100644 --- a/src/sys_uv.zig +++ b/src/sys_uv.zig @@ -2,7 +2,7 @@ //! TODO: Probably should merge this into bun.sys itself with isWindows checks const std = @import("std"); const posix = std.posix; -const bun = @import("root").bun; +const bun = @import("bun"); const assertIsValidWindowsPath = bun.strings.assertIsValidWindowsPath; const fd_t = bun.FileDescriptor; @@ -14,7 +14,6 @@ const uv = bun.windows.libuv; const C = bun.C; const E = C.E; const Environment = bun.Environment; -const FDImpl = bun.FDImpl; const FileDescriptor = bun.FileDescriptor; const JSC = bun.JSC; const MAX_PATH_BYTES = bun.MAX_PATH_BYTES; @@ -28,7 +27,7 @@ comptime { pub const log = bun.sys.syslog; pub const Error = bun.sys.Error; -// libuv dont suppport openat (https://github.com/libuv/libuv/issues/4167) +// libuv dont support openat (https://github.com/libuv/libuv/issues/4167) pub const openat = bun.sys.openat; pub const getFdPath = bun.sys.getFdPath; pub const setFileOffset = bun.sys.setFileOffset; @@ -36,7 +35,7 @@ pub const openatOSPath = bun.sys.openatOSPath; pub const mkdirOSPath = bun.sys.mkdirOSPath; pub const access = bun.sys.access; -// Note: `req = undefined; req.deinit()` has a saftey-check in a debug build +// Note: `req = undefined; req.deinit()` has a safety-check in a debug build pub fn open(file_path: [:0]const u8, c_flags: i32, _perm: bun.Mode) Maybe(bun.FileDescriptor) { assertIsValidWindowsPath(u8, file_path); @@ -48,7 +47,7 @@ pub fn open(file_path: [:0]const u8, c_flags: i32, _perm: bun.Mode) Maybe(bun.Fi var perm = _perm; if (perm == 0) { - // Set a sensible default, otherwise on windows the file will be unuseable + // Set a sensible default, otherwise on windows the file will be unusable perm = 0o644; } @@ -57,7 +56,7 @@ pub fn open(file_path: [:0]const u8, c_flags: i32, _perm: bun.Mode) Maybe(bun.Fi return if (rc.errno()) |errno| .{ .err = .{ .errno = errno, .syscall = .open, .path = file_path } } else - .{ .result = bun.toFD(@as(i32, @intCast(req.result.int()))) }; + .{ .result = req.result.toFD() }; } pub fn mkdir(file_path: [:0]const u8, flags: bun.Mode) Maybe(void) { @@ -88,7 +87,7 @@ pub fn chmod(file_path: [:0]const u8, flags: bun.Mode) Maybe(void) { } pub fn fchmod(fd: FileDescriptor, flags: bun.Mode) Maybe(void) { - const uv_fd = bun.uvfdcast(fd); + const uv_fd = fd.uv(); var req: uv.fs_t = uv.fs_t.uninitialized; defer req.deinit(); const rc = uv.uv_fs_fchmod(uv.Loop.get(), &req, uv_fd, flags, null); @@ -127,7 +126,7 @@ pub fn chown(file_path: [:0]const u8, uid: uv.uv_uid_t, gid: uv.uv_uid_t) Maybe( } pub fn fchown(fd: FileDescriptor, uid: uv.uv_uid_t, gid: uv.uv_uid_t) Maybe(void) { - const uv_fd = bun.uvfdcast(fd); + const uv_fd = fd.uv(); var req: uv.fs_t = uv.fs_t.uninitialized; defer req.deinit(); @@ -235,7 +234,7 @@ pub fn symlinkUV(target: [:0]const u8, new_path: [:0]const u8, flags: c_int) May } pub fn ftruncate(fd: FileDescriptor, size: isize) Maybe(void) { - const uv_fd = bun.uvfdcast(fd); + const uv_fd = fd.uv(); var req: uv.fs_t = uv.fs_t.uninitialized; defer req.deinit(); const rc = uv.uv_fs_ftruncate(uv.Loop.get(), &req, uv_fd, size, null); @@ -248,7 +247,7 @@ pub fn ftruncate(fd: FileDescriptor, size: isize) Maybe(void) { } pub fn fstat(fd: FileDescriptor) Maybe(bun.Stat) { - const uv_fd = bun.uvfdcast(fd); + const uv_fd = fd.uv(); var req: uv.fs_t = uv.fs_t.uninitialized; defer req.deinit(); const rc = uv.uv_fs_fstat(uv.Loop.get(), &req, uv_fd, null); @@ -261,7 +260,7 @@ pub fn fstat(fd: FileDescriptor) Maybe(bun.Stat) { } pub fn fdatasync(fd: FileDescriptor) Maybe(void) { - const uv_fd = bun.uvfdcast(fd); + const uv_fd = fd.uv(); var req: uv.fs_t = uv.fs_t.uninitialized; defer req.deinit(); const rc = uv.uv_fs_fdatasync(uv.Loop.get(), &req, uv_fd, null); @@ -274,7 +273,7 @@ pub fn fdatasync(fd: FileDescriptor) Maybe(void) { } pub fn fsync(fd: FileDescriptor) Maybe(void) { - const uv_fd = bun.uvfdcast(fd); + const uv_fd = fd.uv(); var req: uv.fs_t = uv.fs_t.uninitialized; defer req.deinit(); const rc = uv.uv_fs_fsync(uv.Loop.get(), &req, uv_fd, null); @@ -313,15 +312,15 @@ pub fn lstat(path: [:0]const u8) Maybe(bun.Stat) { } pub fn close(fd: FileDescriptor) ?bun.sys.Error { - return FDImpl.decode(fd).close(); + return fd.closeAllowingBadFileDescriptor(@returnAddress()); } pub fn closeAllowingStdoutAndStderr(fd: FileDescriptor) ?bun.sys.Error { - return FDImpl.decode(fd).closeAllowingStdoutAndStderr(); + return fd.closeAllowingStandardIo(@returnAddress()); } pub fn preadv(fd: FileDescriptor, bufs: []const bun.PlatformIOVec, position: i64) Maybe(usize) { - const uv_fd = bun.uvfdcast(fd); + const uv_fd = fd.uv(); comptime bun.assert(bun.PlatformIOVec == uv.uv_buf_t); const debug_timer = bun.Output.DebugTimer.start(); @@ -355,7 +354,7 @@ pub fn preadv(fd: FileDescriptor, bufs: []const bun.PlatformIOVec, position: i64 } pub fn pwritev(fd: FileDescriptor, bufs: []const bun.PlatformIOVecConst, position: i64) Maybe(usize) { - const uv_fd = bun.uvfdcast(fd); + const uv_fd = fd.uv(); comptime bun.assert(bun.PlatformIOVec == uv.uv_buf_t); const debug_timer = bun.Output.DebugTimer.start(); diff --git a/src/thread_pool.zig b/src/thread_pool.zig index 0d432cc336..de16fddf77 100644 --- a/src/thread_pool.zig +++ b/src/thread_pool.zig @@ -2,7 +2,7 @@ // https://github.com/kprotty/zap/blob/blog/src/thread_pool.zig const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const ThreadPool = @This(); const Futex = @import("./futex.zig"); diff --git a/src/tmp.zig b/src/tmp.zig index 9b1cd7a254..08eee9bf60 100644 --- a/src/tmp.zig +++ b/src/tmp.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const std = @import("std"); const Environment = bun.Environment; const O = bun.O; @@ -46,7 +46,7 @@ pub const Tmpfile = struct { } tmpfile.fd = switch (bun.sys.openat(destination_dir, tmpfilename, O.CREAT | O.CLOEXEC | O.WRONLY, perm)) { - .result => |fd| switch (bun.sys.toLibUVOwnedFD(fd, .open, .close_on_fail)) { + .result => |fd| switch (fd.makeLibUVOwnedForSyscall(.open, .close_on_fail)) { .result => |owned_fd| owned_fd, .err => |err| return .{ .err = err }, }, diff --git a/src/toml/toml_lexer.zig b/src/toml/toml_lexer.zig index fa3bbf2ce4..9b217e0cef 100644 --- a/src/toml/toml_lexer.zig +++ b/src/toml/toml_lexer.zig @@ -2,7 +2,7 @@ const std = @import("std"); const logger = bun.logger; const js_ast = bun.JSAst; -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/src/toml/toml_parser.zig b/src/toml/toml_parser.zig index 3d5a69e097..035d6fe19e 100644 --- a/src/toml/toml_parser.zig +++ b/src/toml/toml_parser.zig @@ -7,7 +7,7 @@ const js_ast = bun.JSAst; const options = @import("../options.zig"); const fs = @import("../fs.zig"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/src/tracy.zig b/src/tracy.zig index 2ca3874a81..341ded983b 100644 --- a/src/tracy.zig +++ b/src/tracy.zig @@ -8,7 +8,7 @@ const std = @import("std"); const builtin = @import("builtin"); const build_options = @import("build_options"); -const bun = @import("root").bun; +const bun = @import("bun"); pub const enable_allocation = false; pub const enable_callstack = false; diff --git a/src/transpiler.zig b/src/transpiler.zig index da4eb523c5..7a8f282d18 100644 --- a/src/transpiler.zig +++ b/src/transpiler.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; @@ -796,12 +796,14 @@ pub const Transpiler = struct { var pathname = try transpiler.allocator.alloc(u8, hashed_name.len + file_path.name.ext.len); bun.copy(u8, pathname, hashed_name); bun.copy(u8, pathname[hashed_name.len..], file_path.name.ext); - const dir = if (transpiler.options.output_dir_handle) |output_handle| bun.toFD(output_handle.fd) else .zero; output_file.value = .{ .copy = options.OutputFile.FileOperation{ .pathname = pathname, - .dir = dir, + .dir = if (transpiler.options.output_dir_handle) |output_handle| + .fromStdDir(output_handle) + else + .invalid, .is_outdir = true, }, }; diff --git a/src/unit_test.zig b/src/unit_test.zig index 7fd5b5bd48..f17f0887fd 100644 --- a/src/unit_test.zig +++ b/src/unit_test.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const t = std.testing; test { diff --git a/src/url.zig b/src/url.zig index 9e66497a1a..bb2705ce6a 100644 --- a/src/url.zig +++ b/src/url.zig @@ -1,7 +1,7 @@ const std = @import("std"); const Api = @import("./api/schema.zig").Api; const resolve_path = @import("./resolver/resolve_path.zig"); -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/src/util.zig b/src/util.zig index 04b2fa9a86..8e914df08e 100644 --- a/src/util.zig +++ b/src/util.zig @@ -1,6 +1,6 @@ // Things that maybe should go in Zig standard library at some point const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); pub fn Key(comptime Map: type) type { return FieldType(Map.KV, "key").?; diff --git a/src/valkey/ValkeyCommand.zig b/src/valkey/ValkeyCommand.zig index d1bae8e74f..325bd9cf9e 100644 --- a/src/valkey/ValkeyCommand.zig +++ b/src/valkey/ValkeyCommand.zig @@ -153,7 +153,7 @@ pub const PromisePair = struct { const Command = @This(); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const protocol = @import("valkey_protocol.zig"); const std = @import("std"); diff --git a/src/valkey/ValkeyContext.zig b/src/valkey/ValkeyContext.zig index 5feb901874..0dec255193 100644 --- a/src/valkey/ValkeyContext.zig +++ b/src/valkey/ValkeyContext.zig @@ -22,5 +22,5 @@ pub fn deinit(this: *@This()) void { } } -const bun = @import("root").bun; +const bun = @import("bun"); const uws = bun.uws; diff --git a/src/valkey/js_valkey.zig b/src/valkey/js_valkey.zig index e7820b04aa..84d7da2d96 100644 --- a/src/valkey/js_valkey.zig +++ b/src/valkey/js_valkey.zig @@ -20,7 +20,11 @@ pub const JSValkeyClient = struct { }, ref_count: RefCount, - pub usingnamespace JSC.Codegen.JSRedisClient; + pub const js = JSC.Codegen.JSRedisClient; + pub const toJS = js.toJS; + pub const fromJS = js.fromJS; + pub const fromJSDirect = js.fromJSDirect; + const RefCount = bun.ptr.RefCount(@This(), "ref_count", deinit, .{}); pub const ref = RefCount.ref; pub const deref = RefCount.deref; @@ -161,16 +165,16 @@ pub const JSValkeyClient = struct { // If already connected, resolve immediately if (this.client.status == .connected) { - return JSC.JSPromise.resolvedPromiseValue(globalObject, JSValkeyClient.helloGetCached(this_value) orelse .undefined); + return JSC.JSPromise.resolvedPromiseValue(globalObject, js.helloGetCached(this_value) orelse .undefined); } - if (JSValkeyClient.connectionPromiseGetCached(this_value)) |promise| { + if (js.connectionPromiseGetCached(this_value)) |promise| { return promise; } const promise_ptr = JSC.JSPromise.create(globalObject); const promise = promise_ptr.asValue(globalObject); - JSValkeyClient.connectionPromiseSetCached(this_value, globalObject, promise); + js.connectionPromiseSetCached(this_value, globalObject, promise); // If was manually closed, reset that flag this.client.flags.is_manually_closed = false; @@ -222,26 +226,26 @@ pub const JSValkeyClient = struct { } pub fn getOnConnect(_: *JSValkeyClient, thisValue: JSValue, _: *JSC.JSGlobalObject) JSValue { - if (JSValkeyClient.onconnectGetCached(thisValue)) |value| { + if (js.onconnectGetCached(thisValue)) |value| { return value; } return .undefined; } pub fn setOnConnect(_: *JSValkeyClient, thisValue: JSValue, globalObject: *JSC.JSGlobalObject, value: JSValue) bool { - JSValkeyClient.onconnectSetCached(thisValue, globalObject, value); + js.onconnectSetCached(thisValue, globalObject, value); return true; } pub fn getOnClose(_: *JSValkeyClient, thisValue: JSValue, _: *JSC.JSGlobalObject) JSValue { - if (JSValkeyClient.oncloseGetCached(thisValue)) |value| { + if (js.oncloseGetCached(thisValue)) |value| { return value; } return .undefined; } pub fn setOnClose(_: *JSValkeyClient, thisValue: JSValue, globalObject: *JSC.JSGlobalObject, value: JSValue) bool { - JSValkeyClient.oncloseSetCached(thisValue, globalObject, value); + js.oncloseSetCached(thisValue, globalObject, value); return true; } @@ -405,16 +409,16 @@ pub const JSValkeyClient = struct { if (this.this_value.tryGet()) |this_value| { const hello_value = value.toJS(globalObject) catch .undefined; - JSValkeyClient.helloSetCached(this_value, globalObject, hello_value); + js.helloSetCached(this_value, globalObject, hello_value); // Call onConnect callback if defined by the user - if (JSValkeyClient.onconnectGetCached(this_value)) |on_connect| { + if (js.onconnectGetCached(this_value)) |on_connect| { const js_value = this_value; js_value.ensureStillAlive(); globalObject.queueMicrotask(on_connect, &[_]JSValue{ js_value, hello_value }); } - if (JSValkeyClient.connectionPromiseGetCached(this_value)) |promise| { - JSValkeyClient.connectionPromiseSetCached(this_value, globalObject, .zero); + if (js.connectionPromiseGetCached(this_value)) |promise| { + js.connectionPromiseSetCached(this_value, globalObject, .zero); promise.asPromise().?.resolve(globalObject, hello_value); } } @@ -455,14 +459,14 @@ pub const JSValkeyClient = struct { defer loop.exit(); if (this_jsvalue != .undefined) { - if (JSValkeyClient.connectionPromiseGetCached(this_jsvalue)) |promise| { - JSValkeyClient.connectionPromiseSetCached(this_jsvalue, globalObject, .zero); + if (js.connectionPromiseGetCached(this_jsvalue)) |promise| { + js.connectionPromiseSetCached(this_jsvalue, globalObject, .zero); promise.asPromise().?.reject(globalObject, error_value); } } // Call onClose callback if it exists - if (JSValkeyClient.oncloseGetCached(this_jsvalue)) |on_close| { + if (js.oncloseGetCached(this_jsvalue)) |on_close| { _ = on_close.call( globalObject, this_jsvalue, @@ -483,7 +487,7 @@ pub const JSValkeyClient = struct { pub fn failWithJSValue(this: *JSValkeyClient, value: JSValue) void { const this_value = this.this_value.tryGet() orelse return; const globalObject = this.globalObject; - if (JSValkeyClient.oncloseGetCached(this_value)) |on_close| { + if (js.oncloseGetCached(this_value)) |on_close| { const loop = this.client.vm.eventLoop(); loop.enter(); defer loop.exit(); @@ -852,7 +856,7 @@ const Options = struct { }; const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const valkey = @import("valkey.zig"); const protocol = @import("valkey_protocol.zig"); const JSC = bun.JSC; diff --git a/src/valkey/js_valkey_functions.zig b/src/valkey/js_valkey_functions.zig index 94bf9d8042..d3f11768d6 100644 --- a/src/valkey/js_valkey_functions.zig +++ b/src/valkey/js_valkey_functions.zig @@ -776,7 +776,7 @@ const compile = struct { }; const JSValkeyClient = @import("./js_valkey.zig").JSValkeyClient; -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const valkey = bun.valkey; const protocol = valkey.protocol; diff --git a/src/valkey/valkey.zig b/src/valkey/valkey.zig index 1470facaf6..8b9be91a6e 100644 --- a/src/valkey/valkey.zig +++ b/src/valkey/valkey.zig @@ -965,7 +965,7 @@ const JSValkeyClient = JSC.API.Valkey; const JSC = bun.JSC; const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const protocol = @import("valkey_protocol.zig"); const js_valkey = @import("js_valkey.zig"); const debug = bun.Output.scoped(.Redis, false); diff --git a/src/valkey/valkey_protocol.zig b/src/valkey/valkey_protocol.zig index 7e7e3cfb0e..b2c1e4a706 100644 --- a/src/valkey/valkey_protocol.zig +++ b/src/valkey/valkey_protocol.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const JSC = bun.JSC; const String = bun.String; const debug = bun.Output.scoped(.Redis, false); diff --git a/src/walker_skippable.zig b/src/walker_skippable.zig index 332b6e512d..679c5192dd 100644 --- a/src/walker_skippable.zig +++ b/src/walker_skippable.zig @@ -1,7 +1,7 @@ const std = @import("std"); const Allocator = std.mem.Allocator; const Walker = @This(); -const bun = @import("root").bun; +const bun = @import("bun"); const path = std.fs.path; const DirIterator = bun.DirIterator; const Environment = bun.Environment; diff --git a/src/watcher/INotifyWatcher.zig b/src/watcher/INotifyWatcher.zig index 03c57615c2..d5ed05aa80 100644 --- a/src/watcher/INotifyWatcher.zig +++ b/src/watcher/INotifyWatcher.zig @@ -98,7 +98,7 @@ pub fn init(this: *INotifyWatcher, _: []const u8) !void { } // TODO: convert to bun.sys.Error - this.fd = bun.toFD(try std.posix.inotify_init1(IN.CLOEXEC)); + this.fd = .fromNative(try std.posix.inotify_init1(IN.CLOEXEC)); this.eventlist_bytes = &(try bun.default_allocator.alignedAlloc(EventListBytes, @alignOf(Event), 1))[0]; log("{} init", .{this.fd}); } @@ -219,7 +219,7 @@ pub fn read(this: *INotifyWatcher) bun.JSC.Maybe([]const *align(1) Event) { pub fn stop(this: *INotifyWatcher) void { log("{} stop", .{this.fd}); if (this.fd != bun.invalid_fd) { - _ = bun.sys.close(this.fd); + this.fd.close(); this.fd = bun.invalid_fd; } } @@ -315,7 +315,7 @@ pub fn watchEventFromInotifyEvent(event: *align(1) const INotifyWatcher.Event, i } const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Environment = bun.Environment; const Output = bun.Output; const Futex = bun.Futex; diff --git a/src/watcher/KEventWatcher.zig b/src/watcher/KEventWatcher.zig index cf823c59d2..08ca530419 100644 --- a/src/watcher/KEventWatcher.zig +++ b/src/watcher/KEventWatcher.zig @@ -7,20 +7,19 @@ const KEvent = std.c.Kevent; // Everything being watched eventlist_index: EventListIndex = 0, -fd: bun.FileDescriptor = bun.invalid_fd, +fd: bun.FD.Optional = .none, const changelist_count = 128; pub fn init(this: *KEventWatcher, _: []const u8) !void { const fd = try std.posix.kqueue(); if (fd == 0) return error.KQueueError; - this.fd = bun.toFD(fd); + this.fd = .init(.fromNative(fd)); } pub fn stop(this: *KEventWatcher) void { - if (this.fd.isValid()) { - _ = bun.sys.close(this.fd); - this.fd = bun.invalid_fd; + if (this.fd.take()) |fd| { + fd.close(); } } @@ -37,7 +36,8 @@ pub fn watchEventFromKEvent(kevent: KEvent) Watcher.Event { } pub fn watchLoopCycle(this: *Watcher) bun.JSC.Maybe(void) { - bun.assert(this.platform.fd.isValid()); + const fd: bun.FD = this.platform.fd.unwrap() orelse + @panic("KEventWatcher has an invalid file descriptor"); // not initialized each time var changelist_array: [changelist_count]KEvent = undefined; @@ -47,7 +47,7 @@ pub fn watchLoopCycle(this: *Watcher) bun.JSC.Maybe(void) { defer Output.flush(); var count = std.posix.system.kevent( - this.platform.fd.cast(), + fd.native(), changelist, 0, changelist, @@ -59,7 +59,7 @@ pub fn watchLoopCycle(this: *Watcher) bun.JSC.Maybe(void) { if (count < 128 / 2) { const remain = 128 - count; const extra = std.posix.system.kevent( - this.platform.fd.cast(), + fd.native(), changelist[@intCast(count)..].ptr, 0, changelist[@intCast(count)..].ptr, @@ -102,7 +102,7 @@ pub fn watchLoopCycle(this: *Watcher) bun.JSC.Maybe(void) { } const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Output = bun.Output; const Watcher = bun.Watcher; const max_eviction_count = Watcher.max_eviction_count; diff --git a/src/watcher/WindowsWatcher.zig b/src/watcher/WindowsWatcher.zig index 22106c04c7..67e7ef7879 100644 --- a/src/watcher/WindowsWatcher.zig +++ b/src/watcher/WindowsWatcher.zig @@ -284,7 +284,7 @@ pub fn createWatchEvent(event: FileEvent, index: WatchItemIndex) WatchEvent { } const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const Environment = bun.Environment; const Output = bun.Output; const log = Output.scoped(.watcher, false); diff --git a/src/which.zig b/src/which.zig index 0470af9d61..34bed1b26b 100644 --- a/src/which.zig +++ b/src/which.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const PosixToWinNormalizer = bun.path.PosixToWinNormalizer; fn isValid(buf: *bun.PathBuffer, segment: []const u8, bin: []const u8) ?u16 { diff --git a/src/which_npm_client.zig b/src/which_npm_client.zig index 7e90f12d34..d6791dcec5 100644 --- a/src/which_npm_client.zig +++ b/src/which_npm_client.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const string = bun.string; const Output = bun.Output; const Global = bun.Global; diff --git a/src/windows.zig b/src/windows.zig index dca9a7d0c4..498927506b 100644 --- a/src/windows.zig +++ b/src/windows.zig @@ -1,4 +1,4 @@ -const bun = @import("root").bun; +const bun = @import("bun"); const windows = std.os.windows; const win32 = windows; pub const PATH_MAX_WIDE = windows.PATH_MAX_WIDE; @@ -107,7 +107,7 @@ pub fn GetFileType(hFile: win32.HANDLE) win32.DWORD { const rc = function(hFile); if (comptime Environment.enable_logs) - bun.sys.syslog("GetFileType({}) = {d}", .{ bun.toFD(hFile), rc }); + bun.sys.syslog("GetFileType({}) = {d}", .{ bun.FD.fromNative(hFile), rc }); return rc; } diff --git a/src/windows_c.zig b/src/windows_c.zig index 21a91e741f..64930d5fbb 100644 --- a/src/windows_c.zig +++ b/src/windows_c.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const builtin = @import("builtin"); const win32 = std.os.windows; const posix = std.posix; @@ -1260,7 +1260,7 @@ pub fn renameAtW( .result => |fd| break :brk fd, } }; - defer _ = bun.sys.close(src_fd); + defer src_fd.close(); return moveOpenedFileAt(src_fd, new_dir_fd, new_path_w, replace_if_exists); } @@ -1352,7 +1352,7 @@ pub fn moveOpenedFileAtLoose( .err => |e| return .{ .err = e }, .result => |fd| fd, }; - defer _ = bun.sys.close(fd); + defer fd.close(); const basename = new_path[last_slash + 1 ..]; return moveOpenedFileAt(src_fd, fd, basename, replace_if_exists); diff --git a/src/work_pool.zig b/src/work_pool.zig index 104e25bba1..d6479767dd 100644 --- a/src/work_pool.zig +++ b/src/work_pool.zig @@ -1,6 +1,6 @@ const ThreadPool = bun.ThreadPool; const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); pub const Batch = ThreadPool.Batch; pub const Task = ThreadPool.Task; diff --git a/src/wyhash.zig b/src/wyhash.zig index b4b72410aa..1d3a1a0ad8 100644 --- a/src/wyhash.zig +++ b/src/wyhash.zig @@ -1,7 +1,7 @@ // // this file is a copy of Wyhash from the zig standard library, version v0.11.0-dev.2609+5e19250a1 // -const assert = if (@hasDecl(@import("root"), "bun")) (@import("root").bun).assert else @import("std").debug.assert; +const assert = if (@hasDecl(@import("root"), "bun")) @import("root").bun.assert else @import("std").debug.assert; const std = @import("std"); const mem = std.mem; diff --git a/src/zlib.zig b/src/zlib.zig index 537d047709..9b0a4581fb 100644 --- a/src/zlib.zig +++ b/src/zlib.zig @@ -1,7 +1,7 @@ // @link "deps/zlib/libz.a" const std = @import("std"); -const bun = @import("root").bun; +const bun = @import("bun"); const mimalloc = @import("./allocators/mimalloc.zig"); diff --git a/test/bundler/bun-build-api.test.ts b/test/bundler/bun-build-api.test.ts index 0524231ae0..4ad15e2595 100644 --- a/test/bundler/bun-build-api.test.ts +++ b/test/bundler/bun-build-api.test.ts @@ -1,8 +1,8 @@ +import assert from "assert"; import { describe, expect, test } from "bun:test"; import { readFileSync, writeFileSync } from "fs"; import { bunEnv, bunExe, tempDirWithFiles } from "harness"; import path, { join } from "path"; -import assert from "assert"; import { buildNoThrow } from "./buildNoThrow"; describe("Bun.build", () => { diff --git a/test/integration/bun-types/bun-types.test.ts b/test/integration/bun-types/bun-types.test.ts index 6719147e09..8d84445c41 100644 --- a/test/integration/bun-types/bun-types.test.ts +++ b/test/integration/bun-types/bun-types.test.ts @@ -122,7 +122,23 @@ describe("@types/bun integration test", () => { "error TS2339: Property 'write' does not exist on type 'ReadableByteStreamController'.", "websocket.ts", - "error TS2353: Object literal may only specify known properties, and 'headers' does not exist in type 'string[]'.", + `error TS2353: Object literal may only specify known properties, and 'protocols' does not exist in type 'string[]'.`, + `error TS2353: Object literal may only specify known properties, and 'protocol' does not exist in type 'string[]'.`, + `error TS2353: Object literal may only specify known properties, and 'protocol' does not exist in type 'string[]'.`, + `error TS2353: Object literal may only specify known properties, and 'headers' does not exist in type 'string[]'.`, + `error TS2353: Object literal may only specify known properties, and 'protocols' does not exist in type 'string[]'.`, + `error TS2554: Expected 2 arguments, but got 0.`, + `error TS2551: Property 'URL' does not exist on type 'WebSocket'. Did you mean 'url'?`, + `error TS2322: Type '"nodebuffer"' is not assignable to type 'BinaryType'.`, + `error TS2339: Property 'ping' does not exist on type 'WebSocket'.`, + `error TS2339: Property 'ping' does not exist on type 'WebSocket'.`, + `error TS2339: Property 'ping' does not exist on type 'WebSocket'.`, + `error TS2339: Property 'ping' does not exist on type 'WebSocket'.`, + `error TS2339: Property 'pong' does not exist on type 'WebSocket'.`, + `error TS2339: Property 'pong' does not exist on type 'WebSocket'.`, + `error TS2339: Property 'pong' does not exist on type 'WebSocket'.`, + `error TS2339: Property 'pong' does not exist on type 'WebSocket'.`, + `error TS2339: Property 'terminate' does not exist on type 'WebSocket'.`, "worker.ts", "error TS2339: Property 'ref' does not exist on type 'Worker'.", diff --git a/test/integration/bun-types/fixture/dns.ts b/test/integration/bun-types/fixture/dns.ts index 3f701f346e..0f2ab24311 100644 --- a/test/integration/bun-types/fixture/dns.ts +++ b/test/integration/bun-types/fixture/dns.ts @@ -1,5 +1,19 @@ +import { dns as bun_dns } from "bun"; import * as dns from "node:dns"; +import { expectType } from "./utilities"; dns.resolve("asdf", "A", () => {}); dns.reverse("asdf", () => {}); dns.getServers(); + +expectType(Bun.dns.getCacheStats()).is<{ + cacheHitsCompleted: number; + cacheHitsInflight: number; + cacheMisses: number; + size: number; + errors: number; + totalCount: number; +}>(); + +expectType(Bun.dns.V4MAPPED).is(); +expectType(bun_dns.prefetch("bun.sh")).is(); diff --git a/test/integration/bun-types/fixture/index.ts b/test/integration/bun-types/fixture/index.ts index 4328b720d7..7265e16ca5 100644 --- a/test/integration/bun-types/fixture/index.ts +++ b/test/integration/bun-types/fixture/index.ts @@ -22,6 +22,8 @@ import * as sqlite from "bun:sqlite"; sqlite.Database; Bun satisfies typeof import("bun"); +expectType(Bun).is(); +expectType().is(); type ConstructorOf = new (...args: any[]) => T; diff --git a/test/integration/bun-types/fixture/toml.ts b/test/integration/bun-types/fixture/toml.ts index a9a77d4bed..1b14d31325 100644 --- a/test/integration/bun-types/fixture/toml.ts +++ b/test/integration/bun-types/fixture/toml.ts @@ -1,4 +1,7 @@ +import { TOML } from "bun"; import data from "./bunfig.toml"; import { expectType } from "./utilities"; expectType(data); +expectType(Bun.TOML.parse(data)).is(); +expectType(TOML.parse(data)).is(); diff --git a/test/integration/bun-types/fixture/websocket.ts b/test/integration/bun-types/fixture/websocket.ts index a1b11aeb09..b8de6edfc5 100644 --- a/test/integration/bun-types/fixture/websocket.ts +++ b/test/integration/bun-types/fixture/websocket.ts @@ -1,15 +1,271 @@ -export class TestWebSocketClient { - #ws: WebSocket; +import { expectType } from "./utilities"; - constructor() { - this.#ws = new WebSocket("wss://dev.local", { - headers: { - cookie: "test=test", - }, - }); - } +// WebSocket constructor tests +{ + // Constructor with string URL only + new WebSocket("wss://dev.local"); - close() { - if (this.#ws != null) this.#ws.close(); - } + // Constructor with string URL and protocols array + new WebSocket("wss://dev.local", ["proto1", "proto2"]); + + // Constructor with string URL and single protocol string + new WebSocket("wss://dev.local", "proto1"); + + // Constructor with URL object only + new WebSocket(new URL("wss://dev.local")); + + // Constructor with URL object and protocols array + new WebSocket(new URL("wss://dev.local"), ["proto1", "proto2"]); + + // Constructor with URL object and single protocol string + new WebSocket(new URL("wss://dev.local"), "proto1"); + + // Constructor with string URL and options object with protocols + new WebSocket("wss://dev.local", { + protocols: ["proto1", "proto2"], + }); + + // Constructor with string URL and options object with protocol + new WebSocket("wss://dev.local", { + protocol: "proto1", + }); + + // Constructor with URL object and options with TLS settings + new WebSocket(new URL("wss://dev.local"), { + protocol: "proto1", + tls: { + rejectUnauthorized: false, + }, + }); + + // Constructor with headers + new WebSocket("wss://dev.local", { + headers: { + "Cookie": "session=123456", + "User-Agent": "BunWebSocketTest", + }, + }); + + // Constructor with full options object + new WebSocket("wss://dev.local", { + protocols: ["proto1", "proto2"], + headers: { + "Cookie": "session=123456", + }, + tls: { + rejectUnauthorized: true, + }, + }); +} + +// Assignability test +{ + function toAny(value: T): any { + return value; + } + + const AnySocket = toAny(WebSocket); + + const ws: WebSocket = new AnySocket("wss://dev.local"); + + ws.close(); + ws.addEventListener("open", e => expectType(e).is()); + ws.addEventListener("message", e => expectType(e).is()); + ws.addEventListener("message", (e: MessageEvent) => expectType(e).is>()); + ws.addEventListener("message", (e: MessageEvent) => expectType(e.data).is()); +} + +// WebSocket static properties test +{ + expectType(WebSocket.CONNECTING).is<0>(); + expectType(WebSocket.OPEN).is<1>(); + expectType(WebSocket.CLOSING).is<2>(); + expectType(WebSocket.CLOSED).is<3>(); + + const instance: WebSocket = null as never; + expectType(instance.CONNECTING).is<0>(); + expectType(instance.OPEN).is<1>(); + expectType(instance.CLOSING).is<2>(); + expectType(instance.CLOSED).is<3>(); +} + +// WebSocket event handlers test +{ + const ws = new WebSocket("wss://dev.local"); + + // Using event handler properties + ws.onopen = (event: Event) => { + expectType(event).is(); + }; + + ws.onmessage = (event: MessageEvent) => { + expectType(event.data).is(); + }; + + ws.onerror = (event: Event) => { + expectType(event).is(); + }; + + ws.onclose = (event: CloseEvent) => { + expectType(event).is(); + expectType(event.code).is(); + expectType(event.reason).is(); + expectType(event.wasClean).is(); + }; + + // Using event handler properties without typing the agument + ws.onopen = event => { + expectType(event).is(); + }; + + ws.onmessage = event => { + expectType(event.data).is(); + + if (typeof event.data === "string") { + expectType(event.data).is(); + } else if (event.data instanceof ArrayBuffer) { + expectType(event.data).is(); + } + }; + + ws.onerror = event => { + expectType(event).is(); + }; + + ws.onclose = event => { + expectType(event).is(); + expectType(event.code).is(); + expectType(event.reason).is(); + expectType(event.wasClean).is(); + }; +} + +// WebSocket addEventListener test +{ + const ws = new WebSocket("wss://dev.local"); + + // Event handler functions + const handleOpen = (event: Event) => { + expectType(event).is(); + }; + + const handleMessage = (event: MessageEvent) => { + expectType(event.data).is(); + }; + + const handleError = (event: Event) => { + expectType(event).is(); + }; + + const handleClose = (event: CloseEvent) => { + expectType(event).is(); + expectType(event.code).is(); + expectType(event.reason).is(); + expectType(event.wasClean).is(); + }; + + // Add event listeners + ws.addEventListener("open", handleOpen); + ws.addEventListener("message", handleMessage); + ws.addEventListener("error", handleError); + ws.addEventListener("close", handleClose); + + // Remove event listeners + ws.removeEventListener("open", handleOpen); + ws.removeEventListener("message", handleMessage); + ws.removeEventListener("error", handleError); + ws.removeEventListener("close", handleClose); +} + +// WebSocket property access test +{ + const ws = new WebSocket("wss://dev.local"); + + // Read various properties + expectType(ws.readyState).is<0 | 2 | 1 | 3>(); + expectType(ws.bufferedAmount).is(); + expectType(ws.url).is(); + expectType(ws.protocol).is(); + expectType(ws.extensions).is(); + + // Legacy URL property (deprecated but exists) + expectType(ws.URL).is(); + + // Set binary type + ws.binaryType = "arraybuffer"; + ws.binaryType = "nodebuffer"; +} + +// WebSocket send method test +{ + const ws = new WebSocket("wss://dev.local"); + + // Send string data + ws.send("Hello, server!"); + + // Send ArrayBuffer + const buffer = new ArrayBuffer(10); + ws.send(buffer); + + // Send ArrayBufferView (Uint8Array) + const uint8Array = new Uint8Array(buffer); + ws.send(uint8Array); + + // --------------------------------------- // + // `.send(blob)` is not supported yet + // --------------------------------------- // + // // Send Blob + // const blob = new Blob(["Hello, server!"]); + // ws.send(blob); + // --------------------------------------- // +} + +// WebSocket close method test +{ + const ws = new WebSocket("wss://dev.local"); + + // Close without parameters + ws.close(); + + // Close with code + ws.close(1000); + + // Close with code and reason + ws.close(1001, "Going away"); +} + +// Bun-specific WebSocket extensions test +{ + const ws = new WebSocket("wss://dev.local"); + + // Send ping frame with no data + ws.ping(); + + // Send ping frame with string data + ws.ping("ping data"); + + // Send ping frame with ArrayBuffer + const pingBuffer = new ArrayBuffer(4); + ws.ping(pingBuffer); + + // Send ping frame with ArrayBufferView + const pingView = new Uint8Array(pingBuffer); + ws.ping(pingView); + + // Send pong frame with no data + ws.pong(); + + // Send pong frame with string data + ws.pong("pong data"); + + // Send pong frame with ArrayBuffer + const pongBuffer = new ArrayBuffer(4); + ws.pong(pongBuffer); + + // Send pong frame with ArrayBufferView + const pongView = new Uint8Array(pongBuffer); + ws.pong(pongView); + + // Terminate the connection immediately + ws.terminate(); } diff --git a/test/integration/bun-types/fixture/ws.ts b/test/integration/bun-types/fixture/ws.ts deleted file mode 100644 index fdc4072af2..0000000000 --- a/test/integration/bun-types/fixture/ws.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { WebSocket, WebSocketServer } from "ws"; - -const ws = new WebSocket("ws://www.host.com/path"); - -ws.send("asdf"); - -const wss = new WebSocketServer({ - port: 8080, - perMessageDeflate: false, -}); -wss; diff --git a/test/internal/ban-words.test.ts b/test/internal/ban-words.test.ts index 9c118175ec..54a547843a 100644 --- a/test/internal/ban-words.test.ts +++ b/test/internal/ban-words.test.ts @@ -5,20 +5,21 @@ import path from "path"; const words: Record = { " != undefined": { reason: "This is by definition Undefined Behavior." }, " == undefined": { reason: "This is by definition Undefined Behavior." }, - '@import("root").bun.': { reason: "Only import 'bun' once" }, + "undefined != ": { reason: "This is by definition Undefined Behavior." }, + "undefined == ": { reason: "This is by definition Undefined Behavior." }, + + '@import("bun").': { reason: "Only import 'bun' once" }, "std.debug.assert": { reason: "Use bun.assert instead", limit: 26 }, "std.debug.dumpStackTrace": { reason: "Use bun.handleErrorReturnTrace or bun.crash_handler.dumpStackTrace instead" }, "std.debug.print": { reason: "Don't let this be committed", limit: 0 }, "std.mem.indexOfAny(u8": { reason: "Use bun.strings.indexOfAny", limit: 3 }, - "undefined != ": { reason: "This is by definition Undefined Behavior." }, - "undefined == ": { reason: "This is by definition Undefined Behavior." }, - "bun.toFD(std.fs.cwd().fd)": { reason: "Use bun.FD.cwd()" }, "std.StringArrayHashMapUnmanaged(": { reason: "bun.StringArrayHashMapUnmanaged has a faster `eql`", limit: 12 }, "std.StringArrayHashMap(": { reason: "bun.StringArrayHashMap has a faster `eql`", limit: 1 }, "std.StringHashMapUnmanaged(": { reason: "bun.StringHashMapUnmanaged has a faster `eql`" }, "std.StringHashMap(": { reason: "bun.StringHashMap has a faster `eql`" }, "std.enums.tagName(": { reason: "Use bun.tagName instead", limit: 2 }, "std.unicode": { reason: "Use bun.strings instead", limit: 36 }, + "allocator.ptr ==": { reason: "The std.mem.Allocator context pointer can be undefined, which makes this comparison undefined behavior" }, "allocator.ptr !=": { reason: "The std.mem.Allocator context pointer can be undefined, which makes this comparison undefined behavior", limit: 1 }, "== allocator.ptr": { reason: "The std.mem.Allocator context pointer can be undefined, which makes this comparison undefined behavior" }, @@ -27,8 +28,15 @@ const words: Record "alloc.ptr !=": { reason: "The std.mem.Allocator context pointer can be undefined, which makes this comparison undefined behavior" }, "== alloc.ptr": { reason: "The std.mem.Allocator context pointer can be undefined, which makes this comparison undefined behavior" }, "!= alloc.ptr": { reason: "The std.mem.Allocator context pointer can be undefined, which makes this comparison undefined behavior" }, + [String.raw`: [a-zA-Z0-9_\.\*\?\[\]\(\)]+ = undefined,`]: { reason: "Do not default a struct field to undefined", limit: 242, regex: true }, - "usingnamespace": { reason: "Zig deprecates this, and will not support it in incremental compilation.", limit: 370 }, + "usingnamespace": { reason: "Zig deprecates this, and will not support it in incremental compilation.", limit: 50 }, + + "std.fs.Dir": { reason: "Prefer bun.sys + bun.FD instead of std.fs", limit: 180 }, + "std.fs.cwd": { reason: "Prefer bun.FD.cwd()", limit: 103 }, + "std.fs.File": { reason: "Prefer bun.sys + bun.FD instead of std.fs", limit: 71 }, + ".stdFile()": { reason: "Prefer bun.sys + bun.FD instead of std.fs.File. Zig hides 'errno' when Bun wants to match libuv", limit: 18 }, + ".stdDir()": { reason: "Prefer bun.sys + bun.FD instead of std.fs.File. Zig hides 'errno' when Bun wants to match libuv", limit: 48 }, }; const words_keys = [...Object.keys(words)]; diff --git a/test/js/bun/http/async-iterator-stream.test.ts b/test/js/bun/http/async-iterator-stream.test.ts index c247055f50..aab8f95fe0 100644 --- a/test/js/bun/http/async-iterator-stream.test.ts +++ b/test/js/bun/http/async-iterator-stream.test.ts @@ -1,5 +1,5 @@ import { spawn } from "bun"; -import { afterAll, describe, expect, mock, test } from "bun:test"; +import { describe, expect, mock, test } from "bun:test"; import { bunEnv, bunExe } from "harness"; describe("Streaming body via", () => { @@ -28,24 +28,18 @@ describe("Streaming body via", () => { }); test("async generator function throws an error but continues to send the headers", async () => { - let subprocess; - - afterAll(() => { - subprocess?.kill(); - }); - const onMessage = mock(async url => { const response = await fetch(url); expect(response.headers.get("X-Hey")).toBe("123"); subprocess?.kill(); }); - subprocess = spawn({ + await using subprocess = spawn({ cwd: import.meta.dirname, cmd: [bunExe(), "async-iterator-throws.fixture.js"], env: bunEnv, ipc: onMessage, - stdout: "ignore", + stdout: "inherit", stderr: "pipe", }); diff --git a/test/js/bun/test/fixtures/failing-test-done-test-fails.fixture.ts b/test/js/bun/test/fixtures/failing-test-done-test-fails.fixture.ts new file mode 100644 index 0000000000..d55b30663d --- /dev/null +++ b/test/js/bun/test/fixtures/failing-test-done-test-fails.fixture.ts @@ -0,0 +1,34 @@ +import { describe, test, expect } from "bun:test"; + +describe("test.failing with a done callback", () => { + test.failing("fails when done is called with no args", done => { + done(); + }); + + test.failing("fails when done is called with undefined", done => { + done(undefined); + }); + + test.failing("fails when all expectations are met and done is called without an error", done => { + expect(1).toBe(1); + done(); + }); + + describe("when test fn is async", () => { + // NOTE: tests that resolve/reject immediately hit a different code path + test.failing("fails when done() is called immediately", async done => { + done(); + }); + + test.failing("fails when done() is called on the next tick", async done => { + await new Promise(resolve => process.nextTick(resolve)); + done(); + }); + + test.failing("fails when all expectations are met and done is called", async done => { + await Bun.sleep(5); + expect(1).toBe(1); + done(); + }); + }); +}); diff --git a/test/js/bun/test/fixtures/failing-test-done-test-succeeds.fixture.ts b/test/js/bun/test/fixtures/failing-test-done-test-succeeds.fixture.ts new file mode 100644 index 0000000000..10b80e6db3 --- /dev/null +++ b/test/js/bun/test/fixtures/failing-test-done-test-succeeds.fixture.ts @@ -0,0 +1,42 @@ +import { describe, test } from "bun:test"; + +describe("test.failing with a done callback", () => { + test.failing("passes when an error is thrown", done => { + throw new Error("test error"); + }); + + test.failing("passes when done() is called with an error", done => { + done(new Error("test error")); + }); + + describe("when test fn is asynchronous but does not return a promise", () => { + test.failing("passes when done(err) is called on next tick", done => { + process.nextTick(() => { + done(new Error("test error")); + }); + }); + + test.failing("passes when done(err) is called on next event loop cycle", done => { + setTimeout(() => { + done(new Error("test error")); + }, 0); + }); + }); + + describe("when test fn is async", () => { + // NOTE: tests that resolve/reject immediately hit a different code path + test.failing("passes when a promise rejects", async _done => { + await Bun.sleep(5); + throw new Error("test error"); + }); + + test.failing("passes when a promise rejects immediately", async _done => { + throw new Error("test error"); + }); + + test.failing("passes when done() is called with an error", async done => { + await Bun.sleep(5); + done(new Error("test error")); + }); + }); +}); diff --git a/test/js/bun/test/fixtures/failing-test-timeout.fixture.ts b/test/js/bun/test/fixtures/failing-test-timeout.fixture.ts index a6934e2fd8..14b1001420 100644 --- a/test/js/bun/test/fixtures/failing-test-timeout.fixture.ts +++ b/test/js/bun/test/fixtures/failing-test-timeout.fixture.ts @@ -1,4 +1,20 @@ +import { isCI, isWindows } from "harness"; + jest.setTimeout(5); -test.failing("timeouts still count as failures", async () => { - await Bun.sleep(1000); + +describe("test.failing", () => { + test.failing("Timeouts still count as failures", async () => { + await Bun.sleep(1000); + }); + + // fixme: hangs on windows. Timer callback never fires + describe.skipIf(isWindows && isCI)("when using a done() callback", () => { + test.failing("fails when an async test never calls done()", async _done => { + // nada + }); + + test.failing("fails when a sync test never calls done()", _done => { + // nada + }); + }); }); diff --git a/test/js/bun/test/snapshot-tests/snapshots/snapshot.test.ts b/test/js/bun/test/snapshot-tests/snapshots/snapshot.test.ts index 02c484dc7b..6aea9871fb 100644 --- a/test/js/bun/test/snapshot-tests/snapshots/snapshot.test.ts +++ b/test/js/bun/test/snapshot-tests/snapshots/snapshot.test.ts @@ -1,7 +1,7 @@ import { $, spawnSync } from "bun"; import { readFileSync, writeFileSync } from "fs"; import { describe, expect, it, test } from "bun:test"; -import { bunEnv, bunExe, DirectoryTree, tempDirWithFiles } from "harness"; +import { bunEnv, bunExe, DirectoryTree, isDebug, tempDirWithFiles } from "harness"; function test1000000(arg1: any, arg218718132: any) {} @@ -185,7 +185,7 @@ class SnapshotTester { contents: string, opts: { shouldNotError?: boolean; shouldGrow?: boolean; skipSnapshot?: boolean } = {}, ) { - test(label, async () => await this.update(contents, opts)); + test(label, async () => await this.update(contents, opts), isDebug ? 100_000 : 5_000); } async update( contents: string, diff --git a/test/js/bun/test/test-failing.test.ts b/test/js/bun/test/test-failing.test.ts index 3090d1e7f8..5c06bb0d8f 100644 --- a/test/js/bun/test/test-failing.test.ts +++ b/test/js/bun/test/test-failing.test.ts @@ -39,7 +39,37 @@ describe("test.failing", () => { if (result.exitCode === 0) { fail("Expected exit code to be non-zero\n\n" + stderr); } - expect(stderr).toContain(" 1 fail\n"); + expect(stderr).toContain(" 0 pass\n"); expect(stderr).toMatch(/timed out after \d+ms/i); }); + + describe("when using a done() callback", () => { + it("when a test throws, rejects, or passes an error to done(), the test passes", async () => { + const result = await $.cwd( + fixtureDir, + ).nothrow()`${bunExe()} test ./failing-test-done-test-succeeds.fixture.ts`.quiet(); + const stderr = result.stderr.toString(); + try { + expect(stderr).toContain("0 fail"); + expect(result.exitCode).toBe(0); + } catch (e) { + console.error(stderr); + throw e; + } + }); + + it("when the test doesn't throw, or otherwise fail, the test does not pass", async () => { + const result = await $.cwd( + fixtureDir, + ).nothrow()`${bunExe()} test ./failing-test-done-test-fails.fixture.ts`.quiet(); + const stderr = result.stderr.toString(); + try { + expect(stderr).toContain("0 pass"); + expect(result.exitCode).not.toBe(0); + } catch (e) { + console.error(stderr); + throw e; + } + }); + }); }); diff --git a/test/js/node/http/node-http.test.ts b/test/js/node/http/node-http.test.ts index fd9752d2ed..9ddc88352b 100644 --- a/test/js/node/http/node-http.test.ts +++ b/test/js/node/http/node-http.test.ts @@ -2371,3 +2371,49 @@ it("Empty requests should not be Transfer-Encoding: chunked", async () => { server.close(); } }); + +it("should reject non-standard body writes when rejectNonStandardBodyWrites is true", async () => { + { + let body_not_allowed_on_write; + let body_not_allowed_on_end; + + for (const rejectNonStandardBodyWrites of [true, false, undefined]) { + await using server = http.createServer({ + rejectNonStandardBodyWrites, + }); + + server.on("request", (req, res) => { + body_not_allowed_on_write = false; + body_not_allowed_on_end = false; + res.writeHead(204); + + try { + res.write("bun"); + } catch (e: any) { + expect(e?.code).toBe("ERR_HTTP_BODY_NOT_ALLOWED"); + body_not_allowed_on_write = true; + } + try { + res.end("bun"); + } catch (e: any) { + expect(e?.code).toBe("ERR_HTTP_BODY_NOT_ALLOWED"); + body_not_allowed_on_end = true; + // if we throw here, we need to call end() to actually end the request + res.end(); + } + }); + + await once(server.listen(0), "listening"); + const url = `http://localhost:${server.address().port}`; + + { + await fetch(url, { + method: "GET", + }).then(res => res.text()); + + expect(body_not_allowed_on_write).toBe(rejectNonStandardBodyWrites || false); + expect(body_not_allowed_on_end).toBe(rejectNonStandardBodyWrites || false); + } + } + } +}); diff --git a/test/js/third_party/express/express.text.test.ts b/test/js/third_party/express/express.text.test.ts index 9b7fad6017..096ed48f21 100644 --- a/test/js/third_party/express/express.text.test.ts +++ b/test/js/third_party/express/express.text.test.ts @@ -509,7 +509,7 @@ describe("express.text()", function () { }); }); -function createApp(options) { +function createApp(options?) { var app = express(); app.use(express.text(options)); diff --git a/test/js/third_party/next-auth/fixture/.gitignore b/test/js/third_party/next-auth/fixture/.gitignore new file mode 100644 index 0000000000..5ef6a52078 --- /dev/null +++ b/test/js/third_party/next-auth/fixture/.gitignore @@ -0,0 +1,41 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/versions + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# env files (can opt-in for committing if needed) +.env* + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/test/js/third_party/next-auth/fixture/eslint.config.mjs b/test/js/third_party/next-auth/fixture/eslint.config.mjs new file mode 100644 index 0000000000..3353a9d4ce --- /dev/null +++ b/test/js/third_party/next-auth/fixture/eslint.config.mjs @@ -0,0 +1,14 @@ +import { FlatCompat } from "@eslint/eslintrc"; +import { dirname } from "path"; +import { fileURLToPath } from "url"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + +const compat = new FlatCompat({ + baseDirectory: __dirname, +}); + +const eslintConfig = [...compat.extends("next/core-web-vitals", "next/typescript")]; + +export default eslintConfig; diff --git a/test/js/third_party/next-auth/fixture/next.config.ts b/test/js/third_party/next-auth/fixture/next.config.ts new file mode 100644 index 0000000000..f70b91fc2c --- /dev/null +++ b/test/js/third_party/next-auth/fixture/next.config.ts @@ -0,0 +1,10 @@ +import type { NextConfig } from "next"; + +const nextConfig: NextConfig = { + /* config options here */ + eslint: { + ignoreDuringBuilds: true, + }, +}; + +export default nextConfig; diff --git a/test/js/third_party/next-auth/fixture/package.json b/test/js/third_party/next-auth/fixture/package.json new file mode 100644 index 0000000000..2246398a08 --- /dev/null +++ b/test/js/third_party/next-auth/fixture/package.json @@ -0,0 +1,28 @@ +{ + "name": "next", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint": "next lint" + }, + "dependencies": { + "next": "15.3.0", + "next-auth": "5.0.0-beta.25", + "react": "19.0.0", + "react-dom": "19.0.0" + }, + "devDependencies": { + "@eslint/eslintrc": "^3", + "@tailwindcss/postcss": "^4", + "@types/node": "^20", + "@types/react": "^19", + "@types/react-dom": "^19", + "eslint": "^9", + "eslint-config-next": "15.3.0", + "tailwindcss": "^4", + "typescript": "^5" + } +} diff --git a/test/js/third_party/next-auth/fixture/postcss.config.mjs b/test/js/third_party/next-auth/fixture/postcss.config.mjs new file mode 100644 index 0000000000..c7bcb4b1ee --- /dev/null +++ b/test/js/third_party/next-auth/fixture/postcss.config.mjs @@ -0,0 +1,5 @@ +const config = { + plugins: ["@tailwindcss/postcss"], +}; + +export default config; diff --git a/test/js/third_party/next-auth/fixture/public/file.svg b/test/js/third_party/next-auth/fixture/public/file.svg new file mode 100644 index 0000000000..004145cddf --- /dev/null +++ b/test/js/third_party/next-auth/fixture/public/file.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test/js/third_party/next-auth/fixture/public/globe.svg b/test/js/third_party/next-auth/fixture/public/globe.svg new file mode 100644 index 0000000000..567f17b0d7 --- /dev/null +++ b/test/js/third_party/next-auth/fixture/public/globe.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test/js/third_party/next-auth/fixture/public/next.svg b/test/js/third_party/next-auth/fixture/public/next.svg new file mode 100644 index 0000000000..5174b28c56 --- /dev/null +++ b/test/js/third_party/next-auth/fixture/public/next.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test/js/third_party/next-auth/fixture/public/vercel.svg b/test/js/third_party/next-auth/fixture/public/vercel.svg new file mode 100644 index 0000000000..7705396033 --- /dev/null +++ b/test/js/third_party/next-auth/fixture/public/vercel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test/js/third_party/next-auth/fixture/public/window.svg b/test/js/third_party/next-auth/fixture/public/window.svg new file mode 100644 index 0000000000..b2b2a44f6e --- /dev/null +++ b/test/js/third_party/next-auth/fixture/public/window.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test/js/third_party/next-auth/fixture/server.js b/test/js/third_party/next-auth/fixture/server.js new file mode 100644 index 0000000000..cf36fccb33 --- /dev/null +++ b/test/js/third_party/next-auth/fixture/server.js @@ -0,0 +1,63 @@ +import net from "net"; +import { parse } from "url"; +import http from "http"; +import next from "next"; +import { expect } from "bun:test"; +function test(port) { + const payload = Buffer.from(JSON.stringify({ message: "bun" })); + + function sendRequest(socket) { + const { promise, resolve } = Promise.withResolvers(); + let first = true; + socket.on("data", data => { + if (first) { + first = false; + const statusText = data.toString("utf8").split("HTTP/1.1")[1]?.split("\r\n")[0]?.trim(); + try { + expect(statusText).toBe("200 OK"); + resolve(); + } catch (err) { + console.error(err); + process.exit(1); + } + } + }); + socket.write( + `POST /api/echo HTTP/1.1\r\nHost: localhost:8080\r\nConnection: keep-alive\r\nContent-Length: ${payload.byteLength}\r\n\r\n`, + ); + socket.write(payload); + + return promise; + } + const socket = net.connect({ port: port, host: "127.0.0.1" }, async () => { + const timer = setTimeout(() => { + console.error("timeout"); + process.exit(1); + }, 30_000).unref(); + await sendRequest(socket); + await sendRequest(socket); + await sendRequest(socket); + console.log("request sent"); + clearTimeout(timer); + process.exit(0); + }); + socket.on("error", err => { + console.error(err); + process.exit(1); + }); +} + +const app = next({ dev: true, dir: import.meta.dirname, quiet: true }); +const handle = app.getRequestHandler(); + +app.prepare().then(() => { + const server = http + .createServer((req, res) => { + const parsedUrl = parse(req.url, true); + handle(req, res, parsedUrl); + }) + .listen(0, "127.0.0.1", () => { + console.log("server listening", server.address().port); + test(server.address().port); + }); +}); diff --git a/test/js/third_party/next-auth/fixture/src/app/api/auth/[...nextauth]/route.ts b/test/js/third_party/next-auth/fixture/src/app/api/auth/[...nextauth]/route.ts new file mode 100644 index 0000000000..020852e741 --- /dev/null +++ b/test/js/third_party/next-auth/fixture/src/app/api/auth/[...nextauth]/route.ts @@ -0,0 +1,3 @@ +import { handlers } from "@/auth"; + +export const { GET, POST } = handlers; \ No newline at end of file diff --git a/test/js/third_party/next-auth/fixture/src/app/api/echo/route.ts b/test/js/third_party/next-auth/fixture/src/app/api/echo/route.ts new file mode 100644 index 0000000000..68294ca156 --- /dev/null +++ b/test/js/third_party/next-auth/fixture/src/app/api/echo/route.ts @@ -0,0 +1,10 @@ +import { NextRequest } from 'next/server'; + +export async function POST(request: NextRequest) { + try { + const body = await request.json(); + return Response.json(body); + } catch (error) { + return Response.json({ error: 'Invalid JSON' }, { status: 400 }); + } +} \ No newline at end of file diff --git a/test/js/third_party/next-auth/fixture/src/app/echo/page.tsx b/test/js/third_party/next-auth/fixture/src/app/echo/page.tsx new file mode 100644 index 0000000000..d612027ab7 --- /dev/null +++ b/test/js/third_party/next-auth/fixture/src/app/echo/page.tsx @@ -0,0 +1,75 @@ +'use client'; + +import { useState } from 'react'; +import Link from 'next/link'; + +export default function EchoPage() { + const [input, setInput] = useState(''); + const [response, setResponse] = useState(null); + const [loading, setLoading] = useState(false); + + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + setLoading(true); + + try { + const res = await fetch('/api/echo', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ message: input }), + }); + + const data = await res.json(); + setResponse(data); + } catch (error) { + setResponse({ error: 'Failed to fetch' }); + } finally { + setLoading(false); + } + }; + + return ( +
+
+

Echo API Demo

+ +
+
+ setInput(e.target.value)} + placeholder="Enter a message" + className="p-3 border rounded-md" + /> + +
+
+ + {response && ( +
+

Response:

+
+              {JSON.stringify(response, null, 2)}
+            
+
+ )} + + + ← Back to home + +
+
+ ); +} diff --git a/test/js/third_party/next-auth/fixture/src/app/favicon.ico b/test/js/third_party/next-auth/fixture/src/app/favicon.ico new file mode 100644 index 0000000000..718d6fea48 Binary files /dev/null and b/test/js/third_party/next-auth/fixture/src/app/favicon.ico differ diff --git a/test/js/third_party/next-auth/fixture/src/app/globals.css b/test/js/third_party/next-auth/fixture/src/app/globals.css new file mode 100644 index 0000000000..a2dc41ecee --- /dev/null +++ b/test/js/third_party/next-auth/fixture/src/app/globals.css @@ -0,0 +1,26 @@ +@import "tailwindcss"; + +:root { + --background: #ffffff; + --foreground: #171717; +} + +@theme inline { + --color-background: var(--background); + --color-foreground: var(--foreground); + --font-sans: var(--font-geist-sans); + --font-mono: var(--font-geist-mono); +} + +@media (prefers-color-scheme: dark) { + :root { + --background: #0a0a0a; + --foreground: #ededed; + } +} + +body { + background: var(--background); + color: var(--foreground); + font-family: Arial, Helvetica, sans-serif; +} diff --git a/test/js/third_party/next-auth/fixture/src/app/layout.tsx b/test/js/third_party/next-auth/fixture/src/app/layout.tsx new file mode 100644 index 0000000000..f7fa87eb87 --- /dev/null +++ b/test/js/third_party/next-auth/fixture/src/app/layout.tsx @@ -0,0 +1,34 @@ +import type { Metadata } from "next"; +import { Geist, Geist_Mono } from "next/font/google"; +import "./globals.css"; + +const geistSans = Geist({ + variable: "--font-geist-sans", + subsets: ["latin"], +}); + +const geistMono = Geist_Mono({ + variable: "--font-geist-mono", + subsets: ["latin"], +}); + +export const metadata: Metadata = { + title: "Create Next App", + description: "Generated by create next app", +}; + +export default function RootLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + return ( + + + {children} + + + ); +} diff --git a/test/js/third_party/next-auth/fixture/src/app/page.tsx b/test/js/third_party/next-auth/fixture/src/app/page.tsx new file mode 100644 index 0000000000..d5e32466c2 --- /dev/null +++ b/test/js/third_party/next-auth/fixture/src/app/page.tsx @@ -0,0 +1,9 @@ +import { auth } from "@/auth"; + +export default async function Home() { + const session = await auth(); + + return ( +
Hello
+ ); +} diff --git a/test/js/third_party/next-auth/fixture/src/app/protected/page.tsx b/test/js/third_party/next-auth/fixture/src/app/protected/page.tsx new file mode 100644 index 0000000000..3288662201 --- /dev/null +++ b/test/js/third_party/next-auth/fixture/src/app/protected/page.tsx @@ -0,0 +1,20 @@ +import { auth, signOut } from "@/auth"; + +export default async function ProtectedPage() { + const session = await auth(); + + return ( +
+
{ + "use server"; + await signOut({ redirectTo: "/" }); + }}> + +
+
+ ); +} \ No newline at end of file diff --git a/test/js/third_party/next-auth/fixture/src/auth.ts b/test/js/third_party/next-auth/fixture/src/auth.ts new file mode 100644 index 0000000000..67a60bc06f --- /dev/null +++ b/test/js/third_party/next-auth/fixture/src/auth.ts @@ -0,0 +1,62 @@ +import NextAuth from "next-auth"; +import type { NextAuthConfig } from "next-auth"; +import CredentialsProvider from "next-auth/providers/credentials"; +import GoogleProvider from "next-auth/providers/google"; + +export const authConfig: NextAuthConfig = { + pages: { + signIn: "/login", + }, + callbacks: { + authorized({ auth, request: { nextUrl } }) { + const isLoggedIn = !!auth?.user; + const isOnProtectedPage = nextUrl.pathname.startsWith("/protected"); + if (isOnProtectedPage) { + if (isLoggedIn) return true; + return false; // Redirect to login page + } else if (isLoggedIn) { + return true; + } + return true; + }, + + async jwt({ token, user }) { + if (user) { + token.user = user; + } + return token; + }, + async session({ session, token }) { + //@ts-ignore + session.user = token.user; + return session; + }, + }, + providers: [ + CredentialsProvider({ + name: "Credentials", + credentials: { + email: { label: "Email", type: "email" }, + password: { label: "Password", type: "password" } + }, + async authorize(credentials) { + // This is a demo authentication - in a real app you would validate against a database + if (credentials?.email === "user@example.com" && credentials?.password === "password") { + return { + id: "1", + email: "user@example.com", + name: "Demo User", + }; + } + + return null; + } + }) + ], + + session: { + strategy: "jwt", + }, +}; + +export const { auth, signIn, signOut, handlers } = NextAuth(authConfig); \ No newline at end of file diff --git a/test/js/third_party/next-auth/fixture/src/client/session.tsx b/test/js/third_party/next-auth/fixture/src/client/session.tsx new file mode 100644 index 0000000000..a7a75457f0 --- /dev/null +++ b/test/js/third_party/next-auth/fixture/src/client/session.tsx @@ -0,0 +1,16 @@ +"use client" +import { useSession } from "next-auth/react" +import { useEffect } from "react" + +export function SessionState() { + + const { data: session, status } = useSession() + + useEffect( ()=> { + + + }); + + return
status: {status}
+ +} \ No newline at end of file diff --git a/test/js/third_party/next-auth/fixture/src/client/test.tsx b/test/js/third_party/next-auth/fixture/src/client/test.tsx new file mode 100644 index 0000000000..a8f2689ee4 --- /dev/null +++ b/test/js/third_party/next-auth/fixture/src/client/test.tsx @@ -0,0 +1,10 @@ +"use client" +import { SessionProvider } from "next-auth/react" +import { SessionState } from './session'; + +export function ClientComponent() { + + + return + +} \ No newline at end of file diff --git a/test/js/third_party/next-auth/fixture/src/middleware.ts b/test/js/third_party/next-auth/fixture/src/middleware.ts new file mode 100644 index 0000000000..5b79ccb888 --- /dev/null +++ b/test/js/third_party/next-auth/fixture/src/middleware.ts @@ -0,0 +1,3 @@ +import { auth } from "./auth"; + +export default auth; \ No newline at end of file diff --git a/test/js/third_party/next-auth/fixture/tsconfig.json b/test/js/third_party/next-auth/fixture/tsconfig.json new file mode 100644 index 0000000000..c1334095f8 --- /dev/null +++ b/test/js/third_party/next-auth/fixture/tsconfig.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "target": "ES2017", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "paths": { + "@/*": ["./src/*"] + } + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], + "exclude": ["node_modules"] +} diff --git a/test/js/third_party/next-auth/next-auth.test.ts b/test/js/third_party/next-auth/next-auth.test.ts new file mode 100644 index 0000000000..dfa9a3a4d5 --- /dev/null +++ b/test/js/third_party/next-auth/next-auth.test.ts @@ -0,0 +1,19 @@ +import { describe, it, expect } from "bun:test"; +import { bunRun, runBunInstall, bunEnv } from "harness"; +import { join } from "path"; +describe("next-auth", () => { + it("should be able to call server action multiple times using auth middleware #18977", async () => { + await runBunInstall(bunEnv, join(import.meta.dir, "fixture"), { + allowWarnings: true, + allowErrors: true, + savesLockfile: false, + }); + const result = bunRun(join(import.meta.dir, "fixture", "server.js"), { + AUTH_SECRET: "I7Jiq12TSMlPlAzyVAT+HxYX7OQb/TTqIbfTTpr1rg8=", + }); + expect(result.stderr).toBe(""); + expect(result.stdout).toBeDefined(); + const lines = result.stdout?.split("\n") ?? []; + expect(lines[lines.length - 1]).toMatch(/request sent/); + }, 30_000); +});