emmylua_code_analysis/db_index/operators/
mod.rs1mod lua_operator;
2mod lua_operator_meta_method;
3
4use std::collections::HashMap;
5
6use crate::FileId;
7
8use super::traits::LuaIndex;
9pub use lua_operator::{LuaOperator, LuaOperatorId, LuaOperatorOwner, OperatorFunction};
10pub use lua_operator_meta_method::LuaOperatorMetaMethod;
11
12#[derive(Debug)]
13pub struct LuaOperatorIndex {
14 operators: HashMap<LuaOperatorId, LuaOperator>,
15 type_operators_map:
16 HashMap<LuaOperatorOwner, HashMap<LuaOperatorMetaMethod, Vec<LuaOperatorId>>>,
17 in_filed_operator_map: HashMap<FileId, Vec<LuaOperatorId>>,
18}
19
20impl LuaOperatorIndex {
21 pub fn new() -> Self {
22 Self {
23 operators: HashMap::new(),
24 type_operators_map: HashMap::new(),
25 in_filed_operator_map: HashMap::new(),
26 }
27 }
28
29 pub fn add_operator(&mut self, operator: LuaOperator) {
30 let id = operator.get_id();
31 let owner = operator.get_owner().clone();
32 let op = operator.get_op();
33 self.operators.insert(id, operator);
34 self.type_operators_map
35 .entry(owner)
36 .or_insert_with(HashMap::new)
37 .entry(op)
38 .or_insert_with(Vec::new)
39 .push(id);
40 self.in_filed_operator_map
41 .entry(id.file_id)
42 .or_insert_with(Vec::new)
43 .push(id);
44 }
45
46 pub fn get_operators(
47 &self,
48 owner: &LuaOperatorOwner,
49 meta_method: LuaOperatorMetaMethod,
50 ) -> Option<&Vec<LuaOperatorId>> {
51 self.type_operators_map
52 .get(owner)
53 .and_then(|map| map.get(&meta_method))
54 }
55
56 pub fn get_operator(&self, id: &LuaOperatorId) -> Option<&LuaOperator> {
57 self.operators.get(id)
58 }
59}
60
61impl LuaIndex for LuaOperatorIndex {
62 fn remove(&mut self, file_id: FileId) {
63 if let Some(operator_ids) = self.in_filed_operator_map.remove(&file_id) {
64 for id in operator_ids {
65 if let Some(operator) = self.operators.remove(&id) {
66 let owner = operator.get_owner();
67 let op = operator.get_op();
68 let operators_map = match self.type_operators_map.get_mut(owner) {
69 Some(map) => map,
70 None => continue,
71 };
72 let operators = match operators_map.get_mut(&op) {
73 Some(operators) => operators,
74 None => continue,
75 };
76 operators.retain(|x| x != &id);
77 if operators.is_empty() {
78 operators_map.remove(&op);
79 }
80
81 if operators_map.is_empty() {
82 self.type_operators_map.remove(owner);
83 }
84 }
85 }
86 }
87 }
88
89 fn clear(&mut self) {
90 self.operators.clear();
91 self.type_operators_map.clear();
92 self.in_filed_operator_map.clear();
93 }
94}