diff --git a/.gitignore b/.gitignore index 5211f11..29751ba 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /.zig-cache/ +/zig-pkg/ diff --git a/build.zig b/build.zig index 245c497..8b5ad53 100644 --- a/build.zig +++ b/build.zig @@ -34,7 +34,7 @@ pub fn build(b: *std.Build) void { ts_bin_query_gen.use_llvm = value; ts_bin_query_gen.use_lld = value; } - ts_bin_query_gen.linkLibC(); + ts_bin_query_gen.root_module.link_libc = true; ts_bin_query_gen.root_module.addImport("cbor", cbor_dep.module("cbor")); ts_bin_query_gen.root_module.addImport("treez", tree_sitter_host_dep.module("treez")); ts_bin_query_gen.root_module.addImport("build_options", options_mod); @@ -182,11 +182,29 @@ pub fn build(b: *std.Build) void { }, }); + const tests = b.addTest(.{ + .root_module = b.createModule(.{ + .root_source_file = b.path("src/syntax.zig"), + .target = target, + .optimize = optimize, + .imports = &.{ + .{ .name = "build_options", .module = options_mod }, + .{ .name = "cbor", .module = cbor_dep.module("cbor") }, + .{ .name = "treez", .module = tree_sitter_dep.module("treez") }, + }, + }), + }); + if (use_tree_sitter) { const ts_bin_query_gen_step = b.addRunArtifact(ts_bin_query_gen); const output = ts_bin_query_gen_step.addOutputFileArg("bin_queries.cbor"); syntax_mod.addAnonymousImport("syntax_bin_queries", .{ .root_source_file = output }); + tests.root_module.addAnonymousImport("syntax_bin_queries", .{ .root_source_file = output }); } + + const test_run_cmd = b.addRunArtifact(tests); + const test_step = b.step("test", "Run unit tests"); + test_step.dependOn(&test_run_cmd.step); } fn ts_queryfile(b: *std.Build, dep: *std.Build.Dependency, bin_gen: *std.Build.Step.Compile, comptime sub_path: []const u8) void { diff --git a/build.zig.zon b/build.zig.zon index 3166aa2..5de39dc 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -2,16 +2,16 @@ .name = .flow_syntax, .version = "0.7.2", .fingerprint = 0x3ba2584ea1cec85f, - .minimum_zig_version = "0.15.2", + .minimum_zig_version = "0.16.0-dev.3133+5ec8e45f3", .dependencies = .{ .tree_sitter = .{ - .url = "https://github.com/neurocyte/tree-sitter/releases/download/master-9327512f8d36343bb3adfa6fb982b0b467ddce91/source.tar.gz", - .hash = "tree_sitter-0.26.7-z0LhyJOPZzF4S6ZW6MrFTfJgiM9Fp81hqKrXUKSBaUAc", + .url = "https://github.com/neurocyte/tree-sitter/releases/download/master-70dbb6fa9d998bcf599c3aaeecac7479e9ee3f0c/source.tar.gz", + .hash = "tree_sitter-0.26.7-z0LhyGSQZzENNbCzqsMPu63xwpZI1WTHcf62imt-H6YL", }, .cbor = .{ - .url = "git+https://github.com/neurocyte/cbor?ref=master#7d2eeb68c8a2fb3f4d6baad6cc04c521b92974c0", - .hash = "cbor-1.0.0-RcQE_AswAQAPlqBCZXYQf9DZXn-0Ubt8Mk03ZcJWcsAG", + .url = "git+https://github.com/neurocyte/cbor?ref=master#66c28df31b8e4448dac7edf063417f2234d6f3c9", + .hash = "cbor-1.1.0-RcQE_DZMAQBg77bTLWHEMF7QSF2lWUudUbarD9xC5yVJ", }, }, .paths = .{ diff --git a/src/QueryCache.zig b/src/QueryCache.zig index 24f6436..1a59d7e 100644 --- a/src/QueryCache.zig +++ b/src/QueryCache.zig @@ -12,15 +12,16 @@ pub const tss = @import("ts_serializer.zig"); pub const FileType = @import("file_type.zig"); const Query = treez.Query; +io: std.Io, allocator: std.mem.Allocator, -mutex: ?std.Thread.Mutex, +mutex: ?std.Io.Mutex, highlights: std.StringHashMapUnmanaged(*CacheEntry) = .{}, injections: std.StringHashMapUnmanaged(*CacheEntry) = .{}, errors: std.StringHashMapUnmanaged(*CacheEntry) = .{}, ref_count: usize = 1, const CacheEntry = struct { - mutex: ?std.Thread.Mutex, + mutex: ?std.Io.Mutex, query: ?*Query, query_arena: ?*std.heap.ArenaAllocator, query_type: QueryType, @@ -60,12 +61,13 @@ const CacheError = error{ pub const Error = CacheError || QueryParseError || QuerySerializeError; -pub fn create(allocator: std.mem.Allocator, opts: struct { lock: bool = false }) !*Self { +pub fn create(io: std.Io, allocator: std.mem.Allocator, opts: struct { lock: bool = false }) !*Self { const self = try allocator.create(Self); errdefer allocator.destroy(self); self.* = .{ + .io = io, .allocator = allocator, - .mutex = if (opts.lock) .{} else null, + .mutex = if (opts.lock) .init else null, }; return self; } @@ -81,8 +83,8 @@ fn add_ref_locked(self: *Self) void { fn release_ref_unlocked_and_maybe_destroy(self: *Self) void { { - if (self.mutex) |*mtx| mtx.lock(); - defer if (self.mutex) |*mtx| mtx.unlock(); + if (self.mutex) |*mtx| mtx.lockUncancelable(self.io); + defer if (self.mutex) |*mtx| mtx.unlock(self.io); self.ref_count -= 1; if (self.ref_count > 0) return; } @@ -104,8 +106,8 @@ fn release_cache_entry_hash_map(allocator: std.mem.Allocator, hash_map: *std.Str } fn get_cache_entry(self: *Self, file_type: FileType, comptime query_type: QueryType) CacheError!*CacheEntry { - if (self.mutex) |*mtx| mtx.lock(); - defer if (self.mutex) |*mtx| mtx.unlock(); + if (self.mutex) |*mtx| mtx.lockUncancelable(self.io); + defer if (self.mutex) |*mtx| mtx.unlock(self.io); const hash = switch (query_type) { .highlights => &self.highlights, @@ -120,7 +122,7 @@ fn get_cache_entry(self: *Self, file_type: FileType, comptime query_type: QueryT q.* = .{ .query = null, .query_arena = null, - .mutex = if (self.mutex) |_| .{} else null, + .mutex = if (self.mutex) |_| .init else null, .lang_fn = file_type.lang_fn, .file_type_name = file_type.name, .query_type = query_type, @@ -132,8 +134,8 @@ fn get_cache_entry(self: *Self, file_type: FileType, comptime query_type: QueryT } fn get_cached_query(self: *Self, entry: *CacheEntry) Error!?*Query { - if (entry.mutex) |*mtx| mtx.lock(); - defer if (entry.mutex) |*mtx| mtx.unlock(); + if (entry.mutex) |*mtx| mtx.lockUncancelable(self.io); + defer if (entry.mutex) |*mtx| mtx.unlock(self.io); return if (entry.query) |query| query else blk: { const lang = entry.lang_fn() orelse std.debug.panic("tree-sitter parser function failed for language: {s}", .{entry.file_type_name}); @@ -173,7 +175,7 @@ pub fn get(self: *Self, file_type: FileType, comptime query_type: QueryType) Err const query = try self.get_cached_query(try self.get_cache_entry(file_type, query_type)); self.add_ref_locked(); return switch (@typeInfo(ReturnType(query_type))) { - .optional => |_| query, + .optional => query, else => query.?, }; } diff --git a/src/syntax.zig b/src/syntax.zig index 455a278..83636a2 100644 --- a/src/syntax.zig +++ b/src/syntax.zig @@ -27,7 +27,7 @@ query: *Query, errors_query: *Query, injections: ?*Query, tree: ?*treez.Tree = null, -injection_list: std.ArrayListUnmanaged(Injection) = .{}, +injection_list: std.ArrayList(Injection) = .empty, content: ?[]u8 = null, pub const Injection = struct { @@ -482,3 +482,11 @@ pub fn count_error_nodes(self: *const Self) usize { }; return error_count; } + +test "simple build and link test" { + const zig_file_type = @import("file_type.zig").get_by_name_static("zig") orelse return error.TestFailed; + const query_cache = try QueryCache.create(std.testing.io, std.testing.allocator, .{}); + defer query_cache.deinit(); + const syntax = try create(zig_file_type, std.testing.allocator, query_cache); + _ = syntax; +} diff --git a/src/ts_bin_query_gen.zig b/src/ts_bin_query_gen.zig index a265abe..97d9e08 100644 --- a/src/ts_bin_query_gen.zig +++ b/src/ts_bin_query_gen.zig @@ -6,24 +6,24 @@ pub const tss = @import("ts_serializer.zig"); const verbose = false; -pub fn main() anyerror!void { +pub fn main(init: std.process.Init) anyerror!void { + const io = init.io; const allocator = std.heap.c_allocator; - const args = try std.process.argsAlloc(allocator); var opt_output_file_path: ?[]const u8 = null; - var i: usize = 1; - while (i < args.len) : (i += 1) { - const arg = args[i]; + var args = init.minimal.args.iterate(); + _ = args.next(); + while (args.next()) |arg| { if (opt_output_file_path != null) fatal("duplicated {s} argument", .{arg}); - opt_output_file_path = args[i]; + opt_output_file_path = arg; } const output_file_path = opt_output_file_path orelse fatal("missing output file", .{}); - var output_file = std.fs.cwd().createFile(output_file_path, .{}) catch |err| { + var output_file = std.Io.Dir.cwd().createFile(io, output_file_path, .{}) catch |err| { fatal("unable to open '{s}': {s}", .{ output_file_path, @errorName(err) }); }; - defer output_file.close(); + defer output_file.close(io); var output = std.Io.Writer.Allocating.init(allocator); const writer = &output.writer; @@ -93,7 +93,7 @@ pub fn main() anyerror!void { } } - try output_file.writeAll(output.written()); + try output_file.writeStreamingAll(io, output.written()); if (verbose) std.log.info("file_types total {d} bytes", .{output.written().len}); }