diff options
author | 2023-04-14 01:49:29 -0700 | |
---|---|---|
committer | 2023-04-14 01:49:29 -0700 | |
commit | 889462a891b857c06e8a2056d22441b53c0614ba (patch) | |
tree | f22e793c7f7629d94c8865bd8ed9911fc91c7f40 /src/string_immutable.zig | |
parent | 3a2fd65f20d3b4e99c89f789acec5e5e40615008 (diff) | |
download | bun-889462a891b857c06e8a2056d22441b53c0614ba.tar.gz bun-889462a891b857c06e8a2056d22441b53c0614ba.tar.zst bun-889462a891b857c06e8a2056d22441b53c0614ba.zip |
Support `@jsx`, `@jsxRuntime`, `@jsxImportSource`, and `@jsxFragment` pragmas (#2655)
* Support parsing @pragma comments
* Support `@jsx`, `@jsxRuntime`, `@jsxImportSource`, `@jsxFragment`
* Fix bug where NODE_ENV would be development in certain places and production in others
---------
Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
Diffstat (limited to 'src/string_immutable.zig')
-rw-r--r-- | src/string_immutable.zig | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/src/string_immutable.zig b/src/string_immutable.zig index a611b302e..44d64dc49 100644 --- a/src/string_immutable.zig +++ b/src/string_immutable.zig @@ -4318,3 +4318,105 @@ pub fn leftHasAnyInRight(to_check: []const string, against: []const string) bool } return false; } + +pub fn hasPrefixWithWordBoundary(input: []const u8, comptime prefix: []const u8) bool { + if (hasPrefixComptime(input, prefix)) { + if (input.len == prefix.len) return true; + + const next = input[prefix.len..]; + var bytes: [4]u8 = .{ + next[0], + if (next.len > 1) next[1] else 0, + if (next.len > 2) next[2] else 0, + if (next.len > 3) next[3] else 0, + }; + + if (!bun.js_lexer.isIdentifierContinue(decodeWTF8RuneT(&bytes, wtf8ByteSequenceLength(next[0]), i32, -1))) { + return true; + } + } + + return false; +} + +pub fn concatWithLength( + allocator: std.mem.Allocator, + args: []const string, + length: usize, +) !string { + var out = try allocator.alloc(u8, length); + @memcpy(out.ptr, args[0].ptr, args[0].len); + return out; +} + +pub fn concat( + allocator: std.mem.Allocator, + args: []const string, +) !string { + var length: usize = 0; + for (args) |arg| { + length += arg.len; + } + return concatWithLength(allocator, args, length); +} + +pub fn concatIfNeeded( + allocator: std.mem.Allocator, + dest: *[]const u8, + args: []const string, + interned_strings_to_check: []const string, +) !void { + const total_length: usize = brk: { + var length: usize = 0; + for (args) |arg| { + length += arg.len; + } + break :brk length; + }; + + if (total_length == 0) { + dest.* = ""; + return; + } + + if (total_length < 1024) { + var stack = std.heap.stackFallback(1024, allocator); + const stack_copy = concatWithLength(stack.get(), args, total_length) catch unreachable; + for (interned_strings_to_check) |interned| { + if (eqlLong(stack_copy, interned, true)) { + dest.* = interned; + return; + } + } + } + + const is_needed = brk: { + var out = dest.*; + var remain = out; + + for (args) |arg| { + if (args.len > remain.len) { + break :brk true; + } + + if (eqlLong(remain[0..args.len], arg, true)) { + remain = remain[args.len..]; + } else { + break :brk true; + } + } + + break :brk false; + }; + + if (!is_needed) return; + + var buf = try allocator.alloc(u8, total_length); + dest.* = buf; + var remain = buf[0..]; + for (args) |arg| { + @memcpy(remain.ptr, arg.ptr, arg.len); + remain = remain[arg.len..]; + } + std.debug.assert(remain.len == 0); +} |