mf_expression/intellisense/
mod.rs1use crate::arena::UnsafeArena;
2use crate::intellisense::scope::IntelliSenseScope;
3use crate::intellisense::types::provider::TypesProvider;
4use crate::lexer::Lexer;
5use crate::parser::{Node, Parser};
6use crate::variable::VariableType;
7use serde::Serialize;
8use std::cell::RefCell;
9
10mod scope;
11mod types;
12
13#[derive(Debug, Serialize)]
14#[serde(rename_all = "camelCase")]
15pub struct IntelliSenseToken {
16 pub span: (u32, u32),
17 pub kind: VariableType,
18 pub node_kind: &'static str,
19 pub error: Option<String>,
20}
21
22pub struct IntelliSense<'arena> {
23 arena: UnsafeArena<'arena>,
24 lexer: Lexer<'arena>,
25}
26
27impl<'arena> IntelliSense<'arena> {
28 pub fn new() -> Self {
29 Self { arena: UnsafeArena::new(), lexer: Lexer::new() }
30 }
31
32 pub fn type_check(
33 &mut self,
34 source: &'arena str,
35 data: &VariableType,
36 ) -> Option<Vec<IntelliSenseToken>> {
37 let arena = self.arena.get();
38
39 let tokens = self.lexer.tokenize(source).ok()?;
40 let parser =
41 Parser::try_new(tokens, &arena).map(|p| p.standard()).ok()?;
42
43 let parser_result = parser.with_metadata().parse();
44 let ast = parser_result.root;
45 let metadata = parser_result.metadata?;
46
47 let type_data = TypesProvider::generate(
48 ast,
49 IntelliSenseScope {
50 pointer_data: data.shallow_clone(),
51 root_data: data.shallow_clone(),
52 current_data: data.shallow_clone(),
53 },
54 );
55
56 let results = RefCell::new(Vec::new());
57 ast.walk(|node| {
58 let addr = node as *const Node as usize;
59 let mut r = results.borrow_mut();
60 let typ = type_data.get_type(node);
61
62 r.push(IntelliSenseToken {
63 span: node
64 .span()
65 .or_else(|| metadata.get(&addr).map(|s| s.span))
66 .unwrap_or_default(),
67 node_kind: node.into(),
68 error: typ.map(|t| t.error.clone()).flatten(),
69 kind: typ
70 .map(|t| t.kind.clone())
71 .unwrap_or_else(|| VariableType::Any),
72 });
73 });
74
75 self.arena.with_mut(|a| a.reset());
76 Some(results.into_inner())
77 }
78
79 pub fn type_check_unary(
80 &mut self,
81 source: &'arena str,
82 data: &VariableType,
83 ) -> Option<Vec<IntelliSenseToken>> {
84 let arena = self.arena.get();
85
86 let tokens = self.lexer.tokenize(source).ok()?;
87 let parser = Parser::try_new(tokens, &arena).map(|p| p.unary()).ok()?;
88
89 let parser_result = parser.with_metadata().parse();
90 let ast = parser_result.root;
91 let metadata = parser_result.metadata?;
92
93 let type_data = TypesProvider::generate(
94 ast,
95 IntelliSenseScope {
96 pointer_data: data.shallow_clone(),
97 root_data: data.shallow_clone(),
98 current_data: data.shallow_clone(),
99 },
100 );
101
102 let results = RefCell::new(Vec::new());
103 ast.walk(|node| {
104 let addr = node as *const Node as usize;
105 let mut r = results.borrow_mut();
106 let typ = type_data.get_type(node);
107
108 r.push(IntelliSenseToken {
109 span: metadata.get(&addr).map(|s| s.span).unwrap_or_default(),
110 node_kind: node.into(),
111 error: typ.map(|t| t.error.clone()).flatten(),
112 kind: typ
113 .map(|t| t.kind.clone())
114 .unwrap_or_else(|| VariableType::Any),
115 });
116 });
117
118 self.arena.with_mut(|a| a.reset());
119 Some(results.into_inner())
120 }
121}
122
123#[cfg(test)]
124mod tests {
125 use crate::intellisense::IntelliSense;
126 use crate::variable::VariableType;
127 use serde_json::json;
128
129 #[test]
130 fn sample_test() {
131 let mut is = IntelliSense::new();
132
133 let data = json!({ "customer": { "firstName": "John", "lastName": "Doe", "array": [{"a": 5}, {"a": 6}] } });
134 let data_type: VariableType = data.into();
135
136 let typ = is.type_check("customer.array[0]", &data_type);
137 println!("{:?}", typ);
138 }
139
140 #[test]
141 fn sample_test_unary() {
142 let mut is = IntelliSense::new();
143
144 let data = json!({ "customer": { "firstName": "John", "lastName": "Doe" }, "$": 10});
145 let data_type: VariableType = data.into();
146
147 let typ = is.type_check_unary("> 10", &data_type);
148 println!("{typ:?}");
149 }
150}