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