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