aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-05-12 13:00:25 -0700
committerGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-05-12 13:00:25 -0700
commitc09d7cf83905111ef7af9ee5bbd523f56664395c (patch)
tree84fed91f8f6522594b109c09140f69d9c39ff598
parentf8131f42bcd039964586cbf3bd019dc9a449c438 (diff)
downloadbun-c09d7cf83905111ef7af9ee5bbd523f56664395c.tar.gz
bun-c09d7cf83905111ef7af9ee5bbd523f56664395c.tar.zst
bun-c09d7cf83905111ef7af9ee5bbd523f56664395c.zip
That's all the errors??
Former-commit-id: f9a74df73d2831bfdd8e6f1c0e5c999ea300fc0d
-rw-r--r--src/cache.zig61
-rw-r--r--src/fs.zig96
-rw-r--r--src/js_ast.zig24
-rw-r--r--src/js_lexer.zig16
-rw-r--r--src/js_parser/js_parser.zig12
-rw-r--r--src/json_parser.zig10
-rw-r--r--src/logger.zig40
-rw-r--r--src/options.zig8
-rw-r--r--src/resolver/package_json.zig30
-rw-r--r--src/resolver/resolve_path.zig2
-rw-r--r--src/resolver/resolver.zig89
-rw-r--r--src/resolver/tsconfig_json.zig86
12 files changed, 254 insertions, 220 deletions
diff --git a/src/cache.zig b/src/cache.zig
index 505a4653c..77f38359b 100644
--- a/src/cache.zig
+++ b/src/cache.zig
@@ -8,6 +8,8 @@ const options = @import("./options.zig");
const Defines = @import("./defines.zig").Defines;
const std = @import("std");
const fs = @import("./fs.zig");
+const sync = @import("sync.zig");
+const Mutex = sync.Mutex;
pub const Cache = struct {
pub const Set = struct {
@@ -19,18 +21,18 @@ pub const Cache = struct {
return Set{
.js = JavaScript{},
.fs = Fs{
- .mutex = std.Thread.Mutex{},
+ .mutex = Mutex.init(),
.entries = std.StringHashMap(Fs.Entry).init(allocator),
},
.json = Json{
- .mutex = std.Thread.Mutex{},
+ .mutex = Mutex.init(),
.entries = std.StringHashMap(*Json.Entry).init(allocator),
},
};
}
};
pub const Fs = struct {
- mutex: std.Thread.Mutex,
+ mutex: Mutex,
entries: std.StringHashMap(Entry),
pub const Entry = struct {
@@ -54,12 +56,12 @@ pub const Cache = struct {
c.entries.deinit();
}
- pub fn readFile(c: *Fs, _fs: fs.FileSystem, path: string) !*Entry {
- const rfs: _fs.RealFS = _fs.fs;
+ pub fn readFile(c: *Fs, _fs: *fs.FileSystem, path: string) !Entry {
+ var rfs = _fs.fs;
{
- const hold = c.mutex.acquire();
- defer hold.release();
+ c.mutex.lock();
+ defer c.mutex.unlock();
if (c.entries.get(path)) |entry| {
return entry;
}
@@ -67,7 +69,7 @@ pub const Cache = struct {
// If the file's modification key hasn't changed since it was cached, assume
// the contents of the file are also the same and skip reading the file.
- var mod_key: ?fs.FileSystem.Implementation.ModKey = rfs.modKey(path) catch |err| {
+ var mod_key: ?fs.FileSystem.Implementation.ModKey = rfs.modKey(path) catch |err| handler: {
switch (err) {
error.FileNotFound, error.AccessDenied => {
return err;
@@ -76,7 +78,7 @@ pub const Cache = struct {
if (isDebug) {
Output.printError("modkey error: {s}", .{@errorName(err)});
}
- mod_key = null;
+ break :handler null;
},
}
};
@@ -94,15 +96,16 @@ pub const Cache = struct {
.mod_key = mod_key,
};
- const hold = c.mutex.acquire();
- defer hold.release();
- var res = c.entries.getOrPut(path, entry) catch unreachable;
+ c.mutex.lock();
+ defer c.mutex.unlock();
+ var res = c.entries.getOrPut(path) catch unreachable;
+
if (res.found_existing) {
res.entry.value.deinit(c.entries.allocator);
}
res.entry.value = entry;
- return &en.value;
+ return res.entry.value;
}
};
@@ -153,19 +156,19 @@ pub const Cache = struct {
ok: bool = false,
// msgs: []logger.Msg,
};
- mutex: std.Thread.Mutex,
+ mutex: Mutex,
entries: std.StringHashMap(*Entry),
pub fn init(allocator: *std.mem.Allocator) Json {
return Json{
- .mutex = std.Thread.Mutex{},
+ .mutex = Mutex.init(),
.entries = std.StringHashMap(Entry).init(allocator),
};
}
- fn parse(cache: *@This(), log: *logger.Log, source: logger.Source, allocator: *std.mem.Allocator, is_tsconfig: bool, func: anytype) anyerror!?Expr {
+ fn parse(cache: *@This(), log: *logger.Log, source: logger.Source, allocator: *std.mem.Allocator, is_tsconfig: bool, func: anytype) anyerror!?js_ast.Expr {
{
- const hold = cache.mutex.acquire();
- defer hold.release();
- if (cache.entries.get(source.key_path)) |entry| {
+ cache.mutex.lock();
+ defer cache.mutex.unlock();
+ if (cache.entries.get(source.key_path.text)) |entry| {
return entry.expr;
}
}
@@ -174,8 +177,8 @@ pub const Cache = struct {
defer {
temp_log.appendTo(log) catch {};
}
- const expr = func(&source, &temp_log, allocator) catch {
- null;
+ const expr = func(&source, &temp_log, allocator) catch handler: {
+ break :handler null;
};
const entry = try allocator.create(Entry);
entry.* = Entry{
@@ -185,18 +188,18 @@ pub const Cache = struct {
.ok = expr != null,
};
- const hold = cache.mutex.acquire();
- defer hold.release();
- std.debug.assert(source.key_path.len > 0); // missing key_path in source
- try cache.entries.put(source.key_path, entry);
+ cache.mutex.lock();
+ defer cache.mutex.unlock();
+ std.debug.assert(source.key_path.text.len > 0); // missing key_path in source
+ try cache.entries.put(source.key_path.text, entry);
return entry.expr;
}
- pub fn parseJSON(cache: *@This(), log: *logger.Log, source: logger.Source, allocator: *std.mem.Allocator) anyerror!?Expr {
- return @call(std.builtin.CallOptions{ .modifier = .always_tail }, parse, .{ cache, log, opts, source, allocator, false, json_parser.ParseJSON });
+ 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 });
}
- pub fn parseTSConfig(cache: *@This(), log: *logger.Log, source: logger.Source, allocator: *std.mem.Allocator) anyerror!?Expr {
- return @call(std.builtin.CallOptions{ .modifier = .always_tail }, parse, .{ cache, log, opts, source, allocator, true, json_parser.ParseTSConfig });
+ 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 });
}
};
};
diff --git a/src/fs.zig b/src/fs.zig
index cdf8c520d..2337bdb19 100644
--- a/src/fs.zig
+++ b/src/fs.zig
@@ -123,22 +123,22 @@ pub const FileSystem = struct {
file,
};
- pub fn kind(entry: *Entry, fs: *Implementation) !Kind {
+ pub fn kind(entry: *Entry, fs: *Implementation) Kind {
entry.mutex.lock();
defer entry.mutex.unlock();
if (entry.need_stat) {
entry.need_stat = false;
- entry.cache = try fs.kind(entry.dir, entry.base);
+ entry.cache = fs.kind(entry.dir, entry.base) catch unreachable;
}
return entry.cache.kind;
}
- pub fn symlink(entry: *Entry, fs: *Implementation) !string {
+ pub fn symlink(entry: *Entry, fs: *Implementation) string {
entry.mutex.lock();
defer entry.mutex.unlock();
if (entry.need_stat) {
entry.need_stat = false;
- entry.cache = try fs.kind(entry.dir, entry.base);
+ entry.cache = fs.kind(entry.dir, entry.base) catch unreachable;
}
return entry.cache.symlink;
}
@@ -175,32 +175,32 @@ pub const FileSystem = struct {
};
}
+ pub const ModKeyError = error{
+ Unusable,
+ };
pub const ModKey = struct {
inode: std.fs.File.INode = 0,
size: u64 = 0,
mtime: i128 = 0,
mode: std.fs.File.Mode = 0,
- pub const Error = error{
- Unusable,
- };
pub fn generate(fs: *RealFS, path: string) anyerror!ModKey {
var file = try std.fs.openFileAbsolute(path, std.fs.File.OpenFlags{ .read = true });
defer file.close();
const stat = try file.stat();
- const seconds = stat.mtime / std.time.ns_per_s;
+ const seconds = @divTrunc(stat.mtime, @as(@TypeOf(stat.mtime), std.time.ns_per_s));
// We can't detect changes if the file system zeros out the modification time
if (seconds == 0 and std.time.ns_per_s == 0) {
- return Error.Unusable;
+ return error.Unusable;
}
// Don't generate a modification key if the file is too new
const now = std.time.nanoTimestamp();
- const now_seconds = now / std.time.ns_per_s;
+ const now_seconds = @divTrunc(now, std.time.ns_per_s);
if (seconds > seconds or (seconds == now_seconds and stat.mtime > now)) {
- return Error.Unusable;
+ return error.Unusable;
}
return ModKey{
@@ -214,35 +214,38 @@ pub const FileSystem = struct {
pub const SafetyGap = 3;
};
- fn modKeyError(fs: *RealFS, path: string, err: anyerror) !void {
+ fn modKeyError(fs: *RealFS, path: string, err: anyerror) void {
if (fs.watcher) |*watcher| {
- watch_data.watch_mutex.lock();
- defer watch_data.watch_mutex.unlock();
+ fs.watcher_mutex.lock();
+ defer fs.watcher_mutex.unlock();
var state = WatchData.State.file_missing;
switch (err) {
- ModKey.Error.Unusable => {
+ error.Unusable => {
state = WatchData.State.file_unusable_mod_key;
},
else => {},
}
- var entry = try watcher.getOrPutValue(path, WatchData{ .state = state });
+ var entry = watcher.getOrPutValue(path, WatchData{ .state = state }) catch unreachable;
entry.value.state = state;
}
- return err;
}
- pub fn modKey(fs: *RealFS, path: string) !ModKey {
+ pub fn modKey(fs: *RealFS, path: string) anyerror!ModKey {
fs.limiter.before();
defer fs.limiter.after();
- const key = ModKey.generate(fs, path) catch |err| return fs.modKeyError(path, err);
+ const key = ModKey.generate(fs, path) catch |err| {
+ fs.modKeyError(path, err);
+ return err;
+ };
+
if (fs.watcher) |*watcher| {
fs.watcher_mutex.lock();
defer fs.watcher_mutex.unlock();
- var entry = try watcher.getOrPutValue(path, WatchData{ .state = .file_has_mod_key, .mod_key = key });
+ var entry = watcher.getOrPutValue(path, WatchData{ .state = .file_has_mod_key, .mod_key = key }) catch unreachable;
entry.value.mod_key = key;
}
@@ -420,32 +423,39 @@ pub const FileSystem = struct {
return result;
}
- fn readFileError(fs: *RealFS, path: string, err: anyerror) !void {
+ fn readFileError(fs: *RealFS, path: string, err: anyerror) void {
if (fs.watcher) |*watcher| {
fs.watcher_mutex.lock();
defer fs.watcher_mutex.unlock();
- var res = try watcher.getOrPutValue(path, WatchData{ .state = .file_missing });
+ var res = watcher.getOrPutValue(path, WatchData{ .state = .file_missing }) catch unreachable;
res.value.state = .file_missing;
}
-
- return err;
}
pub fn readFile(fs: *RealFS, path: string, _size: ?usize) !File {
fs.limiter.before();
defer fs.limiter.after();
- const file: std.fs.File = std.fs.openFileAbsolute(path, std.fs.File.OpenFlags{ .read = true, .write = false }) catch |err| return fs.readFileError(path, err);
+ const file: std.fs.File = std.fs.openFileAbsolute(path, std.fs.File.OpenFlags{ .read = true, .write = false }) catch |err| {
+ fs.readFileError(path, err);
+ return err;
+ };
defer file.close();
// Skip the extra file.stat() call when possible
- const size = _size orelse (try file.getEndPos() catch |err| return fs.readFileError(path, err));
- const file_contents: []u8 = file.readToEndAllocOptions(fs.allocator, size, size, @alignOf(u8), null) catch |err| return fs.readFileError(path, err);
+ const 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;
+ };
if (fs.watcher) |*watcher| {
- var hold = fs.watcher_mutex.acquire();
- defer hold.release();
- var res = try watcher.getOrPutValue(path, WatchData{});
+ fs.watcher_mutex.lock();
+ defer fs.watcher_mutex.unlock();
+ var res = watcher.getOrPutValue(path, WatchData{}) catch unreachable;
res.value.state = .file_need_mod_key;
res.value.file_contents = file_contents;
}
@@ -464,16 +474,17 @@ pub const FileSystem = struct {
const file = try std.fs.openFileAbsolute(entry_path, .{ .read = true, .write = false });
defer file.close();
- const stat = try file.stat();
+ var stat = try file.stat();
+
var _kind = stat.kind;
var cache = Entry.Cache{ .kind = Entry.Kind.file, .symlink = "" };
-
+ var symlink: []u8 = &([_]u8{});
if (_kind == .SymLink) {
// windows has a max filepath of 255 chars
// we give it a little longer for other platforms
- var out_buffer = [_]u8{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- var out_slice = &(out_buffer);
- var symlink = entry_path;
+ var out_buffer = std.mem.zeroes([512]u8);
+ var out_slice = &out_buffer;
+ symlink = entry_path;
var links_walked: u8 = 0;
while (links_walked < 255) : (links_walked += 1) {
@@ -482,7 +493,7 @@ pub const FileSystem = struct {
if (!std.fs.path.isAbsolute(link)) {
combo[0] = dir;
combo[1] = link;
- if (link.ptr != out_slice.ptr) {
+ if (link.ptr != &out_buffer) {
fs.allocator.free(link);
}
link = std.fs.path.join(fs.allocator, &combo) catch return cache;
@@ -496,8 +507,8 @@ pub const FileSystem = struct {
const stat2 = file2.stat() catch return cache;
// Re-run "lstat" on the symlink target
- mode = stat2.mode;
- if (mode == .Symlink) {
+ _kind = stat2.kind;
+ if (_kind != .SymLink) {
break;
}
dir = std.fs.path.dirname(link) orelse return cache;
@@ -508,12 +519,11 @@ pub const FileSystem = struct {
}
}
- if (mode == .Directory) {
- _kind = Entry.Kind.dir;
+ if (_kind == .Directory) {
+ cache.kind = .dir;
} else {
- _kind = Entry.Kind.file;
+ cache.kind = .file;
}
- cache.kind = _kind;
cache.symlink = symlink;
return cache;
@@ -627,7 +637,7 @@ pub const Path = struct {
// for now, assume you won't try to normalize a path longer than 1024 chars
pub fn normalize(str: string, allocator: *std.mem.Allocator) string {
if (str.len == 0 or (str.len == 1 and str[0] == ' ')) return ".";
- if (resolvePath(normalize_buf, str)) |out| {
+ if (resolvePath(&normalize_buf, str)) |out| {
return allocator.dupe(u8, out) catch unreachable;
}
return str;
diff --git a/src/js_ast.zig b/src/js_ast.zig
index 6a93310a2..66954a5bb 100644
--- a/src/js_ast.zig
+++ b/src/js_ast.zig
@@ -938,7 +938,7 @@ pub const E = struct {
}
},
string => {
- return strings.utf16EqlString(other.utf8, s.value);
+ return strings.utf16EqlString(s.value, other);
},
JavascriptString => {
return std.mem.eql(u16, other.value, s.value);
@@ -1381,13 +1381,15 @@ pub const Expr = struct {
pub const Query = struct { expr: Expr, loc: logger.Loc };
- pub fn getProperty(expr: *Expr, name: string) ?Query {
- const obj: *E.Object = expr.data.e_object orelse return null;
+ pub fn getProperty(expr: *const Expr, name: string) ?Query {
+ if (std.meta.activeTag(expr.data) != .e_object) return null;
+ const obj: *E.Object = expr.data.e_object;
for (obj.properties) |prop| {
const value = prop.value orelse continue;
const key = prop.key orelse continue;
- const key_str: *E.String = key.data.e_string orelse continue;
+ if (std.meta.activeTag(key.data) != .e_string) continue;
+ const key_str: *E.String = key.data.e_string;
if (key_str.eql(string, name)) {
return Query{ .expr = value, .loc = key.loc };
}
@@ -1396,16 +1398,20 @@ pub const Expr = struct {
return null;
}
- pub fn getString(expr: *Expr, allocator: *std.mem.Allocator) !?string {
- const key_str: *E.String = expr.data.e_string orelse return null;
+ pub fn getString(expr: *const Expr, allocator: *std.mem.Allocator) ?string {
+ if (std.meta.activeTag(expr.data) != .e_string) return null;
- return if (key_str.isUTF8()) key_str.value else key_str.string(allocator);
+ const key_str: *E.String = expr.data.e_string;
+
+ return if (key_str.isUTF8()) key_str.utf8 else key_str.string(allocator) catch null;
}
pub fn getBool(
- expr: *Expr,
+ expr: *const Expr,
) ?bool {
- const obj: *E.Boolean = expr.data.e_boolean orelse return null;
+ if (std.meta.activeTag(expr.data) != .e_boolean) return null;
+
+ const obj = expr.data.e_boolean;
return obj.value;
}
diff --git a/src/js_lexer.zig b/src/js_lexer.zig
index 4c758c6a4..e90886ead 100644
--- a/src/js_lexer.zig
+++ b/src/js_lexer.zig
@@ -52,7 +52,7 @@ pub const Lexer = struct {
log: *logger.Log,
json_options: ?JSONOptions = null,
for_global_name: bool = false,
- source: *logger.Source,
+ source: *const logger.Source,
current: usize = 0,
start: usize = 0,
end: usize = 0,
@@ -1094,11 +1094,11 @@ pub const Lexer = struct {
};
}
- pub fn initGlobalName(log: *logger.Log, source: *logger.Source, allocator: *std.mem.Allocator) !LexerType {
- var empty_string_literal: JavascriptString = emptyJavaScriptString;
+ pub fn initGlobalName(log: *logger.Log, source: *const logger.Source, allocator: *std.mem.Allocator) !LexerType {
+ var empty_string_literal: JavascriptString = &emptyJavaScriptString;
var lex = LexerType{
.log = log,
- .source = source.*,
+ .source = source,
.string_literal_is_ascii = true,
.string_literal = empty_string_literal,
.string_literal_buffer = std.ArrayList(u16).init(allocator),
@@ -1113,11 +1113,11 @@ pub const Lexer = struct {
return lex;
}
- pub fn initTSConfig(log: *logger.Log, source: *logger.Source, allocator: *std.mem.Allocator) !LexerType {
- var empty_string_literal: JavascriptString = emptyJavaScriptString;
+ pub fn initTSConfig(log: *logger.Log, source: *const logger.Source, allocator: *std.mem.Allocator) !LexerType {
+ var empty_string_literal: JavascriptString = &emptyJavaScriptString;
var lex = LexerType{
.log = log,
- .source = source.*,
+ .source = source,
.string_literal = empty_string_literal,
.string_literal_buffer = std.ArrayList(u16).init(allocator),
.prev_error_loc = logger.Loc.Empty,
@@ -1135,7 +1135,7 @@ pub const Lexer = struct {
return lex;
}
- pub fn initJSON(log: *logger.Log, source: *logger.Source, allocator: *std.mem.Allocator) !LexerType {
+ pub fn initJSON(log: *logger.Log, source: *const logger.Source, allocator: *std.mem.Allocator) !LexerType {
var empty_string_literal: JavascriptString = &emptyJavaScriptString;
var lex = LexerType{
.log = log,
diff --git a/src/js_parser/js_parser.zig b/src/js_parser/js_parser.zig
index e15699a55..5cbf5cd3e 100644
--- a/src/js_parser/js_parser.zig
+++ b/src/js_parser/js_parser.zig
@@ -1323,8 +1323,8 @@ pub const Parser = struct {
var i: usize = 0;
var additional_stmt: ?Stmt = null;
if (jsx_factory_symbol.use_count_estimate > 0) {
- jsx_imports[i] = p.options.jsx.factory;
- try symbols.put(p.options.jsx.factory, p.jsx_factory_ref);
+ jsx_imports[i] = p.options.jsx.factory[0];
+ try symbols.put(p.options.jsx.factory[0], p.jsx_factory_ref);
i += 1;
}
@@ -1347,9 +1347,9 @@ pub const Parser = struct {
}
if (jsx_fragment_symbol.use_count_estimate > 0) {
- jsx_imports[i] = p.options.jsx.fragment;
+ jsx_imports[i] = p.options.jsx.fragment[0];
- try symbols.put(p.options.jsx.fragment, p.jsx_fragment_ref);
+ try symbols.put(p.options.jsx.fragment[0], p.jsx_fragment_ref);
i += 1;
}
@@ -2208,9 +2208,9 @@ pub const P = struct {
p.jsx_filename_ref = p.newSymbol(.other, Prefill.Runtime.JSXFilename) catch unreachable;
}
const jsx_importname = p.options.jsx.jsx;
- p.jsx_fragment_ref = p.newSymbol(.other, p.options.jsx.fragment) catch unreachable;
+ p.jsx_fragment_ref = p.newSymbol(.other, p.options.jsx.fragment[p.options.jsx.fragment.len - 1]) catch unreachable;
p.jsx_runtime_ref = p.newSymbol(.other, jsx_importname) catch unreachable;
- p.jsx_factory_ref = p.newSymbol(.other, p.options.jsx.factory) catch unreachable;
+ p.jsx_factory_ref = p.newSymbol(.other, p.options.jsx.factory[p.options.jsx.factory.len - 1]) catch unreachable;
}
// ECMAScript modules are always interpreted as strict mode. This has to be
diff --git a/src/json_parser.zig b/src/json_parser.zig
index 80c7511a7..4fb1f89f7 100644
--- a/src/json_parser.zig
+++ b/src/json_parser.zig
@@ -41,11 +41,11 @@ const Lexer = js_lexer.Lexer;
fn JSONLikeParser(opts: js_lexer.JSONOptions) type {
return struct {
lexer: Lexer,
- source: *logger.Source,
+ source: *const logger.Source,
log: *logger.Log,
allocator: *std.mem.Allocator,
- pub fn init(allocator: *std.mem.Allocator, source: *logger.Source, log: *logger.Log) !Parser {
+ pub fn init(allocator: *std.mem.Allocator, source: *const logger.Source, log: *logger.Log) !Parser {
if (opts.allow_comments) {
return Parser{
.lexer = try Lexer.initTSConfig(log, source, allocator),
@@ -210,14 +210,14 @@ fn JSONLikeParser(opts: js_lexer.JSONOptions) type {
const JSONParser = JSONLikeParser(js_lexer.JSONOptions{});
const TSConfigParser = JSONLikeParser(js_lexer.JSONOptions{ .allow_comments = true, .allow_trailing_commas = true });
-pub fn ParseJSON(source: *logger.Source, log: *logger.Log, allocator: *std.mem.Allocator) !Expr {
+pub fn ParseJSON(source: *const logger.Source, log: *logger.Log, allocator: *std.mem.Allocator) !Expr {
var parser = try JSONParser.init(allocator, source, log);
return parser.parseExpr();
}
-pub fn ParseTSConfig(log: logger.Loc, source: *logger.Source, allocator: *std.mem.Allocator) !Expr {
- var parser = try TSConfigParser.init(allocator, log, source);
+pub fn ParseTSConfig(source: *const logger.Source, log: *logger.Log, allocator: *std.mem.Allocator) !Expr {
+ var parser = try TSConfigParser.init(allocator, source, log);
return parser.parseExpr();
}
diff --git a/src/logger.zig b/src/logger.zig
index ec93e52cc..a07adc203 100644
--- a/src/logger.zig
+++ b/src/logger.zig
@@ -214,7 +214,7 @@ pub const Log = struct {
};
}
- pub fn addVerbose(log: *Log, source: ?*Source, loc: Loc, text: string) !void {
+ pub fn addVerbose(log: *Log, source: ?*const Source, loc: Loc, text: string) !void {
try log.addMsg(Msg{
.kind = .verbose,
.data = rangeData(source, Range{ .loc = loc }, text),
@@ -232,7 +232,7 @@ pub const Log = struct {
self.msgs.deinit();
}
- pub fn addVerboseWithNotes(log: *Log, source: ?*Source, loc: Loc, text: string, notes: []Data) !void {
+ pub fn addVerboseWithNotes(log: *Log, source: ?*const Source, loc: Loc, text: string, notes: []Data) !void {
try log.addMsg(Msg{
.kind = .verbose,
.data = rangeData(source, Range{ .loc = loc }, text),
@@ -240,7 +240,7 @@ pub const Log = struct {
});
}
- pub fn addRangeError(log: *Log, source: ?*Source, r: Range, text: string) !void {
+ pub fn addRangeError(log: *Log, source: ?*const Source, r: Range, text: string) !void {
log.errors += 1;
try log.addMsg(Msg{
.kind = .err,
@@ -248,7 +248,7 @@ pub const Log = struct {
});
}
- pub fn addRangeErrorFmt(log: *Log, source: ?*Source, r: Range, allocator: *std.mem.Allocator, comptime text: string, args: anytype) !void {
+ pub fn addRangeErrorFmt(log: *Log, source: ?*const Source, r: Range, allocator: *std.mem.Allocator, comptime text: string, args: anytype) !void {
log.errors += 1;
try log.addMsg(Msg{
.kind = .err,
@@ -256,7 +256,7 @@ pub const Log = struct {
});
}
- pub fn addRangeErrorFmtWithNotes(log: *Log, source: ?*Source, r: Range, allocator: *std.mem.Allocator, notes: []Data, comptime text: string, args: anytype) !void {
+ pub fn addRangeErrorFmtWithNotes(log: *Log, source: ?*const Source, r: Range, allocator: *std.mem.Allocator, notes: []Data, comptime text: string, args: anytype) !void {
log.errors += 1;
try log.addMsg(Msg{
.kind = .err,
@@ -265,7 +265,7 @@ pub const Log = struct {
});
}
- pub fn addErrorFmt(log: *Log, source: ?*Source, l: Loc, allocator: *std.mem.Allocator, comptime text: string, args: anytype) !void {
+ pub fn addErrorFmt(log: *Log, source: ?*const Source, l: Loc, allocator: *std.mem.Allocator, comptime text: string, args: anytype) !void {
log.errors += 1;
try log.addMsg(Msg{
.kind = .err,
@@ -273,7 +273,7 @@ pub const Log = struct {
});
}
- pub fn addRangeWarning(log: *Log, source: ?*Source, r: Range, text: string) !void {
+ pub fn addRangeWarning(log: *Log, source: ?*const Source, r: Range, text: string) !void {
log.warnings += 1;
try log.addMsg(Msg{
.kind = .warn,
@@ -281,7 +281,7 @@ pub const Log = struct {
});
}
- pub fn addWarningFmt(log: *Log, source: ?*Source, l: Loc, allocator: *std.mem.Allocator, comptime text: string, args: anytype) !void {
+ pub fn addWarningFmt(log: *Log, source: ?*const Source, l: Loc, allocator: *std.mem.Allocator, comptime text: string, args: anytype) !void {
log.warnings += 1;
try log.addMsg(Msg{
.kind = .err,
@@ -289,7 +289,7 @@ pub const Log = struct {
});
}
- pub fn addRangeWarningFmt(log: *Log, source: ?*Source, r: Range, allocator: *std.mem.Allocator, comptime text: string, args: anytype) !void {
+ pub fn addRangeWarningFmt(log: *Log, source: ?*const Source, r: Range, allocator: *std.mem.Allocator, comptime text: string, args: anytype) !void {
log.warnings += 1;
try log.addMsg(Msg{
.kind = .warn,
@@ -297,7 +297,7 @@ pub const Log = struct {
});
}
- pub fn addWarning(log: *Log, source: ?*Source, l: Loc, text: string) !void {
+ pub fn addWarning(log: *Log, source: ?*const Source, l: Loc, text: string) !void {
log.warnings += 1;
try log.addMsg(Msg{
.kind = .warn,
@@ -305,14 +305,14 @@ pub const Log = struct {
});
}
- pub fn addRangeDebug(log: *Log, source: ?*Source, r: Range, text: string) !void {
+ pub fn addRangeDebug(log: *Log, source: ?*const Source, r: Range, text: string) !void {
try log.addMsg(Msg{
.kind = .debug,
.data = rangeData(source, r, text),
});
}
- pub fn addRangeDebugWithNotes(log: *Log, source: ?*Source, r: Range, text: string, notes: []Data) !void {
+ pub fn addRangeDebugWithNotes(log: *Log, source: ?*const Source, r: Range, text: string, notes: []Data) !void {
// log.de += 1;
try log.addMsg(Msg{
.kind = Kind.debug,
@@ -321,7 +321,7 @@ pub const Log = struct {
});
}
- pub fn addRangeErrorWithNotes(log: *Log, source: ?*Source, r: Range, text: string, notes: []Data) !void {
+ pub fn addRangeErrorWithNotes(log: *Log, source: ?*const Source, r: Range, text: string, notes: []Data) !void {
log.errors += 1;
try log.addMsg(Msg{
.kind = Kind.err,
@@ -330,7 +330,7 @@ pub const Log = struct {
});
}
- pub fn addRangeWarningWithNotes(log: *Log, source: ?*Source, r: Range, text: string, notes: []Data) !void {
+ pub fn addRangeWarningWithNotes(log: *Log, source: ?*const Source, r: Range, text: string, notes: []Data) !void {
log.warnings += 1;
try log.addMsg(Msg{
.kind = .warning,
@@ -345,7 +345,7 @@ pub const Log = struct {
}
// TODO:
- pub fn addError(self: *Log, _source: ?*Source, loc: Loc, text: string) !void {
+ pub fn addError(self: *Log, _source: ?*const Source, loc: Loc, text: string) !void {
self.errors += 1;
try self.addMsg(Msg{ .kind = .err, .data = rangeData(_source, Range{ .loc = loc }, text) });
}
@@ -400,14 +400,14 @@ pub const Source = struct {
pub fn initPathString(pathString: string, contents: string) Source {
var path = fs.Path.init(pathString);
- return Source{ .path = path, .identifier_name = path.name.base, .contents = contents };
+ return Source{ .key_path = path, .path = path, .identifier_name = path.name.base, .contents = contents };
}
- pub fn textForRange(self: *Source, r: Range) string {
+ pub fn textForRange(self: *const Source, r: Range) string {
return self.contents[r.loc.i()..r.endI()];
}
- pub fn rangeOfOperatorBefore(self: *Source, loc: Loc, op: string) Range {
+ pub fn rangeOfOperatorBefore(self: *const Source, loc: Loc, op: string) Range {
const text = self.contents[0..loc.i()];
const index = strings.index(text, op);
if (index >= 0) {
@@ -419,7 +419,7 @@ pub const Source = struct {
return Range{ .loc = loc };
}
- pub fn rangeOfString(self: *Source, loc: Loc) Range {
+ pub fn rangeOfString(self: *const Source, loc: Loc) Range {
const text = self.contents[loc.i()..];
if (text.len == 0) {
@@ -446,7 +446,7 @@ pub const Source = struct {
return Range{ .loc = loc, .len = 0 };
}
- pub fn rangeOfOperatorAfter(self: *Source, loc: Loc, op: string) Range {
+ pub fn rangeOfOperatorAfter(self: *const Source, loc: Loc, op: string) Range {
const text = self.contents[loc.i()..];
const index = strings.index(text, op);
if (index >= 0) {
diff --git a/src/options.zig b/src/options.zig
index 29be30cca..b994dbe4b 100644
--- a/src/options.zig
+++ b/src/options.zig
@@ -180,8 +180,8 @@ pub const defaultLoaders = std.ComptimeStringMap(Loader, .{
pub const JSX = struct {
pub const Pragma = struct {
// these need to be arrays
- factory: string = "React.createElement",
- fragment: string = "React.Fragment",
+ factory: []string = &(Defaults.Factory),
+ fragment: []string = &(Defaults.Fragment),
runtime: JSX.Runtime = JSX.Runtime.automatic,
/// Facilitates automatic JSX importing
@@ -192,6 +192,10 @@ pub const JSX = struct {
development: bool = true,
parse: bool = true,
+ pub const Defaults = struct {
+ pub var Factory = [_]string{ "React", "createElement" };
+ pub var Fragment = [_]string{ "React", "Fragment" };
+ };
pub fn fromApi(jsx: api.Api.Jsx) Pragma {
var pragma = JSX.Pragma{};
diff --git a/src/resolver/package_json.zig b/src/resolver/package_json.zig
index 3bab16ef2..68d6bacb1 100644
--- a/src/resolver/package_json.zig
+++ b/src/resolver/package_json.zig
@@ -44,28 +44,23 @@ pub const PackageJSON = struct {
//
browser_map: BrowserMap,
- pub fn parse(r: *resolver.Resolver, input_path: string) ?*PackageJSON {
- if (!has_set_default_main_fields) {
- has_set_default_main_fields = true;
- }
-
+ pub fn parse(r: *resolver.Resolver, input_path: string) ?PackageJSON {
const parts = [_]string{ input_path, "package.json" };
const package_json_path = std.fs.path.join(r.allocator, &parts) catch unreachable;
errdefer r.allocator.free(package_json_path);
- const entry: *r.caches.fs.Entry = try r.caches.fs.readFile(r.fs, input_path) catch |err| {
- r.log.addErrorFmt(null, .empty, r.allocator, "Cannot read file \"{s}\": {s}", .{ r.prettyPath(fs.Path.init(input_path)), @errorName(err) }) catch unreachable;
+ const entry = r.caches.fs.readFile(r.fs, input_path) catch |err| {
+ r.log.addErrorFmt(null, logger.Loc.Empty, r.allocator, "Cannot read file \"{s}\": {s}", .{ r.prettyPath(fs.Path.init(input_path)), @errorName(err) }) catch unreachable;
return null;
};
- if (r.debug_logs) |debug| {
+ if (r.debug_logs) |*debug| {
debug.addNoteFmt("The file \"{s}\" exists", .{package_json_path}) catch unreachable;
}
- const key_path = fs.Path.init(allocator.dupe(package_json_path) catch unreachable);
+ const key_path = fs.Path.init(r.allocator.dupe(u8, package_json_path) catch unreachable);
- var json_source = logger.Source.initPathString(key_path);
- json_source.contents = entry.contents;
+ var json_source = logger.Source.initPathString(key_path.text, entry.contents);
json_source.path.pretty = r.prettyPath(json_source.path);
const json: js_ast.Expr = (r.caches.json.parseJSON(r.log, json_source, r.allocator) catch |err| {
@@ -77,8 +72,9 @@ pub const PackageJSON = struct {
var package_json = PackageJSON{
.source = json_source,
+ .module_type = .unknown,
.browser_map = BrowserMap.init(r.allocator),
- .main_fields_map = MainFieldMap.init(r.allocator),
+ .main_fields = MainFieldMap.init(r.allocator),
};
if (json.getProperty("type")) |type_json| {
@@ -110,7 +106,7 @@ pub const PackageJSON = struct {
if (json.getProperty(main)) |main_json| {
const expr: js_ast.Expr = main_json.expr;
- if ((main_json.getString(r.allocator) catch null)) |str| {
+ if ((expr.getString(r.allocator))) |str| {
if (str.len > 0) {
package_json.main_fields.put(main, str) catch unreachable;
}
@@ -132,13 +128,13 @@ pub const PackageJSON = struct {
// },
//
if (json.getProperty("browser")) |browser_prop| {
- switch (browser_prop.data) {
+ switch (browser_prop.expr.data) {
.e_object => |obj| {
// The value is an object
// Remap all files in the browser field
for (obj.properties) |prop| {
- var _key_str = (prop.key orelse continue).getString(r.allocator) catch unreachable;
+ var _key_str = (prop.key orelse continue).getString(r.allocator) orelse continue;
const value: js_ast.Expr = prop.value orelse continue;
// Normalize the path so we can compare against it without getting
@@ -155,7 +151,7 @@ pub const PackageJSON = struct {
switch (value.data) {
.e_string => |str| {
// If this is a string, it's a replacement package
- package_json.browser_map.put(key, str) catch unreachable;
+ package_json.browser_map.put(key, str.string(r.allocator) catch unreachable) catch unreachable;
},
.e_boolean => |boolean| {
if (!boolean.value) {
@@ -163,7 +159,7 @@ pub const PackageJSON = struct {
}
},
else => {
- r.log.addWarning("Each \"browser\" mapping must be a string or boolean", value.loc) catch unreachable;
+ r.log.addWarning(&json_source, value.loc, "Each \"browser\" mapping must be a string or boolean") catch unreachable;
},
}
}
diff --git a/src/resolver/resolve_path.zig b/src/resolver/resolve_path.zig
index 78f00cf96..f639bff1b 100644
--- a/src/resolver/resolve_path.zig
+++ b/src/resolver/resolve_path.zig
@@ -25,7 +25,7 @@ pub fn resolvePath(buffer: []u8, src_path: []const u8) ?[]u8 {
}
} else {
if (end + segment.len + 1 > buffer.len)
- return error.BufferTooSmall;
+ return null;
const start = end;
buffer[end] = '/';
diff --git a/src/resolver/resolver.zig b/src/resolver/resolver.zig
index 340648399..88bc13cd5 100644
--- a/src/resolver/resolver.zig
+++ b/src/resolver/resolver.zig
@@ -34,7 +34,7 @@ pub const DirInfo = struct {
entries: fs.FileSystem.DirEntry,
has_node_modules: bool = false, // Is there a "node_modules" subdirectory?
package_json: ?*PackageJSON = null, // Is there a "package.json" file?
- ts_config_json: ?*TSConfigJSON = null, // Is there a "tsconfig.json" file in this directory or a parent directory?
+ tsconfig_json: ?*TSConfigJSON = null, // Is there a "tsconfig.json" file in this directory or a parent directory?
abs_real_path: string = "", // If non-empty, this is the real absolute path resolving any symlinks
};
@@ -331,7 +331,7 @@ pub const Resolver = struct {
// First, check path overrides from the nearest enclosing TypeScript "tsconfig.json" file
if ((r.dirInfoCached(source_dir) catch null)) |_dir_info| {
const dir_info: *DirInfo = _dir_info;
- if (dir_info.ts_config_json) |tsconfig| {
+ if (dir_info.tsconfig_json) |tsconfig| {
if (tsconfig.paths.count() > 0) {
const res = r.matchTSConfigPaths(tsconfig, import_path, kind);
return Result{ .path_pair = res.path_pair, .diff_case = res.diff_case };
@@ -384,27 +384,23 @@ pub const Resolver = struct {
const entry = try r.caches.fs.readFile(r.fs, file);
const key_path = Path.init(file);
- const source = logger.Source{
- .key_path = key_path,
- .pretty_path = r.prettyPath(key_path),
- .contents = entry.contents,
- };
- const file_dir = std.fs.path.dirname(file);
+ const source = logger.Source.initPathString(key_path.text, entry.contents);
+ const file_dir = std.fs.path.dirname(file) orelse return null;
- var result = try TSConfigJSON.parse(r.allocator, r.log, r.opts, r.caches.json) orelse return null;
+ var result = (try TSConfigJSON.parse(r.allocator, r.log, source, &r.caches.json)) orelse return null;
if (result.base_url) |base| {
// this might leak
if (!std.fs.path.isAbsolute(base)) {
- var paths = [_]string{ file_dir, base };
- result.base_url = std.fs.path.join(r.allocator, paths) catch unreachable;
+ const paths = [_]string{ file_dir, base };
+ result.base_url = std.fs.path.join(r.allocator, &paths) catch unreachable;
}
}
if (result.paths.count() > 0 and (result.base_url_for_paths.len == 0 or !std.fs.path.isAbsolute(result.base_url_for_paths))) {
// this might leak
- var paths = [_]string{ file_dir, base };
- result.base_url_for_paths = std.fs.path.join(r.allocator, paths) catch unreachable;
+ const paths = [_]string{ file_dir, result.base_url.? };
+ result.base_url_for_paths = std.fs.path.join(r.allocator, &paths) catch unreachable;
}
return result;
@@ -416,7 +412,10 @@ pub const Resolver = struct {
}
pub fn parsePackageJSON(r: *Resolver, file: string) !?*PackageJSON {
- return try PackageJSON.parse(r, file);
+ const pkg = PackageJSON.parse(r, file) orelse return null;
+ var _pkg = try r.allocator.create(PackageJSON);
+ _pkg.* = pkg;
+ return _pkg;
}
pub fn isPackagePath(path: string) bool {
@@ -504,7 +503,7 @@ pub const Resolver = struct {
if (!strings.eqlComptime(base, "node_modules")) {
if (entries.get("node_modules")) |entry| {
// the catch might be wrong!
- info.has_node_modules = (entry.entry.kind(rfs) catch .file) == .dir;
+ info.has_node_modules = (entry.entry.kind(rfs)) == .dir;
}
}
@@ -514,19 +513,21 @@ pub const Resolver = struct {
// Make sure "absRealPath" is the real path of the directory (resolving any symlinks)
if (!r.opts.preserve_symlinks) {
- if (parent_info.entries.get(base)) |entry| {
+ if (parent_info.entries.get(base)) |lookup| {
+ const entry = lookup.entry;
+
var symlink = entry.symlink(rfs);
if (symlink.len > 0) {
- if (r.debug_logs) |logs| {
- try logs.addNote(std.fmt.allocPrint(r.allocator, "Resolved symlink \"{s}\" to \"{s}\"", .{ path, symlink }));
+ if (r.debug_logs) |*logs| {
+ try logs.addNote(std.fmt.allocPrint(r.allocator, "Resolved symlink \"{s}\" to \"{s}\"", .{ path, symlink }) catch unreachable);
}
info.abs_real_path = symlink;
} else if (parent_info.abs_real_path.len > 0) {
// this might leak a little i'm not sure
const parts = [_]string{ parent_info.abs_real_path, base };
- symlink = std.fs.path.join(r.allocator, &parts);
- if (r.debug_logs) |logs| {
- try logs.addNote(std.fmt.allocPrint(r.allocator, "Resolved symlink \"{s}\" to \"{s}\"", .{ path, symlink }));
+ symlink = std.fs.path.join(r.allocator, &parts) catch unreachable;
+ if (r.debug_logs) |*logs| {
+ try logs.addNote(std.fmt.allocPrint(r.allocator, "Resolved symlink \"{s}\" to \"{s}\"", .{ path, symlink }) catch unreachable);
}
info.abs_real_path = symlink;
}
@@ -535,19 +536,20 @@ pub const Resolver = struct {
}
// Record if this directory has a package.json file
- if (entries.get("package.json")) |entry| {
+ if (entries.get("package.json")) |lookup| {
+ const entry = lookup.entry;
if (entry.kind(rfs) == .file) {
- info.package_json = r.parsePackageJSON(path);
+ info.package_json = r.parsePackageJSON(path) catch null;
if (info.package_json) |pkg| {
- if (pkg.browser_map != null) {
+ if (pkg.browser_map.count() > 0) {
info.enclosing_browser_scope = info;
}
- if (r.debug_logs) |logs| {
- try logs.addNote(std.fmt.allocPrint(r.allocator, "Resolved package.json in \"{s}\"", .{
+ if (r.debug_logs) |*logs| {
+ logs.addNoteFmt("Resolved package.json in \"{s}\"", .{
path,
- }));
+ }) catch unreachable;
}
}
}
@@ -557,14 +559,20 @@ pub const Resolver = struct {
{
var tsconfig_path: ?string = null;
if (r.opts.tsconfig_override == null) {
- var entry = entries.get("tsconfig.json");
- if (entry.kind(rfs) == .file) {
- const parts = [_]string{ path, "tsconfig.json" };
- tsconfig_path = try std.fs.path.join(r.allocator, parts);
- } else if (entries.get("jsconfig.json")) |jsconfig| {
- if (jsconfig.kind(rfs) == .file) {
- const parts = [_]string{ path, "jsconfig.json" };
- tsconfig_path = try std.fs.path.join(r.allocator, parts);
+ if (entries.get("tsconfig.json")) |lookup| {
+ const entry = lookup.entry;
+ if (entry.kind(rfs) == .file) {
+ const parts = [_]string{ path, "tsconfig.json" };
+ tsconfig_path = try std.fs.path.join(r.allocator, &parts);
+ }
+ }
+ if (tsconfig_path == null) {
+ if (entries.get("jsconfig.json")) |lookup| {
+ const entry = lookup.entry;
+ if (entry.kind(rfs) == .file) {
+ const parts = [_]string{ path, "jsconfig.json" };
+ tsconfig_path = try std.fs.path.join(r.allocator, &parts);
+ }
}
}
} else if (parent == null) {
@@ -574,20 +582,21 @@ pub const Resolver = struct {
if (tsconfig_path) |tsconfigpath| {
var visited = std.StringHashMap(bool).init(r.allocator);
defer visited.deinit();
- info.ts_config_json = r.parseTSConfig(tsconfigpath, visited) catch |err| {
+ info.tsconfig_json = r.parseTSConfig(tsconfigpath, &visited) catch |err| brk: {
const pretty = r.prettyPath(Path.init(tsconfigpath));
if (err == error.ENOENT) {
- r.log.addErrorFmt(null, logger.Loc.Empty, r.allocator, "Cannot find tsconfig file \"{s}\"", .{pretty});
+ r.log.addErrorFmt(null, logger.Loc.Empty, r.allocator, "Cannot find tsconfig file \"{s}\"", .{pretty}) catch unreachable;
} else if (err != error.ParseErrorAlreadyLogged) {
- r.log.addErrorFmt(null, logger.Loc.Empty, r.allocator, "Cannot read file \"{s}\": {s}", .{ pretty, @errorName(err) });
+ r.log.addErrorFmt(null, logger.Loc.Empty, r.allocator, "Cannot read file \"{s}\": {s}", .{ pretty, @errorName(err) }) catch unreachable;
}
+ break :brk null;
};
}
}
- if (info.ts_config_json == null and parent != null) {
- info.ts_config_json = parent.?.tsconfig_json;
+ if (info.tsconfig_json == null and parent != null) {
+ info.tsconfig_json = parent.?.tsconfig_json;
}
return info;
diff --git a/src/resolver/tsconfig_json.zig b/src/resolver/tsconfig_json.zig
index b4e027413..6c7992833 100644
--- a/src/resolver/tsconfig_json.zig
+++ b/src/resolver/tsconfig_json.zig
@@ -1,10 +1,10 @@
usingnamespace @import("../global.zig");
const std = @import("std");
const options = @import("../options.zig");
-const log = @import("../logger.zig");
-const cache = @import("../cache.zig");
const logger = @import("../logger.zig");
+const cache = @import("../cache.zig");
const js_ast = @import("../js_ast.zig");
+const js_lexer = @import("../js_lexer.zig");
const alloc = @import("../alloc.zig");
const PathsMap = std.StringHashMap([]string);
@@ -53,7 +53,6 @@ pub const TSConfigJSON = struct {
allocator: *std.mem.Allocator,
log: *logger.Log,
source: logger.Source,
- opts: options.TransformOptions,
json_cache: *cache.Cache.Json,
) anyerror!?*TSConfigJSON {
// Unfortunately "tsconfig.json" isn't actually JSON. It's some other
@@ -64,52 +63,52 @@ pub const TSConfigJSON = struct {
// these particular files. This is likely not a completely accurate
// emulation of what the TypeScript compiler does (e.g. string escape
// behavior may also be different).
- const json: js_ast.Expr = (json_cache.parseTSConfig(log, opts, source, allocator) catch null) orelse return null;
+ const json: js_ast.Expr = (json_cache.parseTSConfig(log, source, allocator) catch null) orelse return null;
var result: TSConfigJSON = TSConfigJSON{ .abs_path = source.key_path.text, .paths = PathsMap.init(allocator) };
errdefer allocator.free(result.paths);
- if (extends != null) {
- if (json.getProperty("extends")) |extends_value| {
- log.addWarning(&source, extends_value.loc, "\"extends\" is not implemented yet") catch unreachable;
- // if ((extends_value.expr.getString(allocator) catch null)) |str| {
- // if (extends(str, source.rangeOfString(extends_value.loc))) |base| {
- // result.jsx = base.jsx;
- // result.base_url_for_paths = base.base_url_for_paths;
- // result.use_define_for_class_fields = base.use_define_for_class_fields;
- // result.preserve_imports_not_used_as_values = base.preserve_imports_not_used_as_values;
- // // https://github.com/microsoft/TypeScript/issues/14527#issuecomment-284948808
- // result.paths = base.paths;
- // }
- // }
- }
+ if (json.getProperty("extends")) |extends_value| {
+ log.addWarning(&source, extends_value.loc, "\"extends\" is not implemented yet") catch unreachable;
+ // if ((extends_value.expr.getString(allocator) catch null)) |str| {
+ // if (extends(str, source.rangeOfString(extends_value.loc))) |base| {
+ // result.jsx = base.jsx;
+ // result.base_url_for_paths = base.base_url_for_paths;
+ // result.use_define_for_class_fields = base.use_define_for_class_fields;
+ // result.preserve_imports_not_used_as_values = base.preserve_imports_not_used_as_values;
+ // // https://github.com/microsoft/TypeScript/issues/14527#issuecomment-284948808
+ // result.paths = base.paths;
+ // }
+ // }
}
// Parse "compilerOptions"
if (json.getProperty("compilerOptions")) |compiler_opts| {
+ var has_base_url = false;
// Parse "baseUrl"
if (compiler_opts.expr.getProperty("baseUrl")) |base_url_prop| {
// maybe we should add a warning when it exists but the value is an array or osmething invalid?
- if ((base_url_prop.expr.getString(allocator) catch null)) |base_url| {
+ if ((base_url_prop.expr.getString(allocator))) |base_url| {
result.base_url = base_url;
+ has_base_url = true;
}
}
// Parse "jsxFactory"
if (compiler_opts.expr.getProperty("jsxFactory")) |jsx_prop| {
if (jsx_prop.expr.getString(allocator)) |str| {
- result.jsx.factory = try parseMemberExpressionForJSX(log, source, jsx_prop.loc, str, allocator);
+ result.jsx.factory = try parseMemberExpressionForJSX(log, &source, jsx_prop.loc, str, allocator);
}
}
// Parse "jsxFragmentFactory"
if (compiler_opts.expr.getProperty("jsxFactory")) |jsx_prop| {
if (jsx_prop.expr.getString(allocator)) |str| {
- result.jsx.fragment = try parseMemberExpressionForJSX(log, source, jsx_prop.loc, str, allocator);
+ result.jsx.fragment = try parseMemberExpressionForJSX(log, &source, jsx_prop.loc, str, allocator);
}
}
// Parse "jsxImportSource"
- if (compiler_opts.expr.getProperty("jsxImportSource")) |jsx_factory_prop| {
+ if (compiler_opts.expr.getProperty("jsxImportSource")) |jsx_prop| {
if (jsx_prop.expr.getString(allocator)) |str| {
result.jsx.import_source = str;
}
@@ -123,16 +122,16 @@ pub const TSConfigJSON = struct {
}
// Parse "importsNotUsedAsValues"
- if (compiler_opts.expr.getProperty("importsNotUsedAsValues")) |imports_not_used_as_values_prop| {
+ if (compiler_opts.expr.getProperty("importsNotUsedAsValues")) |jsx_prop| {
// This should never allocate since it will be utf8
- if ((jsx_prop.expr.getString(allocator) catch null)) |str| {
+ if ((jsx_prop.expr.getString(allocator))) |str| {
switch (ImportsNotUsedAsValue.List.get(str) orelse ImportsNotUsedAsValue.invalid) {
.preserve, .err => {
result.preserve_imports_not_used_as_values = true;
},
.remove => {},
else => {
- log.addRangeWarningFmt(source, source.rangeOfString(imports_not_used_as_values_prop.loc), allocator, "Invalid value \"{s}\" for \"importsNotUsedAsValues\"", .{str}) catch {};
+ log.addRangeWarningFmt(&source, source.rangeOfString(jsx_prop.loc), allocator, "Invalid value \"{s}\" for \"importsNotUsedAsValues\"", .{str}) catch {};
},
}
}
@@ -146,9 +145,9 @@ pub const TSConfigJSON = struct {
result.paths = PathsMap.init(allocator);
for (paths.properties) |property| {
const key_prop = property.key orelse continue;
- const key = (key_prop.getString(allocator) catch null) orelse continue;
+ const key = (key_prop.getString(allocator)) orelse continue;
- if (!TSConfigJSON.isValidTSConfigPathNoBaseURLPattern(key, log, source, key_prop.loc)) {
+ if (!TSConfigJSON.isValidTSConfigPathNoBaseURLPattern(key, log, &source, allocator, key_prop.loc)) {
continue;
}
@@ -178,20 +177,27 @@ pub const TSConfigJSON = struct {
switch (value_prop.data) {
.e_array => |array| {
if (array.items.len > 0) {
- var paths = allocator.alloc(string, array.items.len) catch unreachable;
- errdefer allocator.free(paths);
+ var values = allocator.alloc(string, array.items.len) catch unreachable;
+ errdefer allocator.free(values);
var count: usize = 0;
for (array.items) |expr| {
- if ((expr.getString(allocator) catch null)) |str| {
- if (TSConfigJSON.isValidTSConfigPathPattern(str, log, source, loc, allocator) and
+ if ((expr.getString(allocator))) |str| {
+ if (TSConfigJSON.isValidTSConfigPathPattern(
+ str,
+ log,
+ &source,
+ expr.loc,
+ allocator,
+ ) and
(has_base_url or
TSConfigJSON.isValidTSConfigPathNoBaseURLPattern(
str,
log,
- source,
- loc,
+ &source,
+ allocator,
+ expr.loc,
))) {
- paths[count] = str;
+ values[count] = str;
count += 1;
}
}
@@ -199,15 +205,15 @@ pub const TSConfigJSON = struct {
if (count > 0) {
result.paths.put(
key,
- paths[0..count],
+ values[0..count],
) catch unreachable;
}
}
},
else => {
log.addRangeWarningFmt(
- source,
- log,
+ &source,
+ source.rangeOfString(key_prop.loc),
allocator,
"Substitutions for pattern \"{s}\" should be an array",
.{key},
@@ -226,7 +232,7 @@ pub const TSConfigJSON = struct {
return _result;
}
- pub fn isValidTSConfigPathPattern(text: string, log: *logger.Log, source: *logger.Source, loc: logger.Loc, allocator: *std.mem.Allocator) bool {
+ pub fn isValidTSConfigPathPattern(text: string, log: *logger.Log, source: *const logger.Source, loc: logger.Loc, allocator: *std.mem.Allocator) bool {
var found_asterisk = false;
for (text) |c, i| {
if (c == '*') {
@@ -242,7 +248,7 @@ pub const TSConfigJSON = struct {
return true;
}
- pub fn parseMemberExpressionForJSX(log: *logger.Log, source: *logger.Source, loc: logger.Loc, text: string, allocator: *std.mem.Allocator) ![]string {
+ pub fn parseMemberExpressionForJSX(log: *logger.Log, source: *const logger.Source, loc: logger.Loc, text: string, allocator: *std.mem.Allocator) ![]string {
if (text.len == 0) {
return &([_]string{});
}
@@ -267,7 +273,7 @@ pub const TSConfigJSON = struct {
return c == '/' or c == '\\';
}
- pub fn isValidTSConfigPathNoBaseURLPattern(text: string, log: logger.Log, source: *logger.Source, loc: logger.Loc) bool {
+ pub fn isValidTSConfigPathNoBaseURLPattern(text: string, log: *logger.Log, source: *const logger.Source, allocator: *std.mem.Allocator, loc: logger.Loc) bool {
var c0: u8 = 0;
var c1: u8 = 0;
var c2: u8 = 0;