tree_sitter_ocaml/lib.rs
1//! This crate provides OCaml language support for the [tree-sitter][] parsing
2//! library. There are separate languages for implementation, (`.ml`),
3//! interfaces (`.mli`) and types.
4//!
5//! Typically, you will use [`LANGUAGE_OCAML`][LANGUAGE_OCAML] to add this language
6//! to a tree-sitter [`Parser`][Parser], and then use the parser to parse some code:
7//!
8//! ```
9//! let code = r#"
10//! module M = struct
11//! let x = 0
12//! end
13//! "#;
14//! let mut parser = tree_sitter::Parser::new();
15//! let language = tree_sitter_ocaml::LANGUAGE_OCAML;
16//! parser
17//! .set_language(&language.into())
18//! .expect("Error loading OCaml language");
19//! let tree = parser.parse(code, None).unwrap();
20//! assert!(!tree.root_node().has_error());
21//! ```
22//!
23//! Use [`LANGUAGE_OCAML_INTERFACE`][LANGUAGE_OCAML_INTERFACE] to parse interface
24//! files (with `.mli` extension) and [`LANGUAGE_OCAML_TYPE`][LANGUAGE_OCAML_TYPE]
25//! to parse type signatures.
26//!
27//! [LANGUAGE_OCAML]: constant.LANGUAGE_OCAML.html
28//! [LANGUAGE_OCAML_INTERFACE]: constant.LANGUAGE_OCAML_INTERFACE.html
29//! [LANGUAGE_OCAML_TYPE]: constant.LANGUAGE_OCAML_TYPE.html
30//! [Parser]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Parser.html
31//! [tree-sitter]: https://tree-sitter.github.io/
32
33use tree_sitter_language::LanguageFn;
34
35extern "C" {
36 fn tree_sitter_ocaml() -> *const ();
37 fn tree_sitter_ocaml_interface() -> *const ();
38 fn tree_sitter_ocaml_type() -> *const ();
39}
40
41/// The tree-sitter [`LanguageFn`][LanguageFn] for OCaml.
42///
43/// [LanguageFn]: https://docs.rs/tree-sitter-language/*/tree_sitter_language/struct.LanguageFn.html
44pub const LANGUAGE_OCAML: LanguageFn = unsafe { LanguageFn::from_raw(tree_sitter_ocaml) };
45
46/// The tree-sitter [`LanguageFn`] for OCaml interfaces.
47///
48/// [Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html
49pub const LANGUAGE_OCAML_INTERFACE: LanguageFn = unsafe { LanguageFn::from_raw(tree_sitter_ocaml_interface) };
50
51/// The tree-sitter [`LanguageFn`] for OCaml types.
52///
53/// [Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html
54pub const LANGUAGE_OCAML_TYPE: LanguageFn = unsafe { LanguageFn::from_raw(tree_sitter_ocaml_type) };
55
56/// The content of the [`node-types.json`][] file for OCaml.
57///
58/// [`node-types.json`]: https://tree-sitter.github.io/tree-sitter/using-parsers/6-static-node-types.html
59pub const OCAML_NODE_TYPES: &str = include_str!("../../grammars/ocaml/src/node-types.json");
60
61/// The content of the [`node-types.json`][] file for OCaml interfaces.
62///
63/// [`node-types.json`]: https://tree-sitter.github.io/tree-sitter/using-parsers/6-static-node-types.html
64pub const INTERFACE_NODE_TYPES: &str = include_str!("../../grammars/interface/src/node-types.json");
65
66/// The content of the [`node-types.json`][] file for OCaml types.
67///
68/// [`node-types.json`]: https://tree-sitter.github.io/tree-sitter/using-parsers/6-static-node-types.html
69pub const TYPE_NODE_TYPES: &str = include_str!("../../grammars/type/src/node-types.json");
70
71/// The syntax highlighting query for OCaml.
72pub const HIGHLIGHTS_QUERY: &str = include_str!("../../queries/highlights.scm");
73
74/// The local-variable syntax highlighting query for OCaml.
75pub const LOCALS_QUERY: &str = include_str!("../../queries/locals.scm");
76
77/// The symbol tagging query for OCaml.
78pub const TAGS_QUERY: &str = include_str!("../../queries/tags.scm");
79
80#[cfg(test)]
81mod tests {
82 #[test]
83 fn test_ocaml() {
84 let mut parser = tree_sitter::Parser::new();
85 parser
86 .set_language(&super::LANGUAGE_OCAML.into())
87 .expect("Error loading OCaml parser");
88
89 let code = r#"
90 module M = struct
91 let x = 0
92 end
93 "#;
94
95 let tree = parser.parse(code, None).unwrap();
96 let root = tree.root_node();
97 assert!(!root.has_error());
98 }
99
100 #[test]
101 fn test_ocaml_interface() {
102 let mut parser = tree_sitter::Parser::new();
103 parser
104 .set_language(&super::LANGUAGE_OCAML_INTERFACE.into())
105 .expect("Error loading OCaml interface parser");
106
107 let code = r#"
108 module M : sig
109 val x : int
110 end
111 "#;
112
113 let tree = parser.parse(code, None).unwrap();
114 let root = tree.root_node();
115 assert!(!root.has_error());
116 }
117
118 #[test]
119 fn test_ocaml_type() {
120 let mut parser = tree_sitter::Parser::new();
121 parser
122 .set_language(&super::LANGUAGE_OCAML_TYPE.into())
123 .expect("Error loading OCaml type parser");
124
125 let code = r#"int list"#;
126
127 let tree = parser.parse(code, None).unwrap();
128 let root = tree.root_node();
129 assert!(!root.has_error());
130 }
131}