Files
carbon-lang/utils/tree_sitter/BUILD
T
Jon Ross-Perkins 6f6e46ef57 Migrate tree-sitter support to MODULE.bazel (#4783)
The WORKSPACE file is deprecated; support is already off by default, and
it'll be removed in the next major bazel release. Our main dependency is
tree-sitter, and I'm trying to address that here.

We're currently using https://github.com/elliottt/rules_tree_sitter, but
that hasn't been updated in a couple years, meaning it lacks
MODULE.bazel support. In the registry, there's
https://registry.bazel.build/modules/tree-sitter-bazel, but this is only
the *parser* libraries of tree-sitter, not the *generator*. I'm using it
for that much, at least.

For the *generator*, which transforms grammar.js to parser.c/h, I'm just
requiring a non-hermetic invocation (i.e., people who want to work on it
will need to install tree-sitter; see the README.md updates). I tried
running it manually, but parser.c is about 600 KB; pre-commit rejects
files that large and I don't think an exception makes sense to override
for this (it'd probably also grow substantially if the grammar were
updated to cover more syntax). In order to make the non-hermetic call
not break "bazel build //..." for most developers, I'm marking most
targets in the package as manual.

Note, I did look long and hard at using `aspect_rules_js`/`rules_nodejs`
to invoke npm. This took a lot of time, and I have a commit that's
mostly working, except I hit a point where it uses `declare_symlink`
which we disallow for compatibility reasons (commit "Lots of work for
figuring out rule_js uses declare_symlink" on the PR). As a consequence,
I think we can't use the primary supported ways to have hermetic npm
calls.

Also, `treesitter` -> `tree_sitter` because it's generally called
`tree-sitter`, two words. We even had a `treesitter/src/tree_sitter`
directory so it's a bit inconsistent.

As far as bugs here, the parser library breaks bazel queries, e.g. the
error:
```
ERROR: Evaluation of query "somepath(//..., @llvm-project//third-party/unittest:gtest)" failed: preloading transitive closure failed: no such package '@@[unknown repo 'platforms' requested from @@tree-sitter-bazel+]//': The repository '@@[unknown repo 'platforms' requested from @@tree-sitter-bazel+]' could not be resolved: No repository visible as '@platforms' from repository '@@tree-sitter-bazel+'
```

I'm just excluding tree_sitter from queries where I can to work around
the error.
2025-01-13 19:04:10 +00:00

119 lines
3.0 KiB
Python

# Part of the Carbon Language project, under the Apache License v2.0 with LLVM
# Exceptions. See /LICENSE for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_test")
package(default_visibility = ["//bazel/check_deps:__pkg__"])
# See README.md for instructions on tree-sitter setup and use. These rules are
# manual because the tree-sitter invocation is non-hermetic, and most developers
# won't have it installed; we don't want to break "bazel test //..." if we can
# avoid it.
#
# We use tree-sitter non-hermetically for two key reasons:
#
# - The main way of hermetically using npms in bazel, `aspect_rules_js`, uses
# declare_symlink; we disallow that for important compatibility reasons.
# - When generated, src/parser.c is over 500 KB, which is larger than we want to
# check in. It should also be expected to grow if the grammar becomes more complete.
# Convenience target for running all tests, including manual tests.
test_suite(
name = "tests",
tags = ["manual"],
tests = [
":explorer_tests",
":string_fail_tests",
":string_tests",
],
)
# Call tree-sitter to generate parser files.
genrule(
name = "parser_files",
srcs = ["grammar.js"],
outs = [
"src/parser.c",
"src/tree_sitter/parser.h",
],
cmd = "tree-sitter generate $(location grammar.js) &&\n" +
"cp src/parser.c $(location src/parser.c) &&\n" +
"cp src/tree_sitter/parser.h $(location src/tree_sitter/parser.h)",
tags = ["manual"],
)
cc_library(
name = "parser",
srcs = [
"src/scanner.c",
":src/parser.c",
],
hdrs = [":src/tree_sitter/parser.h"],
copts = ["-Wno-missing-prototypes"],
tags = ["manual"],
deps = ["@tree-sitter-bazel//:tree-sitter"],
)
cc_binary(
name = "test_runner",
testonly = 1,
srcs = ["test_runner.cpp"],
tags = ["manual"],
deps = [
":parser",
],
)
cc_test(
name = "explorer_tests",
size = "small",
srcs = ["test_runner.cpp"],
args = ["$(locations //explorer:tree_sitter_testdata)"],
data = ["//explorer:tree_sitter_testdata"],
tags = ["manual"],
deps = [
":parser",
],
)
filegroup(
name = "string_testdata",
srcs = glob(
["testdata/string/*.carbon"],
exclude = ["testdata/string/fail_*.carbon"],
),
)
filegroup(
name = "string_fail_testdata",
srcs = glob(["testdata/string/fail_*.carbon"]),
)
cc_test(
name = "string_tests",
size = "small",
srcs = ["test_runner.cpp"],
args = ["$(locations :string_testdata)"],
data = [":string_testdata"],
tags = ["manual"],
deps = [
":parser",
],
)
cc_test(
name = "string_fail_tests",
size = "small",
srcs = ["test_runner.cpp"],
args = ["$(locations :string_fail_testdata)"],
data = [":string_fail_testdata"],
env = {
"FAIL_TESTS": "1",
},
tags = ["manual"],
deps = [
":parser",
],
)