1mod parser;
2mod syntax_kind;
3mod syntax_node;
4
5use js_sys::{Array, Object, Reflect};
6use syntax_node::SyntaxNode;
7use wasm_bindgen::{prelude::wasm_bindgen, JsValue};
8
9use syntax_kind::SyntaxKind;
10
11#[wasm_bindgen]
12pub fn get_parse_tree(input: &str) -> JsValue {
13 let root = SyntaxNode::new_root(parser::parse_text(input));
14 build_js_tree(&root)
15}
16
17fn build_js_tree(node: &SyntaxNode) -> JsValue {
18 let obj = Object::new();
19 Reflect::set(
20 &obj,
21 &JsValue::from_str("kind"),
22 &JsValue::from_str(&format!("{:?}", node.kind())),
23 )
24 .unwrap();
25 Reflect::set(&obj, &JsValue::from_str("type"), &JsValue::from_str("node")).unwrap();
26 let children = Array::from_iter(node.children_with_tokens().filter_map(|child| match child {
27 rowan::NodeOrToken::Node(node) => Some(build_js_tree(&node)),
28 rowan::NodeOrToken::Token(token) if token.kind() != SyntaxKind::WHITESPACE => {
29 let token_obj = Object::new();
30 Reflect::set(
31 &token_obj,
32 &JsValue::from_str("kind"),
33 &JsValue::from_str(&format!("{:?}", token.kind())),
34 )
35 .unwrap();
36 Reflect::set(
37 &token_obj,
38 &JsValue::from_str("type"),
39 &JsValue::from_str("token"),
40 )
41 .unwrap();
42 Reflect::set(
43 &token_obj,
44 &JsValue::from_str("text"),
45 &JsValue::from_str(token.text()),
46 )
47 .unwrap();
48 Some(token_obj.into())
49 }
50 _ => None,
51 }));
52 Reflect::set(&obj, &JsValue::from_str("children"), &children.into()).unwrap();
53 obj.into()
54}