Skip to content

Commit eed662d

Browse files
committed
fix(bindings): correct Zig bindings to expose a language function
Instead of having users declare the extern function themselves, they can pass in the language to `Language.create` in the zig bindings. If they really want, they can always opt into the `extern fn tree_sitter_LANG() *const ts.Language` approach.
1 parent 9ad096e commit eed662d

File tree

4 files changed

+61
-12
lines changed

4 files changed

+61
-12
lines changed

cli/src/init.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ const TESTS_SWIFT_TEMPLATE: &str = include_str!("./templates/tests.swift");
9797

9898
const BUILD_ZIG_TEMPLATE: &str = include_str!("./templates/build.zig");
9999
const BUILD_ZIG_ZON_TEMPLATE: &str = include_str!("./templates/build.zig.zon");
100+
const ROOT_ZIG_TEMPLATE: &str = include_str!("./templates/root.zig");
100101

101102
const TREE_SITTER_JSON_SCHEMA: &str =
102103
"https://tree-sitter.github.io/tree-sitter/assets/schemas/config.schema.json";
@@ -700,6 +701,14 @@ pub fn generate_grammar_files(
700701
missing_path(repo_path.join("build.zig.zon"), |path| {
701702
generate_file(path, BUILD_ZIG_ZON_TEMPLATE, language_name, &generate_opts)
702703
})?;
704+
705+
missing_path(bindings_dir.join("zig"), create_dir)?.apply(|path| {
706+
missing_path(path.join("root.zig"), |path| {
707+
generate_file(path, ROOT_ZIG_TEMPLATE, language_name, &generate_opts)
708+
})?;
709+
710+
Ok(())
711+
})?;
703712
}
704713

705714
Ok(())

cli/src/templates/build.zig

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,20 +39,38 @@ pub fn build(b: *std.Build) !void {
3939
}
4040

4141
lib.addIncludePath(b.path("src"));
42-
lib.installHeadersDirectory(b.path("bindings/c"), ".", .{});
4342

4443
b.installArtifact(lib);
4544
b.installFile("src/node-types.json", "node-types.json");
46-
b.installDirectory(.{
47-
.source_dir = b.path("queries"),
48-
.install_dir = .prefix,
49-
.install_subdir = "queries",
50-
.include_extensions = &.{"scm"}
45+
b.installDirectory(.{ .source_dir = b.path("queries"), .install_dir = .prefix, .install_subdir = "queries", .include_extensions = &.{"scm"} });
46+
47+
const module = b.addModule("tree-sitter-PARSER_NAME", .{
48+
.root_source_file = b.path("bindings/zig/root.zig"),
49+
.target = target,
50+
.optimize = optimize,
51+
});
52+
module.linkLibrary(lib);
53+
54+
const ts_dep = b.dependency("tree-sitter", .{});
55+
const ts_mod = ts_dep.module("tree-sitter");
56+
module.addImport("tree-sitter", ts_mod);
57+
58+
// ╭─────────────────╮
59+
// │ Tests │
60+
// ╰─────────────────╯
61+
62+
const tests = b.addTest(.{
63+
.root_source_file = b.path("bindings/zig/root.zig"),
64+
.target = target,
65+
.optimize = optimize,
5166
});
67+
tests.linkLibrary(lib);
68+
tests.root_module.addImport("tree-sitter", ts_mod);
69+
70+
const run_tests = b.addRunArtifact(tests);
5271

53-
const test_cmd = b.addSystemCommand(&.{"tree-sitter", "test"});
54-
const test_step = b.step("test", "Run parser tests");
55-
test_step.dependOn(&test_cmd.step);
72+
const test_step = b.step("test", "Run unit tests");
73+
test_step.dependOn(&run_tests.step);
5674
}
5775

5876
inline fn hasScanner(dir: std.fs.Dir) bool {

cli/src/templates/build.zig.zon

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
.{
2-
.name = "tree_sitter_PARSER_NAME",
2+
.name = "tree-sitter-PARSER_NAME",
33
.version = "PARSER_VERSION",
4-
.dependencies = .{},
4+
.dependencies = .{ .@"tree-sitter" = .{
5+
.url = "https://github.com/tree-sitter/zig-tree-sitter/archive/refs/tags/v0.25.0.tar.gz",
6+
.hash = "12201a8d5e840678bbbf5128e605519c4024af422295d68e2ba2090e675328e5811d",
7+
} },
58
.paths = .{
69
"build.zig",
710
"build.zig.zon",
8-
"bindings/c",
11+
"bindings/zig",
912
"src",
1013
"queries",
1114
"LICENSE",

cli/src/templates/root.zig

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
const testing = @import("std").testing;
2+
3+
const ts = @import("tree-sitter");
4+
const Language = ts.Language;
5+
const Parser = ts.Parser;
6+
7+
pub extern fn tree_sitter_PARSER_NAME() callconv(.C) *const Language;
8+
9+
pub export fn language() *const Language {
10+
return tree_sitter_PARSER_NAME();
11+
}
12+
13+
test "can load grammar" {
14+
const parser = Parser.create();
15+
defer parser.destroy();
16+
try testing.expectEqual(parser.setLanguage(language()), void{});
17+
try testing.expectEqual(parser.getLanguage(), tree_sitter_PARSER_NAME());
18+
}
19+

0 commit comments

Comments
 (0)