Skip to main content

tree_sitter_javascript/
lib.rs

1//! This crate provides JavaScript language support for the [tree-sitter] parsing library.
2//!
3//! Typically, you will use the [`LANGUAGE`] constant to add this language to a
4//! tree-sitter [`Parser`], and then use the parser to parse some code:
5//!
6//! ```
7//! let code = "const App = () => <p>Hello</p>;\n";
8//! let mut parser = tree_sitter::Parser::new();
9//! let language = tree_sitter_javascript::LANGUAGE;
10//! parser
11//!     .set_language(&language.into())
12//!     .expect("Error loading JavaScript parser");
13//! let tree = parser.parse(code, None).unwrap();
14//! assert!(!tree.root_node().has_error());
15//! ```
16//!
17//! [`Parser`]: https://docs.rs/willbooster-tree-sitter/7/tree_sitter/struct.Parser.html
18//! [tree-sitter]: https://tree-sitter.github.io/
19
20use tree_sitter_language::LanguageFn;
21
22unsafe extern "C" {
23    fn tree_sitter_javascript() -> *const ();
24    fn tree_sitter_javascript_script() -> *const ();
25}
26
27/// The tree-sitter [`LanguageFn`] for this grammar.
28pub const LANGUAGE: LanguageFn = unsafe { LanguageFn::from_raw(tree_sitter_javascript) };
29
30/// Parses the ECMAScript Script goal, where top-level `await` is an identifier.
31pub const LANGUAGE_SCRIPT: LanguageFn =
32    unsafe { LanguageFn::from_raw(tree_sitter_javascript_script) };
33
34/// The content of the [`node-types.json`] file for this grammar.
35///
36/// [`node-types.json`]: https://tree-sitter.github.io/tree-sitter/using-parsers/6-static-node-types
37pub const NODE_TYPES: &str = include_str!("../../src/node-types.json");
38
39#[cfg(test)]
40mod tests {
41    #[test]
42    fn parses_await_with_the_selected_source_goal() {
43        let source = "await\nvalue; async function f(){ await operand; } await(next);";
44        for (language, expected) in [(super::LANGUAGE, 3), (super::LANGUAGE_SCRIPT, 1)] {
45            let mut parser = tree_sitter::Parser::new();
46            parser.set_language(&language.into()).unwrap();
47            let tree = parser.parse(source, None).unwrap();
48            assert!(!tree.root_node().has_error());
49            let awaits = tree
50                .root_node()
51                .to_sexp()
52                .matches("(await_expression ")
53                .count();
54            assert_eq!(awaits, expected);
55        }
56    }
57
58    #[test]
59    fn parses_top_level_yield_as_a_script_identifier() {
60        let mut parser = tree_sitter::Parser::new();
61        parser.set_language(&super::LANGUAGE_SCRIPT.into()).unwrap();
62        let tree = parser
63            .parse(
64                "yield / divisor / g; function* f(){ yield /value/g; }",
65                None,
66            )
67            .unwrap();
68        assert!(!tree.root_node().has_error());
69        let printed = tree.root_node().to_sexp();
70        assert_eq!(printed.matches("(yield_expression ").count(), 1);
71        assert_eq!(printed.matches("(binary_expression ").count(), 2);
72    }
73}