diff options
author | 2021-10-23 05:00:31 -0700 | |
---|---|---|
committer | 2021-10-23 05:00:31 -0700 | |
commit | 384ad96637171fdb8b32867d9025ece1e85c3a0e (patch) | |
tree | 2bdb2a2d35f338d54c4b72a48ce7ad8777f3349d | |
parent | 0361b0df70a38e9a30c8bbf5e282cf18b583c387 (diff) | |
download | bun-384ad96637171fdb8b32867d9025ece1e85c3a0e.tar.gz bun-384ad96637171fdb8b32867d9025ece1e85c3a0e.tar.zst bun-384ad96637171fdb8b32867d9025ece1e85c3a0e.zip |
Support string-only defines
-rw-r--r-- | src/defines.zig | 118 |
1 files changed, 65 insertions, 53 deletions
diff --git a/src/defines.zig b/src/defines.zig index a17b96fe9..141dbc309 100644 --- a/src/defines.zig +++ b/src/defines.zig @@ -27,6 +27,7 @@ const Globals = struct { const defines_path = fs.Path.initWithNamespace("defines.json", "internal"); pub const RawDefines = std.StringArrayHashMap(string); pub const UserDefines = std.StringHashMap(DefineData); +pub const UserDefinesArray = std.StringArrayHashMap(DefineData); const Rewrites = struct { pub const global = "global"; @@ -74,9 +75,9 @@ pub const DefineData = struct { while (splitter.next()) |part| { if (!js_lexer.isIdentifier(part)) { if (strings.eql(part, entry.key_ptr)) { - try log.addErrorFmt(null, logger.Loc{}, allocator, "The define key \"{s}\" must be a valid identifier", .{entry.key_ptr}); + try log.addErrorFmt(null, logger.Loc{}, allocator, "The define key \"{s}\" must be a valid identifier", .{entry.key_ptr.*}); } else { - try log.addErrorFmt(null, logger.Loc{}, allocator, "The define key \"{s}\" contains invalid identifier \"{s}\"", .{ part, entry.key_ptr }); + try log.addErrorFmt(null, logger.Loc{}, allocator, "The define key \"{s}\" contains invalid identifier \"{s}\"", .{ part, entry.value_ptr.* }); } break; } @@ -201,7 +202,61 @@ pub const Define = struct { dots: std.StringHashMap([]DotDefine), allocator: *std.mem.Allocator, - pub fn init(allocator: *std.mem.Allocator, _user_defines: ?UserDefines) !*@This() { + pub fn insertFromIterator(define: *Define, allocator: *std.mem.Allocator, comptime Iterator: type, iter: Iterator) !void { + while (iter.next()) |user_define| { + const user_define_key = user_define.key_ptr.*; + // If it has a dot, then it's a DotDefine. + // e.g. process.env.NODE_ENV + if (strings.lastIndexOfChar(user_define_key, '.')) |last_dot| { + const tail = user_define_key[last_dot + 1 .. user_define_key.len]; + const remainder = user_define_key[0..last_dot]; + const count = std.mem.count(u8, remainder, ".") + 1; + var parts = try allocator.alloc(string, count + 1); + var splitter = std.mem.split(u8, remainder, "."); + var i: usize = 0; + while (splitter.next()) |split| : (i += 1) { + parts[i] = split; + } + parts[i] = tail; + var didFind = false; + var initial_values: []DotDefine = &([_]DotDefine{}); + + // "NODE_ENV" + if (define.dots.getEntry(tail)) |entry| { + for (entry.value_ptr.*) |*part| { + // ["process", "env"] === ["process", "env"] (if that actually worked) + if (arePartsEqual(part.parts, parts)) { + part.data = part.data.merge(user_define.value_ptr.*); + didFind = true; + break; + } + } + + initial_values = entry.value_ptr.*; + } + + if (!didFind) { + var list = try std.ArrayList(DotDefine).initCapacity(allocator, initial_values.len + 1); + if (initial_values.len > 0) { + list.appendSliceAssumeCapacity(initial_values); + } + + list.appendAssumeCapacity(DotDefine{ + .data = user_define.value_ptr.*, + // TODO: do we need to allocate this? + .parts = parts, + }); + try define.dots.put(tail, list.toOwnedSlice()); + } + } else { + + // e.g. IS_BROWSER + try define.identifiers.put(user_define_key, user_define.value_ptr.*); + } + } + } + + pub fn init(allocator: *std.mem.Allocator, _user_defines: ?UserDefines, string_defines: ?UserDefinesArray) !*@This() { var define = try allocator.create(Define); define.allocator = allocator; define.identifiers = std.StringHashMap(IdentifierDefine).init(allocator); @@ -276,57 +331,14 @@ pub const Define = struct { // At this stage, user data has already been validated. if (_user_defines) |user_defines| { var iter = user_defines.iterator(); - while (iter.next()) |user_define| { - const user_define_key = user_define.key_ptr.*; - // If it has a dot, then it's a DotDefine. - // e.g. process.env.NODE_ENV - if (strings.lastIndexOfChar(user_define_key, '.')) |last_dot| { - const tail = user_define_key[last_dot + 1 .. user_define_key.len]; - const remainder = user_define_key[0..last_dot]; - const count = std.mem.count(u8, remainder, ".") + 1; - var parts = try allocator.alloc(string, count + 1); - var splitter = std.mem.split(u8, remainder, "."); - var i: usize = 0; - while (splitter.next()) |split| : (i += 1) { - parts[i] = split; - } - parts[i] = tail; - var didFind = false; - var initial_values: []DotDefine = &([_]DotDefine{}); - - // "NODE_ENV" - if (define.dots.getEntry(tail)) |entry| { - for (entry.value_ptr.*) |*part| { - // ["process", "env"] === ["process", "env"] (if that actually worked) - if (arePartsEqual(part.parts, parts)) { - part.data = part.data.merge(user_define.value_ptr.*); - didFind = true; - break; - } - } - - initial_values = entry.value_ptr.*; - } - - if (!didFind) { - var list = try std.ArrayList(DotDefine).initCapacity(allocator, initial_values.len + 1); - if (initial_values.len > 0) { - list.appendSliceAssumeCapacity(initial_values); - } - - list.appendAssumeCapacity(DotDefine{ - .data = user_define.value_ptr.*, - // TODO: do we need to allocate this? - .parts = parts, - }); - try define.dots.put(tail, list.toOwnedSlice()); - } - } else { + try define.insertFromIterator(allocator, @TypeOf(&iter), &iter); + } - // e.g. IS_BROWSER - try define.identifiers.put(user_define_key, user_define.value_ptr.*); - } - } + // Step 4. Load environment data into hash tables. + // These are only strings. We do not parse them as JSON. + if (string_defines) |string_defines_| { + var iter = string_defines_.iterator(); + try define.insertFromIterator(allocator, @TypeOf(&iter), &iter); } { |