diff options
author | 2021-05-13 00:46:22 -0700 | |
---|---|---|
committer | 2021-05-13 00:46:22 -0700 | |
commit | bed0227a8f2d8b674a98803659922d08ac665bfe (patch) | |
tree | 42e6cd96757a0f9c01d103de1f42bdc7a9e958b8 /src | |
parent | 9fd6f635cd5092ce82359b504f1e053d7f0387d6 (diff) | |
download | bun-bed0227a8f2d8b674a98803659922d08ac665bfe.tar.gz bun-bed0227a8f2d8b674a98803659922d08ac665bfe.tar.zst bun-bed0227a8f2d8b674a98803659922d08ac665bfe.zip |
hm
Former-commit-id: 28fce4aac174c7cf7a492ca4c5442d57a4f395a3
Diffstat (limited to 'src')
-rw-r--r-- | src/bundler.zig | 35 | ||||
-rw-r--r-- | src/cache.zig | 27 | ||||
-rw-r--r-- | src/fs.zig | 3 | ||||
-rw-r--r-- | src/js_lexer.zig | 21 | ||||
-rw-r--r-- | src/json_parser.zig | 47 | ||||
-rw-r--r-- | src/options.zig | 6 | ||||
-rw-r--r-- | src/resolver/resolver.zig | 36 | ||||
-rw-r--r-- | src/sync.zig | 2 | ||||
-rw-r--r-- | src/thread_safe_hash_map.zig | 12 |
9 files changed, 143 insertions, 46 deletions
diff --git a/src/bundler.zig b/src/bundler.zig index 04a3725f9..8df23e265 100644 --- a/src/bundler.zig +++ b/src/bundler.zig @@ -22,7 +22,7 @@ const ThreadSafeHashMap = @import("./thread_safe_hash_map.zig"); // pub const // const BundleMap = - +const ResolveResults = ThreadSafeHashMap.ThreadSafeStringHashMap(Resolver.Resolver.Result); pub const Bundler = struct { options: options.BundleOptions, log: *logger.Log, @@ -30,7 +30,9 @@ pub const Bundler = struct { result: options.TransformResult = undefined, resolver: Resolver.Resolver, fs: *Fs.FileSystem, - thread_pool: *ThreadPool, + // thread_pool: *ThreadPool, + + resolve_results: *ResolveResults, // to_bundle: @@ -43,20 +45,24 @@ pub const Bundler = struct { ) !Bundler { var fs = try Fs.FileSystem.init1(allocator, opts.absolute_working_dir, opts.watch orelse false); const bundle_options = try options.BundleOptions.fromApi(allocator, fs, log, opts); - var pool = try allocator.create(ThreadPool); - try pool.init(ThreadPool.InitConfig{ - .allocator = allocator, - }); + // var pool = try allocator.create(ThreadPool); + // try pool.init(ThreadPool.InitConfig{ + // .allocator = allocator, + // }); return Bundler{ .options = bundle_options, .fs = fs, .allocator = allocator, .resolver = Resolver.Resolver.init1(allocator, log, fs, bundle_options), .log = log, - .thread_pool = pool, + // .thread_pool = pool, + .result = options.TransformResult{}, + .resolve_results = try ResolveResults.init(allocator), }; } + pub fn scan(bundler: *Bundler) !void {} + pub fn bundle( allocator: *std.mem.Allocator, log: *logger.Log, @@ -65,14 +71,27 @@ pub const Bundler = struct { var bundler = try Bundler.init(allocator, log, opts); var entry_points = try allocator.alloc(Resolver.Resolver.Result, bundler.options.entry_points.len); + var entry_point_i: usize = 0; for (bundler.options.entry_points) |entry| { - entry_points[entry_point_i] = bundler.resolver.resolve(bundler.fs.top_level_dir, entry, .entry_point) catch { + const result = bundler.resolver.resolve(bundler.fs.top_level_dir, entry, .entry_point) catch { continue; } orelse continue; + const key = result.path_pair.primary.text; + if (bundler.resolve_results.contains(key)) { + continue; + } + try bundler.resolve_results.put(key, result); + entry_points[entry_point_i] = result; + Output.print("Resolved {s} => {s}", .{ entry, result.path_pair.primary.text }); entry_point_i += 1; } + switch (bundler.options.resolve_mode) { + .lazy, .dev, .bundle => {}, + else => Global.panic("Unsupported resolve mode: {s}", .{@tagName(bundler.options.resolve_mode)}), + } + return bundler.result; } }; diff --git a/src/cache.zig b/src/cache.zig index 77f38359b..52beb46bb 100644 --- a/src/cache.zig +++ b/src/cache.zig @@ -83,13 +83,22 @@ pub const Cache = struct { } }; - const size = if (mod_key != null) mod_key.?.size else null; - const file = rfs.readFile(path, size) catch |err| { - if (isDebug) { - Output.printError("{s}: readFile error -- {s}", .{ path, @errorName(err) }); - } - return err; - }; + var file: fs.File = undefined; + if (mod_key) |modk| { + file = rfs.readFile(path, modk.size) catch |err| { + if (isDebug) { + Output.printError("{s}: readFile error -- {s}", .{ path, @errorName(err) }); + } + return err; + }; + } else { + file = rfs.readFile(path, null) catch |err| { + if (isDebug) { + Output.printError("{s}: readFile error -- {s}", .{ path, @errorName(err) }); + } + return err; + }; + } const entry = Entry{ .contents = file.contents, @@ -195,11 +204,11 @@ pub const Cache = struct { return entry.expr; } pub fn parseJSON(cache: *@This(), log: *logger.Log, source: logger.Source, allocator: *std.mem.Allocator) anyerror!?js_ast.Expr { - return @call(std.builtin.CallOptions{ .modifier = .always_tail }, parse, .{ cache, log, source, allocator, false, json_parser.ParseJSON }); + return try parse(cache, log, source, allocator, false, json_parser.ParseJSON); } pub fn parseTSConfig(cache: *@This(), log: *logger.Log, source: logger.Source, allocator: *std.mem.Allocator) anyerror!?js_ast.Expr { - return @call(std.builtin.CallOptions{ .modifier = .always_tail }, parse, .{ cache, log, source, allocator, true, json_parser.ParseTSConfig }); + return try parse(cache, log, source, allocator, true, json_parser.ParseTSConfig); } }; }; diff --git a/src/fs.zig b/src/fs.zig index e5ab8e832..2577d4552 100644 --- a/src/fs.zig +++ b/src/fs.zig @@ -443,10 +443,11 @@ pub const FileSystem = struct { defer file.close(); // Skip the extra file.stat() call when possible - const size = _size orelse (file.getEndPos() catch |err| { + var size = _size orelse (file.getEndPos() catch |err| { fs.readFileError(path, err); return err; }); + const file_contents: []u8 = file.readToEndAllocOptions(fs.allocator, size, size, @alignOf(u8), null) catch |err| { fs.readFileError(path, err); return err; diff --git a/src/js_lexer.zig b/src/js_lexer.zig index e90886ead..512a5e5cd 100644 --- a/src/js_lexer.zig +++ b/src/js_lexer.zig @@ -1216,12 +1216,29 @@ pub const Lexer = struct { // TODO: use wtf-8 encoding. pub fn utf16ToStringWithValidation(lexer: *LexerType, js: JavascriptString) !string { - return std.unicode.utf16leToUtf8Alloc(lexer.allocator, js); + // return std.unicode.utf16leToUtf8Alloc(lexer.allocator, js); + return utf16ToString(lexer, js); } // TODO: use wtf-8 encoding. pub fn utf16ToString(lexer: *LexerType, js: JavascriptString) string { - return std.unicode.utf16leToUtf8Alloc(lexer.allocator, js) catch unreachable; + var temp = std.mem.zeroes([4]u8); + var list = std.ArrayList(u8).initCapacity(lexer.allocator, js.len) catch unreachable; + var i: usize = 0; + while (i < js.len) : (i += 1) { + var r1 = @intCast(i32, js[i]); + if (r1 >= 0xD800 and r1 <= 0xDBFF and i + 1 < js.len) { + const r2 = @intCast(i32, js[i] + 1); + if (r2 >= 0xDC00 and r2 <= 0xDFFF) { + r1 = (r1 - 0xD800) << 10 | (r2 - 0xDC00) + 0x10000; + i += 1; + } + } + const width = strings.encodeWTF8Rune(&temp, r1); + list.appendSlice(temp[0..width]) catch unreachable; + } + return list.toOwnedSlice(); + // return std.unicode.utf16leToUtf8Alloc(lexer.allocator, js) catch unreachable; } pub fn nextInsideJSXElement(lexer: *LexerType) !void { diff --git a/src/json_parser.zig b/src/json_parser.zig index 4fb1f89f7..120bcb4d7 100644 --- a/src/json_parser.zig +++ b/src/json_parser.zig @@ -93,11 +93,20 @@ fn JSONLikeParser(opts: js_lexer.JSONOptions) type { return p.e(E.Null{}, loc); }, .t_string_literal => { - const value = p.lexer.string_literal; + var str: E.String = undefined; + if (p.lexer.string_literal_is_ascii) { + str = E.String{ + .utf8 = p.lexer.string_literal_slice, + }; + } else { + const value = p.lexer.stringLiteralUTF16(); + str = E.String{ + .value = value, + }; + } + try p.lexer.next(); - return p.e(E.String{ - .value = value, - }, loc); + return p.e(str, loc); }, .t_numeric_literal => { const value = p.lexer.number; @@ -143,7 +152,7 @@ fn JSONLikeParser(opts: js_lexer.JSONOptions) type { try p.lexer.next(); var is_single_line = !p.lexer.has_newline_before; var properties = std.ArrayList(G.Property).init(p.allocator); - var duplicates = std.StringHashMap(u1).init(p.allocator); + var duplicates = std.BufSet.init(p.allocator); while (p.lexer.token != .t_close_brace) { if (properties.items.len > 0) { @@ -158,18 +167,30 @@ fn JSONLikeParser(opts: js_lexer.JSONOptions) type { } } - var key_string = p.lexer.string_literal; + var str: E.String = undefined; + if (p.lexer.string_literal_is_ascii) { + str = E.String{ + .utf8 = p.lexer.string_literal_slice, + }; + } else { + const value = p.lexer.stringLiteralUTF16(); + str = E.String{ + .value = value, + }; + } + const is_duplicate = duplicates.exists(p.lexer.string_literal_slice); + if (!is_duplicate) { + duplicates.put(p.lexer.string_literal_slice) catch unreachable; + } var key_range = p.lexer.range(); - var key = p.e(E.String{ .value = key_string }, key_range.loc); - try p.lexer.expect(.t_string_literal); - var key_text = p.lexer.utf16ToString(key_string); // Warn about duplicate keys - - const entry = duplicates.getOrPut(key_text) catch unreachable; - if (entry.found_existing) { - p.log.addRangeWarningFmt(p.source, key_range, p.allocator, "Duplicate key \"{s}\" in object literal", .{key_text}) catch unreachable; + if (is_duplicate) { + p.log.addRangeWarningFmt(p.source, key_range, p.allocator, "Duplicate key \"{s}\" in object literal", .{p.lexer.string_literal_slice}) catch unreachable; } + var key = p.e(str, key_range.loc); + try p.lexer.expect(.t_string_literal); + try p.lexer.expect(.t_colon); var value = try p.parseExpr(); properties.append(G.Property{ .key = key, .value = value }) catch unreachable; diff --git a/src/options.zig b/src/options.zig index 9d5f91699..7daa14804 100644 --- a/src/options.zig +++ b/src/options.zig @@ -421,9 +421,9 @@ pub const OutputFile = struct { }; pub const TransformResult = struct { - errors: []logger.Msg, - warnings: []logger.Msg, - output_files: []OutputFile, + errors: []logger.Msg = &([_]logger.Msg{}), + warnings: []logger.Msg = &([_]logger.Msg{}), + output_files: []OutputFile = &([_]OutputFile{}), pub fn init( output_files: []OutputFile, log: *logger.Log, diff --git a/src/resolver/resolver.zig b/src/resolver/resolver.zig index 8ac9f083d..6d2425654 100644 --- a/src/resolver/resolver.zig +++ b/src/resolver/resolver.zig @@ -39,10 +39,10 @@ pub const DirInfo = struct { }; pub const TemporaryBuffer = struct { - pub var ExtensionPathBuf = std.mem.zeroes([512]u8); - pub var TSConfigMatchStarBuf = std.mem.zeroes([512]u8); - pub var TSConfigMatchPathBuf = std.mem.zeroes([512]u8); - pub var TSConfigMatchFullBuf = std.mem.zeroes([512]u8); + pub threadlocal var ExtensionPathBuf = std.mem.zeroes([512]u8); + pub threadlocal var TSConfigMatchStarBuf = std.mem.zeroes([512]u8); + pub threadlocal var TSConfigMatchPathBuf = std.mem.zeroes([512]u8); + pub threadlocal var TSConfigMatchFullBuf = std.mem.zeroes([512]u8); }; pub const Resolver = struct { @@ -194,6 +194,9 @@ pub const Resolver = struct { is_external: bool = false, + // This is true when the package was loaded from within the node_modules directory. + is_from_node_modules: bool = false, + diff_case: ?Fs.FileSystem.Entry.Lookup.DifferentCase = null, // If present, any ES6 imports to this file can be considered to have no side @@ -239,7 +242,18 @@ pub const Resolver = struct { }; pub fn isExternalPattern(r: *Resolver, import_path: string) bool { - Global.notimpl(); + for (r.opts.external.patterns) |pattern| { + if (import_path.len >= pattern.prefix.len + pattern.suffix.len and (strings.startsWith( + import_path, + pattern.prefix, + ) and strings.endsWith( + import_path, + pattern.suffix, + ))) { + return true; + } + } + return false; } pub fn flushDebugLogs(r: *Resolver, flush_mode: DebugLogs.FlushMode) !void { @@ -487,7 +501,11 @@ pub const Resolver = struct { if (pair.secondary != null) { pair.secondary.?.is_disabled = true; } - return Result{ .path_pair = pair, .diff_case = node_module.diff_case }; + return Result{ + .path_pair = pair, + .diff_case = node_module.diff_case, + .is_from_node_modules = true, + }; } } else { var primary = Path.init(import_path); @@ -544,6 +562,11 @@ pub const Resolver = struct { } pub fn loadNodeModules(r: *Resolver, import_path: string, kind: ast.ImportKind, _dir_info: *DirInfo) ?MatchResult { + var res = _loadNodeModules(r, import_path, kind, _dir_info) orelse return null; + res.is_node_module = true; + return res; + } + pub fn _loadNodeModules(r: *Resolver, import_path: string, kind: ast.ImportKind, _dir_info: *DirInfo) ?MatchResult { var dir_info = _dir_info; if (r.debug_logs) |*debug| { debug.addNoteFmt("Searching for {s} in \"node_modules\" directories starting from \"{s}\"", .{ import_path, dir_info.abs_path }) catch {}; @@ -706,6 +729,7 @@ pub const Resolver = struct { pub const MatchResult = struct { path_pair: PathPair, + is_node_module: bool = false, diff_case: ?Fs.FileSystem.Entry.Lookup.DifferentCase = null, }; diff --git a/src/sync.zig b/src/sync.zig index 80e20cfa1..c43c227db 100644 --- a/src/sync.zig +++ b/src/sync.zig @@ -608,7 +608,7 @@ pub const RwLock = if (std.builtin.os.tag != .windows and std.builtin.link_libc) }, .netbsd => extern struct { ptr_magic: c_uint = 0x99990009, - ptr_interlock: switch (std.builtin.arch) { + ptr_interlock: switch (std.Target.current.cpu.arch) { .aarch64, .sparc, .x86_64, .i386 => u8, .arm, .powerpc => c_int, else => unreachable, diff --git a/src/thread_safe_hash_map.zig b/src/thread_safe_hash_map.zig index 321cb757f..40aeff7d6 100644 --- a/src/thread_safe_hash_map.zig +++ b/src/thread_safe_hash_map.zig @@ -9,9 +9,9 @@ pub fn ThreadSafeStringHashMap(comptime Value: type) type { lock: sync.RwLock, pub const HashMap = @This(); - pub fn init(allocator: *std.mem.Allocator) !*HashMapType { - var self = try allocator.create(HashMapType); - self.* = HashMapType{ .backing = HashMapType.init(allocator), .lock = sync.RwLock.init() }; + pub fn init(allocator: *std.mem.Allocator) !*HashMap { + var self = try allocator.create(HashMap); + self.* = HashMap{ .backing = HashMapType.init(allocator), .lock = sync.RwLock.init() }; return self; } @@ -22,6 +22,12 @@ pub fn ThreadSafeStringHashMap(comptime Value: type) type { return self.backing.get(key); } + pub fn contains(self: *HashMap, str: string) bool { + self.lock.lockShared(); + defer self.lock.unlockShared(); + return self.backing.contains(str); + } + pub fn deinit(self: *HashMap, allocator: *std.mem.Allocator) void { self.backing.deinit(); } |