ll_sparql_parser/
lib.rs

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