aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-09-02 19:24:51 -0700
committerGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-09-02 19:24:51 -0700
commit4debcdcbbbd994e989694242a4c32201514b1de2 (patch)
treeb686b348b41c2e4c099853bdb0ae6ee5eaeb4395 /src
parentf23d7c5259b9cfe6874484cecb7add5a18255c34 (diff)
downloadbun-4debcdcbbbd994e989694242a4c32201514b1de2.tar.gz
bun-4debcdcbbbd994e989694242a4c32201514b1de2.tar.zst
bun-4debcdcbbbd994e989694242a4c32201514b1de2.zip
Fix tsconfig paths
Former-commit-id: 1ea6a0d624b0fc42acda9a81f214d06336b9271e
Diffstat (limited to 'src')
-rw-r--r--src/resolver/resolver.zig59
-rw-r--r--src/resolver/tsconfig_json.zig1
2 files changed, 38 insertions, 22 deletions
diff --git a/src/resolver/resolver.zig b/src/resolver/resolver.zig
index 13d504538..1d438999d 100644
--- a/src/resolver/resolver.zig
+++ b/src/resolver/resolver.zig
@@ -295,6 +295,7 @@ pub const LoadResult = struct {
path: string,
diff_case: ?Fs.FileSystem.Entry.Lookup.DifferentCase,
dirname_fd: StoredFileDescriptorType = 0,
+ file_fd: StoredFileDescriptorType = 0,
};
// This is a global so even if multiple resolvers are created, the mutex will still work
@@ -747,11 +748,14 @@ pub fn NewResolver(cache_files: bool) type {
if (dir_info.tsconfig_json) |tsconfig| {
if (tsconfig.paths.count() > 0) {
if (r.matchTSConfigPaths(tsconfig, import_path, kind)) |res| {
+
+ // We don't set the directory fd here because it might remap an entirely different directory
return Result{
.path_pair = res.path_pair,
.diff_case = res.diff_case,
- .dirname_fd = dir_info.getFileDescriptor(),
.package_json = res.package_json,
+ .dirname_fd = res.dirname_fd,
+ .file_fd = res.file_fd,
};
}
}
@@ -780,6 +784,7 @@ pub fn NewResolver(cache_files: bool) type {
.path_pair = entry.path_pair,
.diff_case = entry.diff_case,
.package_json = entry.package_json,
+ .file_fd = entry.file_fd,
};
}
@@ -1490,7 +1495,14 @@ pub fn NewResolver(cache_files: bool) type {
// This closely follows the behavior of "tryLoadModuleUsingPaths()" in the
// official TypeScript compiler
- pub fn matchTSConfigPaths(r: *ThisResolver, tsconfig: *TSConfigJSON, path: string, kind: ast.ImportKind) ?MatchResult {
+ pub fn matchTSConfigPaths(r: *ThisResolver, tsconfig: *TSConfigJSON, path_: string, kind: ast.ImportKind) ?MatchResult {
+ // Rewrite absolute import paths to be project-relative
+ // This is so that whe nimporting URLs from the web, we can still match them.
+ var path = path_;
+ if (strings.startsWith(path_, r.fs.top_level_dir)) {
+ path = path[r.fs.top_level_dir.len..];
+ }
+
if (r.debug_logs) |*debug| {
debug.addNoteFmt("Matching \"{s}\" against \"paths\" in \"{s}\"", .{ path, tsconfig.abs_path }) catch unreachable;
}
@@ -1528,8 +1540,6 @@ pub fn NewResolver(cache_files: bool) type {
return res;
}
}
-
- return null;
}
}
}
@@ -1549,16 +1559,20 @@ pub fn NewResolver(cache_files: bool) type {
const key = entry.key_ptr.*;
const original_paths = entry.value_ptr.*;
- if (strings.indexOfChar(key, '*')) |star_index| {
- const prefix = key[0..star_index];
- const suffix = key[star_index..key.len];
+ if (strings.indexOfChar(key, '*')) |star| {
+ const prefix = key[0 .. star - 1];
+ const suffix = key[star + 1 ..];
// Find the match with the longest prefix. If two matches have the same
// prefix length, pick the one with the longest suffix. This second edge
// case isn't handled by the TypeScript compiler, but we handle it
- // because we want the output to always be deterministic and Go map
- // iteration order is deliberately non-deterministic.
- if (strings.startsWith(path, prefix) and strings.endsWith(path, suffix) and (prefix.len > longest_match_prefix_length or (prefix.len == longest_match_prefix_length and suffix.len > longest_match_suffix_length))) {
+ // because we want the output to always be deterministic
+ if (strings.startsWith(path, prefix) and
+ strings.endsWith(path, suffix) and
+ (prefix.len > longest_match_prefix_length or
+ (prefix.len == longest_match_prefix_length and
+ suffix.len > longest_match_suffix_length)))
+ {
longest_match_prefix_length = @intCast(i32, prefix.len);
longest_match_suffix_length = @intCast(i32, suffix.len);
longest_match = TSConfigMatch{ .prefix = prefix, .suffix = suffix, .original_paths = original_paths };
@@ -1586,28 +1600,23 @@ pub fn NewResolver(cache_files: bool) type {
var total_length: usize = 0;
const star = std.mem.indexOfScalar(u8, original_path, '*') orelse unreachable;
total_length = star;
- std.mem.copy(u8, &TemporaryBuffer.TSConfigMatchPathBuf, original_path[0..total_length]);
- start = total_length;
- total_length += matched_text.len;
- std.mem.copy(u8, TemporaryBuffer.TSConfigMatchPathBuf[start..total_length], matched_text);
- start = total_length;
-
- total_length += original_path.len - star + 1; // this might be an off by one.
- std.mem.copy(u8, TemporaryBuffer.TSConfigMatchPathBuf[start..TemporaryBuffer.TSConfigMatchPathBuf.len], original_path[star..original_path.len]);
- const region = TemporaryBuffer.TSConfigMatchPathBuf[0..total_length];
+ const parts = [_]string{ original_path[0..total_length], matched_text, longest_match.suffix };
+ const region = r.fs.joinBuf(&parts, &TemporaryBuffer.TSConfigMatchPathBuf);
// Load the original path relative to the "baseUrl" from tsconfig.json
var absolute_original_path: string = region;
- var did_allocate = false;
if (!std.fs.path.isAbsolute(region)) {
- var paths = [_]string{ abs_base_url, original_path };
+ var paths = [_]string{ abs_base_url, region };
absolute_original_path = r.fs.absAlloc(r.allocator, &paths) catch unreachable;
- did_allocate = true;
} else {
absolute_original_path = std.mem.dupe(r.allocator, u8, region) catch unreachable;
}
+ defer {
+ r.allocator.free(absolute_original_path);
+ }
+
if (r.loadAsFileOrDirectory(absolute_original_path, kind)) |res| {
return res;
}
@@ -1844,6 +1853,7 @@ pub fn NewResolver(cache_files: bool) type {
.diff_case = file.diff_case,
.dirname_fd = file.dirname_fd,
.package_json = package_json,
+ .file_fd = file.file_fd,
};
}
}
@@ -1855,6 +1865,7 @@ pub fn NewResolver(cache_files: bool) type {
.path_pair = .{ .primary = Path.init(file.path) },
.diff_case = file.diff_case,
.dirname_fd = file.dirname_fd,
+ .file_fd = file.file_fd,
};
}
@@ -1937,6 +1948,7 @@ pub fn NewResolver(cache_files: bool) type {
.diff_case = _result.diff_case,
.dirname_fd = _result.dirname_fd,
.package_json = package_json,
+ .file_fd = auto_main_result.file_fd,
};
} else {
if (r.debug_logs) |*debug| {
@@ -2027,6 +2039,7 @@ pub fn NewResolver(cache_files: bool) type {
.path = abs_path,
.diff_case = query.diff_case,
.dirname_fd = entries.fd,
+ .file_fd = query.entry.cache.fd,
};
}
}
@@ -2053,6 +2066,7 @@ pub fn NewResolver(cache_files: bool) type {
.path = r.fs.dirname_store.append(@TypeOf(buffer), buffer) catch unreachable,
.diff_case = query.diff_case,
.dirname_fd = entries.fd,
+ .file_fd = query.entry.cache.fd,
};
}
}
@@ -2095,6 +2109,7 @@ pub fn NewResolver(cache_files: bool) type {
.path = r.fs.dirname_store.append(@TypeOf(buffer), buffer) catch unreachable,
.diff_case = query.diff_case,
.dirname_fd = entries.fd,
+ .file_fd = query.entry.cache.fd,
};
}
}
diff --git a/src/resolver/tsconfig_json.zig b/src/resolver/tsconfig_json.zig
index 11ecd4c24..5ca1f4b26 100644
--- a/src/resolver/tsconfig_json.zig
+++ b/src/resolver/tsconfig_json.zig
@@ -214,6 +214,7 @@ pub const TSConfigJSON = struct {
}
}
if (count > 0) {
+
result.paths.put(
key,
values[0..count],