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