1use std::io;
6
7use js_sys::Function;
8use serde_wasm_bindgen::to_value;
9use wasm_bindgen::prelude::*;
10
11use crate::analyzer;
12
13#[wasm_bindgen]
14pub struct Analyzer {
15 analyzer: analyzer::Analyzer,
16}
17
18#[wasm_bindgen]
19impl Analyzer {
20 pub fn new() -> Analyzer {
21 Analyzer {
22 analyzer: analyzer::Analyzer::new(),
23 }
24 }
25
26 pub fn sync_document(&mut self, path: &str, content: &str) {
27 self.analyzer.sync_document(path, content);
28 }
29
30 pub fn remove_document(&mut self, path: &str) {
31 self.analyzer.remove_document(path);
32 }
33
34 pub fn errors(&self) -> JsValue {
35 let errors = self.analyzer.errors();
36 to_value(errors).unwrap_or_default()
37 }
38
39 pub fn semantic_tokens(&self, path: &str) -> Option<Vec<u32>> {
40 self.analyzer.semantic_tokens(path).cloned()
41 }
42
43 pub fn semantic_token_types(&self) -> Vec<String> {
44 self.analyzer.semantic_token_types()
45 }
46
47 pub fn semantic_token_modifiers(&self) -> Vec<String> {
48 self.analyzer.semantic_token_modifiers()
49 }
50
51 pub fn definition(&self, path: &str, line: u32, column: u32) -> JsValue {
52 let pos = analyzer::base::Position { line, column };
53
54 match self.analyzer.definition(path, pos) {
55 Some(loc) => to_value(&loc).unwrap_or_default(),
56 None => JsValue::null(),
57 }
58 }
59
60 pub fn types_for_completion(&self, path: &str, line: u32, column: u32) -> JsValue {
61 let pos = analyzer::base::Position { line, column };
62 let completions = self.analyzer.types_for_completion(path, pos);
63 to_value(&completions).unwrap_or_default()
64 }
65
66 pub fn includes_for_completion(&self, path: &str, line: u32, column: u32) -> JsValue {
67 let pos = analyzer::base::Position { line, column };
68 let completions = self.analyzer.includes_for_completion(path, pos);
69 to_value(&completions).unwrap_or_default()
70 }
71
72 pub fn keywords_for_completion(&self) -> JsValue {
73 let completions = self.analyzer.keywords_for_completion();
74 to_value(&completions).unwrap_or_default()
75 }
76
77 pub fn set_wasm_read_file(&mut self, read_file: Function) {
78 self.analyzer.wasm_read_file = Some(Box::new(move |path: String| -> io::Result<String> {
79 let args = js_sys::Array::new();
80 args.push(&path.into());
81 let result = read_file.apply(&JsValue::null(), &args).unwrap_or_default();
82 let content =
83 js_sys::Reflect::get(&result, &JsValue::from_str("content")).unwrap_or_default();
84 let error = js_sys::Reflect::get(&result, &JsValue::from_str("error"))
85 .unwrap_or_default()
86 .as_string()
87 .unwrap_or_default();
88 if error.len() > 0 {
89 return Err(io::Error::new(io::ErrorKind::Other, error));
90 }
91
92 let result = content.as_string().unwrap_or_default();
93 Ok(result)
94 }));
95 }
96}