@@ -5,12 +5,14 @@ use std::rc::Rc;
55use std:: rc:: Weak ;
66use lsp_types:: MessageType ;
77use weak_table:: PtrWeakHashSet ;
8+ use weak_table:: PtrWeakKeyHashMap ;
89use std:: collections:: HashSet ;
910
1011use crate :: constants:: BuildStatus ;
1112use crate :: constants:: BuildSteps ;
1213use crate :: constants:: OYarn ;
1314use crate :: constants:: SymType ;
15+ use crate :: core:: xml_data:: OdooDataRecord ;
1416use crate :: threads:: SessionInfo ;
1517
1618use super :: symbols:: module_symbol:: ModuleSymbol ;
@@ -73,6 +75,10 @@ impl ModelData {
7375pub struct Model {
7476 name : OYarn ,
7577 symbols : PtrWeakHashSet < Weak < RefCell < Symbol > > > ,
78+ // One XML file can have multiple records that define models or fields
79+ // xml symbols and model fields are thus maps from xml file symbol to a list of records
80+ xml_symbols : PtrWeakKeyHashMap < Weak < RefCell < Symbol > > , HashSet < OdooDataRecord > > ,
81+ model_fields : PtrWeakKeyHashMap < Weak < RefCell < Symbol > > , HashSet < OdooDataRecord > > ,
7682 pub dependents : PtrWeakHashSet < Weak < RefCell < Symbol > > > ,
7783}
7884
@@ -81,12 +87,30 @@ impl Model {
8187 let mut res = Self {
8288 name,
8389 symbols : PtrWeakHashSet :: new ( ) ,
90+ xml_symbols : PtrWeakKeyHashMap :: new ( ) ,
91+ model_fields : PtrWeakKeyHashMap :: new ( ) ,
8492 dependents : PtrWeakHashSet :: new ( ) ,
8593 } ;
8694 res. symbols . insert ( symbol) ;
8795 res
8896 }
8997
98+ pub fn new_from_xml ( name : OYarn , xml_file_symbol : Rc < RefCell < Symbol > > , record : OdooDataRecord ) -> Self {
99+ let mut res = Self {
100+ name,
101+ symbols : PtrWeakHashSet :: new ( ) ,
102+ xml_symbols : PtrWeakKeyHashMap :: new ( ) ,
103+ model_fields : PtrWeakKeyHashMap :: new ( ) ,
104+ dependents : PtrWeakHashSet :: new ( ) ,
105+ } ;
106+ res. xml_symbols . insert ( xml_file_symbol, HashSet :: from ( [ record] ) ) ;
107+ res
108+ }
109+
110+ pub fn name ( & self ) -> & OYarn {
111+ & self . name
112+ }
113+
90114 pub fn add_symbol ( & mut self , session : & mut SessionInfo , symbol : Rc < RefCell < Symbol > > ) {
91115 if self . symbols . contains ( & symbol) {
92116 return ;
@@ -96,6 +120,78 @@ impl Model {
96120 self . add_dependents_to_validation ( session, from_module) ;
97121 }
98122
123+ fn add_xml_ref ( collection : & mut PtrWeakKeyHashMap < Weak < RefCell < Symbol > > , HashSet < OdooDataRecord > > , symbol : & Rc < RefCell < Symbol > > , record : OdooDataRecord ) -> bool {
124+ if let Some ( records) = collection. get_mut ( symbol) {
125+ records. insert ( record)
126+ } else {
127+ collection. insert ( symbol. clone ( ) , HashSet :: from ( [ record] ) ) ;
128+ true
129+ }
130+ }
131+
132+ pub fn add_xml_symbol ( & mut self , session : & mut SessionInfo , symbol : Rc < RefCell < Symbol > > , record : OdooDataRecord ) {
133+ if Self :: add_xml_ref ( & mut self . xml_symbols , & symbol, record) {
134+ self . add_dependents_to_validation ( session, symbol. borrow ( ) . find_module ( ) ) ;
135+ }
136+ }
137+
138+ pub fn add_model_field ( & mut self , session : & mut SessionInfo , symbol : Rc < RefCell < Symbol > > , record : OdooDataRecord ) {
139+ if Self :: add_xml_ref ( & mut self . model_fields , & symbol, record) {
140+ self . add_dependents_to_validation ( session, symbol. borrow ( ) . find_module ( ) ) ;
141+ }
142+ }
143+
144+
145+ pub fn get_model_field_records ( & self , session : & mut SessionInfo , from_module : Option < Rc < RefCell < Symbol > > > ) -> Vec < ( Rc < RefCell < Symbol > > , OdooDataRecord ) > {
146+ let mut result = Vec :: new ( ) ;
147+ for ( s, records) in self . model_fields . iter ( ) {
148+ let module = s. borrow ( ) . find_module ( ) ;
149+ if let Some ( module) = module {
150+ if from_module. is_none ( ) || ModuleSymbol :: is_in_deps ( session, from_module. as_ref ( ) . unwrap ( ) , & module. borrow ( ) . as_module_package ( ) . dir_name ) {
151+ for r in records. iter ( ) {
152+ result. push ( ( s. clone ( ) , r. clone ( ) ) ) ;
153+ }
154+ }
155+ }
156+ }
157+ result
158+ }
159+
160+
161+ pub fn get_model_field_record_by_name ( & self , session : & mut SessionInfo , from_module : Option < Rc < RefCell < Symbol > > > , field_name : & str ) -> Vec < ( Rc < RefCell < Symbol > > , OdooDataRecord ) > {
162+ self . get_model_field_records ( session, from_module) . into_iter ( ) . filter ( |( _, r) | {
163+ r. fields . iter ( ) . any ( |f| f. name . as_str ( ) == "name" && f. text . as_deref ( ) == Some ( field_name) )
164+ } ) . collect ( )
165+ }
166+
167+ pub fn get_xml_symbols ( & self , session : & mut SessionInfo , from_module : Option < Rc < RefCell < Symbol > > > ) -> Vec < Rc < RefCell < Symbol > > > {
168+ let mut result = Vec :: new ( ) ;
169+ for ( s, _records) in self . xml_symbols . iter ( ) {
170+ let module = s. borrow ( ) . find_module ( ) ;
171+ if let Some ( module) = module {
172+ if from_module. is_none ( ) || ModuleSymbol :: is_in_deps ( session, from_module. as_ref ( ) . unwrap ( ) , & module. borrow ( ) . as_module_package ( ) . dir_name ) {
173+ result. push ( s) ;
174+ }
175+ }
176+ }
177+ result
178+ }
179+
180+ pub fn get_xml_symbol_records ( & self , session : & mut SessionInfo , from_module : Option < Rc < RefCell < Symbol > > > ) -> Vec < ( Rc < RefCell < Symbol > > , OdooDataRecord ) > {
181+ let mut result = Vec :: new ( ) ;
182+ for ( s, record) in self . xml_symbols . iter ( ) {
183+ let module = s. borrow ( ) . find_module ( ) ;
184+ if let Some ( module) = module {
185+ if from_module. is_none ( ) || ModuleSymbol :: is_in_deps ( session, from_module. as_ref ( ) . unwrap ( ) , & module. borrow ( ) . as_module_package ( ) . dir_name ) {
186+ for r in record. iter ( ) {
187+ result. push ( ( s. clone ( ) , r. clone ( ) ) ) ;
188+ }
189+ }
190+ }
191+ }
192+ result
193+ }
194+
99195 pub fn remove_symbol ( & mut self , session : & mut SessionInfo , symbol : & Rc < RefCell < Symbol > > , from_module : Option < Rc < RefCell < Symbol > > > ) {
100196 self . symbols . remove ( symbol) ;
101197 self . add_dependents_to_validation ( session, from_module) ;
@@ -130,13 +226,22 @@ impl Model {
130226 }
131227
132228 pub fn model_in_deps ( & self , session : & mut SessionInfo , from_module : & Rc < RefCell < Symbol > > ) -> bool {
133- for sym in self . symbols . iter ( ) {
134- if !sym . borrow ( ) . as_class_sym ( ) . _model . as_ref ( ) . unwrap ( ) . inherit . contains ( & sym. borrow ( ) . as_class_sym ( ) . _model . as_ref ( ) . unwrap ( ) . name ) {
135- let dir_name = sym . borrow ( ) . find_module ( ) . unwrap ( ) . borrow ( ) . as_module_package ( ) . dir_name . clone ( ) ;
229+ let sym_module_check = | session : & mut SessionInfo < ' _ > , sym : & Rc < RefCell < Symbol > > | {
230+ if let Some ( module ) = sym. borrow ( ) . find_module ( ) {
231+ let dir_name = module . borrow ( ) . as_module_package ( ) . dir_name . clone ( ) ;
136232 if ModuleSymbol :: is_in_deps ( session, from_module, & dir_name) {
137233 return true ;
138234 }
139235 }
236+ false
237+ } ;
238+ if self . symbols . iter ( ) . any ( |sym|
239+ !sym. borrow ( ) . as_class_sym ( ) . _model . as_ref ( ) . unwrap ( ) . inherit . contains ( & sym. borrow ( ) . as_class_sym ( ) . _model . as_ref ( ) . unwrap ( ) . name )
240+ && sym_module_check ( session, & sym) ) {
241+ return true ;
242+ }
243+ if self . xml_symbols . iter ( ) . any ( |( sym, _record) | sym_module_check ( session, & sym) ) {
244+ return true ;
140245 }
141246 false
142247 }
@@ -188,7 +293,9 @@ impl Model {
188293
189294 pub fn has_symbols ( & mut self ) -> bool {
190295 self . symbols . remove_expired ( ) ;
191- !self . symbols . is_empty ( )
296+ self . xml_symbols . remove_expired ( ) ;
297+ self . model_fields . remove_expired ( ) ;
298+ !self . symbols . is_empty ( ) || !self . xml_symbols . is_empty ( )
192299 }
193300
194301 /* Return all symbols that build this model.
0 commit comments