aboutsummaryrefslogtreecommitdiff
path: root/src/resolver/resolver.zig
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/resolver/resolver.zig89
1 files changed, 66 insertions, 23 deletions
diff --git a/src/resolver/resolver.zig b/src/resolver/resolver.zig
index 8dffbb497..56143ed56 100644
--- a/src/resolver/resolver.zig
+++ b/src/resolver/resolver.zig
@@ -125,8 +125,8 @@ pub const Result = struct {
// remember: non-node_modules can have package.json
// checking package.json may not be relevant
pub fn isLikelyNodeModule(this: *const Result) bool {
- const dir = this.path_pair.primary.name.dirWithTrailingSlash();
- return strings.indexOf(dir, "/node_modules/") != null;
+ const path_ = this.pathConst() orelse return false;
+ return strings.indexOf(path_.text, "/node_modules/") != null;
}
// Most NPM modules are CommonJS
@@ -500,27 +500,28 @@ pub fn NewResolver(cache_files: bool) type {
const json = (try r.caches.json.parseJSON(r.log, pkg.source, r.allocator)) orelse return error.JSONParseError;
pkg.loadFrameworkWithPreference(pair, json, r.allocator, load_defines, preference);
- const dir = pkg.source.path.name.dirWithTrailingSlash();
+ const dir = pkg.source.path.sourceDir();
+
var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
if (pair.framework.client.isEnabled()) {
var parts = [_]string{ dir, pair.framework.client.path };
const abs = r.fs.abs(&parts);
- pair.framework.client.path = try r.allocator.dupe(u8, try std.os.realpath(abs, &buf));
+ pair.framework.client.path = try r.allocator.dupe(u8, abs);
pair.framework.resolved = true;
}
if (pair.framework.server.isEnabled()) {
var parts = [_]string{ dir, pair.framework.server.path };
const abs = r.fs.abs(&parts);
- pair.framework.server.path = try r.allocator.dupe(u8, try std.os.realpath(abs, &buf));
+ pair.framework.server.path = try r.allocator.dupe(u8, abs);
pair.framework.resolved = true;
}
if (pair.framework.fallback.isEnabled()) {
var parts = [_]string{ dir, pair.framework.fallback.path };
const abs = r.fs.abs(&parts);
- pair.framework.fallback.path = try r.allocator.dupe(u8, try std.os.realpath(abs, &buf));
+ pair.framework.fallback.path = try r.allocator.dupe(u8, abs);
pair.framework.resolved = true;
}
@@ -647,50 +648,80 @@ pub fn NewResolver(cache_files: bool) type {
pub fn finalizeResult(r: *ThisResolver, result: *Result) !void {
if (result.is_external) return;
- if (result.package_json) |package_json| {
- result.module_type = switch (package_json.module_type) {
- .esm, .cjs => package_json.module_type,
- .unknown => result.module_type,
- };
- }
-
var iter = result.path_pair.iter();
while (iter.next()) |path| {
var dir: *DirInfo = (r.readDirInfo(path.name.dir) catch continue) orelse continue;
+ result.package_json = result.package_json orelse dir.package_json;
+
if (dir.getEntries()) |entries| {
if (entries.get(path.name.filename)) |query| {
const symlink_path = query.entry.symlink(&r.fs.fs);
if (symlink_path.len > 0) {
- path.non_symlink = path.text;
- // Is this entry itself a symlink?
- path.text = symlink_path;
- path.name = Fs.PathName.init(path.text);
+ path.setRealpath(symlink_path);
+ if (result.file_fd == 0) result.file_fd = query.entry.cache.fd;
if (r.debug_logs) |*debug| {
- debug.addNoteFmt("Resolved symlink \"{s}\" to \"{s}\"", .{ path.non_symlink, path.text }) catch {};
+ debug.addNoteFmt("Resolved symlink \"{s}\" to \"{s}\"", .{ path.text, symlink_path }) catch {};
}
} else if (dir.abs_real_path.len > 0) {
- path.non_symlink = path.text;
var parts = [_]string{ dir.abs_real_path, query.entry.base() };
var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
+
var out = r.fs.absBuf(&parts, &buf);
+
+ if (query.entry.cache.fd == 0) {
+ buf[out.len] = 0;
+ const span = buf[0..out.len :0];
+ var file = try std.fs.openFileAbsoluteZ(span, .{ .read = true });
+
+ if (comptime !FeatureFlags.store_file_descriptors) {
+ out = try std.os.getFdPath(query.entry.cache.fd, &buf);
+ file.close();
+ } else {
+ query.entry.cache.fd = file.handle;
+ Fs.FileSystem.setMaxFd(file.handle);
+ }
+ }
+
+ defer {
+ if (r.fs.fs.needToCloseFiles()) {
+ if (query.entry.cache.fd != 0) {
+ var file = std.fs.File{ .handle = query.entry.cache.fd };
+ file.close();
+ query.entry.cache.fd = 0;
+ }
+ }
+ }
+
+ if (comptime FeatureFlags.store_file_descriptors) {
+ out = try std.os.getFdPath(query.entry.cache.fd, &buf);
+ }
+
const symlink = try Fs.FileSystem.FilenameStore.instance.append(@TypeOf(out), out);
if (r.debug_logs) |*debug| {
debug.addNoteFmt("Resolved symlink \"{s}\" to \"{s}\"", .{ symlink, path.text }) catch {};
}
query.entry.cache.symlink = symlink;
+ if (result.file_fd == 0) result.file_fd = query.entry.cache.fd;
- path.name = Fs.PathName.init(path.text);
+ path.setRealpath(symlink);
}
}
}
}
+
+ if (result.package_json) |package_json| {
+ result.module_type = switch (package_json.module_type) {
+ .esm, .cjs => package_json.module_type,
+ .unknown => result.module_type,
+ };
+ }
}
pub fn resolveWithoutSymlinks(r: *ThisResolver, source_dir: string, import_path: string, kind: ast.ImportKind) !?Result {
// This implements the module resolution algorithm from node.js, which is
// described here: https://nodejs.org/api/modules.html#modules_all_together
- var result: Result = Result{ .path_pair = PathPair{ .primary = Path.init("") } };
+ var result: Result = Result{ .path_pair = PathPair{ .primary = Path.empty } };
// Return early if this is already an absolute path. In addition to asking
// the file system whether this is an absolute path, we also explicitly check
@@ -969,11 +1000,21 @@ pub fn NewResolver(cache_files: bool) type {
pub fn rootNodeModulePackageJSON(
r: *ThisResolver,
result: *const Result,
+ base_path: *string,
) ?*const PackageJSON {
- const absolute = (result.pathConst() orelse return null).text;
+ const path = (result.pathConst() orelse return null);
+ var absolute = path.text;
// /foo/node_modules/@babel/standalone/index.js
// ^------------^
- var end = strings.lastIndexOf(absolute, node_module_root_string) orelse return null;
+ var end = strings.lastIndexOf(absolute, node_module_root_string) orelse brk: {
+ // try non-symlinked version
+ if (path.pretty.len != absolute.len) {
+ absolute = path.pretty;
+ break :brk strings.lastIndexOf(absolute, node_module_root_string);
+ }
+
+ break :brk null;
+ } orelse return null;
end += node_module_root_string.len;
const is_scoped_package = absolute[end] == '@';
@@ -996,11 +1037,13 @@ pub fn NewResolver(cache_files: bool) type {
// That can cause filesystem lookups in parent directories and it requires a lock
if (result.package_json) |pkg| {
if (strings.eql(slice, pkg.source.path.name.dirWithTrailingSlash())) {
+ base_path.* = absolute;
return pkg;
}
}
const dir_info = (r.dirInfoCached(slice) catch null) orelse return null;
+ base_path.* = absolute;
return dir_info.package_json;
}