type_sitter_proc/
lib.rs

1#![doc = include_str!("../README.md")]
2
3use crate::generate_queries_args::GenerateQueriesArgs;
4use generate_nodes_args::GenerateNodesArgs;
5use syn::parse_macro_input;
6
7mod generate_nodes_args;
8mod generate_queries_args;
9
10/// Generate typed AST node wrappers.
11///
12/// # Parameters
13/// - `0`: Path to the `node-types.json` file of the language, relative to the crate root.
14///
15/// # Note
16///
17/// If you included the tree-sitter language as a dependency that is downloaded from the internet,
18/// you need to vendor it or at least vendor its `node-types.json`, because this macro needs its
19/// path and I don't know how to get it from the crate.
20///
21/// # Example
22///
23/// ```ignore
24/// # Doc tests give hygiene errors, so instead we use crate `type-sitter` to test these
25/// use type_sitter_proc::generate_nodes;
26///
27/// generate_nodes!("vendor/tree-sitter-json/src/node-types.json");
28/// ```
29#[proc_macro]
30pub fn generate_nodes(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
31    let args = parse_macro_input!(item as GenerateNodesArgs);
32    type_sitter_gen::generate_nodes(args.path.as_path())
33        .map(|g| g.collapse())
34        .unwrap_or_else(|err| err.to_compile_error())
35        .into()
36}
37
38/// Generate typed wrappers for tree-sitter queries.
39///
40/// # Parameters
41/// - `0`: Path to the queries, relative to the crate root. Must point to a `.scm` or directory of
42///   `.scm` files. If a directory, this function will generate submodules for each `.scm`.
43/// - `1`: the path to the tree-sitter language root, relative to the crate root. Typically
44///   `vendor/tree-sitter-<language>`.
45/// - `2`: Path to the crate with the typed node wrappers. Typically `super::nodes` (and then put an
46///   invocation of [`generate_nodes!`] at top-level in the sister crate `nodes.rs`).
47///
48/// # Example
49///
50/// ```ignore
51/// # Doc tests give hygiene errors, so instead we use crate `type-sitter` to test these
52/// use type_sitter_proc::generate_queries;
53///
54/// generate_queries!("vendor/tree-sitter-typescript/queries/tags.scm", "vendor/tree-sitter-typescript", super::typescript_nodes);
55/// generate_queries!("vendor/tree-sitter-rust/queries", "vendor/tree-sitter-rust", super::rust_nodes);
56/// ```
57#[proc_macro]
58pub fn generate_queries(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
59    let args = parse_macro_input!(item as GenerateQueriesArgs);
60    type_sitter_gen::generate_queries(
61        &args.path,
62        &args.language_path,
63        &args.nodes,
64        use_yak_sitter(),
65    )
66    .map(|g| g.collapse(&args.nodes))
67    .unwrap_or_else(|err| err.to_compile_error())
68    .into()
69}
70
71#[cfg(feature = "yak-sitter")]
72fn use_yak_sitter() -> bool {
73    true
74}
75
76#[cfg(not(feature = "yak-sitter"))]
77fn use_yak_sitter() -> bool {
78    false
79}