Skip to content

Commit 4646006

Browse files
committed
[FIX] server: adapt all_members to be correct
1 parent 5dcc234 commit 4646006

File tree

4 files changed

+134
-93
lines changed

4 files changed

+134
-93
lines changed

server/src/core/model.rs

Lines changed: 60 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -208,22 +208,73 @@ impl Model {
208208
} else {
209209
symbols.push((s.clone(), None));
210210
}
211-
if with_inheritance { //TODO wrong, should be recursive
212-
let inherited_models = s.borrow().as_class_sym()._model.as_ref().unwrap().inherit.clone();
213-
for inherited_model in inherited_models.iter() {
214-
if !seen_inherited_models.contains(inherited_model) {
215-
seen_inherited_models.insert(inherited_model.clone());
216-
let model = session.sync_odoo.models.get(inherited_model).cloned();
217-
if let Some(model) = model {
218-
symbols.extend(model.borrow().all_symbols_helper(session, from_module.clone(), true, seen_inherited_models));
219-
}
211+
if !with_inheritance {
212+
continue;
213+
}
214+
let inherited_models = s.borrow().as_class_sym()._model.as_ref().unwrap().inherit.clone();
215+
for inherited_model in inherited_models.iter() {
216+
if !seen_inherited_models.contains(inherited_model) {
217+
seen_inherited_models.insert(inherited_model.clone());
218+
if let Some(model) = session.sync_odoo.models.get(inherited_model).cloned() {
219+
symbols.extend(model.borrow().all_symbols_helper(session, from_module.clone(), true, seen_inherited_models));
220220
}
221221
}
222222
}
223223
}
224224
symbols
225225
}
226226

227+
pub fn all_symbols_inherits(&self, session: &mut SessionInfo, from_module: Option<Rc<RefCell<Symbol>>>) -> (Vec<(Rc<RefCell<Symbol>>, Option<OYarn>)>, Vec<(Rc<RefCell<Symbol>>, Option<OYarn>)>) {
228+
let mut visited_models = HashSet::new();
229+
self.all_inherits_helper(session, from_module, &mut visited_models)
230+
}
231+
232+
fn all_inherits_helper(&self, session: &mut SessionInfo, from_module: Option<Rc<RefCell<Symbol>>>, visited_models: &mut HashSet<String>) -> (Vec<(Rc<RefCell<Symbol>>, Option<OYarn>)>, Vec<(Rc<RefCell<Symbol>>, Option<OYarn>)>) {
233+
if visited_models.contains(&self.name) {
234+
return (Vec::new(), Vec::new());
235+
}
236+
visited_models.insert(self.name.clone());
237+
let mut symbols = Vec::new();
238+
let mut inherits_symbols = Vec::new();
239+
for s in self.symbols.iter() {
240+
if let Some(from_module) = from_module.as_ref() {
241+
let module = s.borrow().find_module();
242+
if let Some(module) = module {
243+
if ModuleSymbol::is_in_deps(session, &from_module, &module.borrow().as_module_package().dir_name) {
244+
symbols.push((s.clone(), None));
245+
} else {
246+
symbols.push((s.clone(), Some(module.borrow().as_module_package().dir_name.clone())));
247+
}
248+
} else {
249+
session.log_message(MessageType::WARNING, "A model should be declared in a module.".to_string());
250+
}
251+
} else {
252+
symbols.push((s.clone(), None));
253+
}
254+
// First get results from normal inherit
255+
// To make sure we visit all of inherit before inherits, since it is DFS
256+
// Only inherits in the tree that are not already visited will be processed in the next iteration
257+
let inherited_models = s.borrow().as_class_sym()._model.as_ref().unwrap().inherit.clone();
258+
for inherited_model in inherited_models.iter() {
259+
if let Some(model) = session.sync_odoo.models.get(inherited_model).cloned() {
260+
let (main_result, inherits_result) = model.borrow().all_inherits_helper(session, from_module.clone(), visited_models);
261+
symbols.extend(main_result);
262+
inherits_symbols.extend(inherits_result);
263+
}
264+
}
265+
for (inherits_model, _) in s.borrow().as_class_sym()._model.as_ref().unwrap().inherits.clone() {
266+
if let Some(model) = session.sync_odoo.models.get(&inherits_model).cloned() {
267+
let (main_result, inherits_result) = model.borrow().all_inherits_helper(session, from_module.clone(), visited_models);
268+
// Everything that is in inherits should be added to inherits_symbols, regardless of whether
269+
// it was in inherit or inherits. Since we need that distinction to later only get fields
270+
inherits_symbols.extend(main_result);
271+
inherits_symbols.extend(inherits_result);
272+
}
273+
}
274+
}
275+
(symbols, inherits_symbols)
276+
}
277+
227278
pub fn add_dependent(&mut self, symbol: &Rc<RefCell<Symbol>>) {
228279
self.dependents.insert(symbol.clone());
229280
}

server/src/core/python_odoo_builder.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,7 @@ impl PythonOdooBuilder {
170170
drop(_inherits);
171171
drop(symbol);
172172
//Add inherits from delegate=True from fields
173-
let mut all_fields = HashMap::new();
174-
Symbol::all_members(&self.symbol, session, &mut all_fields, false, true, false, None, &mut None, false);
173+
let all_fields = Symbol::all_members(&self.symbol, session, false, true, false, None, false);
175174
for (field_name, symbols) in all_fields.iter() {
176175
for (symbol, _deps) in symbols.iter() {
177176
if let Some(evals) = symbol.borrow().evaluations() {

server/src/core/symbols/symbol.rs

Lines changed: 71 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -2213,30 +2213,30 @@ impl Symbol {
22132213
let mut iter: Vec<Rc<RefCell<Symbol>>> = Vec::new();
22142214
match self {
22152215
Symbol::File(_) => {
2216-
for symbol in self.iter_symbols().flat_map(|(name, hashmap)| hashmap.into_iter().flat_map(|(_, vec)| vec.clone())) {
2216+
for symbol in self.iter_symbols().flat_map(|(_, hashmap)| hashmap.into_iter().flat_map(|(_, vec)| vec.clone())) {
22172217
iter.push(symbol.clone());
22182218
}
22192219
},
22202220
Symbol::Class(_) => {
2221-
for symbol in self.iter_symbols().flat_map(|(name, hashmap)| hashmap.into_iter().flat_map(|(_, vec)| vec.clone())) {
2221+
for symbol in self.iter_symbols().flat_map(|(_, hashmap)| hashmap.into_iter().flat_map(|(_, vec)| vec.clone())) {
22222222
iter.push(symbol.clone());
22232223
}
22242224
},
22252225
Symbol::Function(_) => {
2226-
for symbol in self.iter_symbols().flat_map(|(name, hashmap)| hashmap.iter().flat_map(|(_, vec)| vec.clone())) {
2226+
for symbol in self.iter_symbols().flat_map(|(_, hashmap)| hashmap.iter().flat_map(|(_, vec)| vec.clone())) {
22272227
iter.push(symbol.clone());
22282228
}
22292229
},
22302230
Symbol::Package(PackageSymbol::Module(m)) => {
2231-
for symbol in self.iter_symbols().flat_map(|(name, hashmap)| hashmap.iter().flat_map(|(_, vec)| vec.clone())) {
2231+
for symbol in self.iter_symbols().flat_map(|(_, hashmap)| hashmap.iter().flat_map(|(_, vec)| vec.clone())) {
22322232
iter.push(symbol.clone());
22332233
}
22342234
for symbol in m.module_symbols.values().cloned() {
22352235
iter.push(symbol.clone());
22362236
}
22372237
},
22382238
Symbol::Package(PackageSymbol::PythonPackage(p)) => {
2239-
for symbol in self.iter_symbols().flat_map(|(name, hashmap)| hashmap.iter().flat_map(|(_, vec)| vec.clone())) {
2239+
for symbol in self.iter_symbols().flat_map(|(_, hashmap)| hashmap.iter().flat_map(|(_, vec)| vec.clone())) {
22402240
iter.push(symbol.clone());
22412241
}
22422242
for symbol in p.module_symbols.values().cloned() {
@@ -2260,77 +2260,81 @@ impl Symbol {
22602260

22612261
//store in result all available members for symbol: sub symbols, base class elements and models symbols
22622262
//TODO is order right of Vec in HashMap? if we take first or last in it, do we have the last effective value?
2263-
pub fn all_members(symbol: &Rc<RefCell<Symbol>>, session: &mut SessionInfo, result: &mut HashMap<OYarn, Vec<(Rc<RefCell<Symbol>>, Option<OYarn>)>>, with_co_models: bool, only_fields: bool, only_methods: bool, from_module: Option<Rc<RefCell<Symbol>>>, acc: &mut Option<HashSet<Tree>>, is_super: bool) {
2264-
if acc.is_none() {
2265-
*acc = Some(HashSet::new());
2266-
}
2263+
pub fn all_members(
2264+
symbol: &Rc<RefCell<Symbol>>,
2265+
session: &mut SessionInfo,
2266+
with_co_models: bool,
2267+
only_fields: bool,
2268+
only_methods: bool,
2269+
from_module: Option<Rc<RefCell<Symbol>>>,
2270+
is_super: bool) -> HashMap<OYarn, Vec<(Rc<RefCell<Symbol>>, Option<OYarn>)>>{
2271+
let mut result: HashMap<OYarn, Vec<(Rc<RefCell<Symbol>>, Option<OYarn>)>> = HashMap::new();
2272+
let mut acc: HashSet<Tree> = HashSet::new();
2273+
Symbol::_all_members(symbol, session, &mut result, with_co_models, only_fields, only_methods, from_module, &mut acc, is_super);
2274+
return result;
2275+
}
2276+
fn _all_members(symbol: &Rc<RefCell<Symbol>>, session: &mut SessionInfo, result: &mut HashMap<OYarn, Vec<(Rc<RefCell<Symbol>>, Option<OYarn>)>>, with_co_models: bool, only_fields: bool, only_methods: bool, from_module: Option<Rc<RefCell<Symbol>>>, acc: &mut HashSet<Tree>, is_super: bool) {
22672277
let tree = symbol.borrow().get_tree();
2268-
if acc.as_mut().unwrap().contains(&tree) {
2278+
if acc.contains(&tree) {
22692279
return;
22702280
}
2271-
acc.as_mut().unwrap().insert(tree);
2281+
acc.insert(tree);
2282+
let mut append_result = |symbol: Rc<RefCell<Symbol>>, dep: Option<OYarn>| {
2283+
let name = symbol.borrow().name().clone();
2284+
if let Some(vec) = result.get_mut(&name) {
2285+
vec.push((symbol, dep));
2286+
} else {
2287+
result.insert(name.clone(), vec![(symbol, dep)]);
2288+
}
2289+
};
22722290
let typ = symbol.borrow().typ();
22732291
match typ {
22742292
SymType::CLASS => {
22752293
// Skip current class symbols for super
22762294
if !is_super{
22772295
for symbol in symbol.borrow().all_symbols() {
2278-
if only_fields && !symbol.borrow().is_field(session){
2296+
if (only_fields && !symbol.borrow().is_field(session)) || (only_methods && symbol.borrow().typ() != SymType::FUNCTION) {
22792297
continue;
22802298
}
2281-
if only_methods && symbol.borrow().typ() != SymType::FUNCTION {
2282-
continue;
2283-
}
2284-
let name = symbol.borrow().name().clone();
2285-
if let Some(vec) = result.get_mut(&name) {
2286-
vec.push((symbol, None));
2287-
} else {
2288-
result.insert(name.clone(), vec![(symbol, None)]);
2289-
}
2299+
append_result(symbol, None);
22902300
}
22912301
}
2302+
let mut bases: PtrWeakHashSet<Weak<RefCell<Symbol>>> = PtrWeakHashSet::new();
2303+
symbol.borrow().as_class_sym().bases.iter().for_each(|base| {
2304+
base.upgrade().map(|b| bases.insert(b));
2305+
});
22922306
if with_co_models {
2293-
let sym = symbol.borrow();
2294-
let model_data = sym.as_class_sym()._model.as_ref();
2295-
if let Some(model_data) = model_data {
2296-
if let Some(model) = session.sync_odoo.models.get(&model_data.name).cloned() {
2297-
for (model_sym, dependency) in model.borrow().all_symbols(session, from_module.clone(), true) {
2298-
if dependency.is_none() && !Rc::ptr_eq(symbol, &model_sym) {
2299-
for s in model_sym.borrow().all_symbols() {
2300-
if only_fields && !s.borrow().is_field(session){
2301-
continue;
2302-
}
2303-
if only_methods && symbol.borrow().typ() != SymType::FUNCTION{
2304-
continue;
2305-
}
2306-
let name = s.borrow().name().clone();
2307-
if let Some(vec) = result.get_mut(&name) {
2308-
vec.push((s, Some(model_sym.borrow().name().clone())));
2309-
} else {
2310-
result.insert(name.clone(), vec![(s, Some(model_sym.borrow().name().clone()))]);
2311-
}
2312-
}
2313-
//add fields from _inherits
2314-
if let Some(model_data) = model_sym.borrow().as_class_sym()._model.as_ref() {
2315-
for (inherits_model, inherits_field) in model_data.inherits.iter() {
2316-
let inherits_model_sym = session.sync_odoo.models.get(inherits_model).cloned();
2317-
if let Some(inherits_model_sym) = inherits_model_sym {
2318-
for (model_symbol, deps) in inherits_model_sym.borrow().all_symbols(session, from_module.clone(), true).iter().filter(|(x, deps)| deps.is_none()) {
2319-
for (field_name, field_symbols) in Symbol::all_fields(&model_symbol, session, from_module.clone()) {
2320-
for (s, deps) in field_symbols.iter().filter(|(x, deps)| deps.is_none()) {
2321-
if let Some(vec) = result.get_mut(&field_name) {
2322-
vec.push((s.clone(), Some(model_sym.borrow().name().clone())));
2323-
} else {
2324-
result.insert(field_name.clone(), vec![(s.clone(), Some(model_sym.borrow().name().clone()))]);
2325-
}
2326-
}
2327-
}
2328-
}
2329-
}
2330-
}
2331-
}
2332-
}
2307+
let Some(model) = symbol.borrow().as_class_sym()._model.as_ref().and_then(|model_data|
2308+
session.sync_odoo.models.get(&model_data.name).cloned()
2309+
) else {
2310+
return;
2311+
};
2312+
// no recursion because it is handled in all_symbols_inherits
2313+
let (model_symbols, model_inherits_symbols) = model.borrow().all_symbols_inherits(session, from_module.clone());
2314+
for (model_sym, dependency) in model_symbols {
2315+
if dependency.is_some() || Rc::ptr_eq(symbol, &model_sym) {
2316+
continue;
2317+
}
2318+
model_sym.borrow().as_class_sym().bases.iter().for_each(|base| {
2319+
base.upgrade().map(|b| bases.insert(b));
2320+
});
2321+
for s in model_sym.borrow().all_symbols() {
2322+
if (only_fields && !s.borrow().is_field(session)) || (only_methods && s.borrow().typ() != SymType::FUNCTION) {
2323+
continue;
23332324
}
2325+
append_result(s, Some(model_sym.borrow().name().clone()));
2326+
}
2327+
}
2328+
for (model_sym, dependency) in model_inherits_symbols {
2329+
if dependency.is_some() || Rc::ptr_eq(symbol, &model_sym) {
2330+
continue;
2331+
}
2332+
model_sym.borrow().as_class_sym().bases.iter().for_each(|base| {
2333+
base.upgrade().map(|b| bases.insert(b));
2334+
});
2335+
// for inherits symbols, we only add fields
2336+
for s in model_sym.borrow().all_symbols().filter(|s| s.borrow().is_field(session)) {
2337+
append_result(s, Some(model_sym.borrow().name().clone()));
23342338
}
23352339
}
23362340
}
@@ -2339,23 +2343,14 @@ impl Symbol {
23392343
//no comodel as we will search for co-model from original class (what about overrided _name?)
23402344
//TODO what about base of co-models classes?
23412345
if let Some(base) = base.upgrade() {
2342-
Symbol::all_members(&base, session, result, false, only_fields, only_methods, from_module.clone(), acc, false);
2346+
Symbol::_all_members(&base, session, result, false, only_fields, only_methods, from_module.clone(), acc, false);
23432347
}
23442348
}
23452349
},
2346-
_ => {
2347-
for symbol in symbol.borrow().all_symbols() {
2348-
if only_fields && !symbol.borrow().is_field(session){
2349-
continue;
2350-
}
2351-
let name = symbol.borrow().name().clone();
2352-
if let Some(vec) = result.get_mut(&name) {
2353-
vec.push((symbol, None));
2354-
} else {
2355-
result.insert(name.clone(), vec![(symbol, None)]);
2356-
}
2357-
}
2358-
}
2350+
// if not class just add it to result
2351+
_ => symbol.borrow().all_symbols().for_each(|s|
2352+
if !(only_fields && !s.borrow().is_field(session)) {append_result(s, None)}
2353+
)
23592354
}
23602355
}
23612356

@@ -2596,9 +2591,7 @@ impl Symbol {
25962591
}
25972592

25982593
pub fn all_fields(symbol: &Rc<RefCell<Symbol>>, session: &mut SessionInfo, from_module: Option<Rc<RefCell<Symbol>>>) -> HashMap<OYarn, Vec<(Rc<RefCell<Symbol>>, Option<OYarn>)>> {
2599-
let mut all_fields = HashMap::new();
2600-
Symbol::all_members(symbol, session, &mut all_fields, true, true, false, from_module.clone(), &mut None, false);
2601-
all_fields
2594+
Symbol::all_members(symbol, session, true, true, false, from_module.clone(), false)
26022595
}
26032596

26042597
/* similar to get_symbol: will return the symbol that is under this one with the specified name.

server/src/features/completion.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -929,8 +929,7 @@ fn add_nested_field_names(
929929
}
930930
if let Some(object) = &obj {
931931
if index == split_expr.len() - 1 {
932-
let mut all_symbols: HashMap<OYarn, Vec<(Rc<RefCell<Symbol>>, Option<OYarn>)>> = HashMap::new();
933-
Symbol::all_members(&object, session, &mut all_symbols, true, true, false, from_module.clone(), &mut None, false);
932+
let all_symbols = Symbol::all_members(&object, session, true, true, false, from_module.clone(), false);
934933
for (_symbol_name, symbols) in all_symbols {
935934
//we could use symbol_name to remove duplicated names, but it would hide functions vs variables
936935
if _symbol_name.starts_with(name) {
@@ -988,8 +987,7 @@ fn add_model_attributes(
988987
only_methods: bool,
989988
attribute_name: &str
990989
){
991-
let mut all_symbols: HashMap<OYarn, Vec<(Rc<RefCell<Symbol>>, Option<OYarn>)>> = HashMap::new();
992-
Symbol::all_members(&parent_sym, session, &mut all_symbols, true, only_fields, only_methods, from_module.clone(), &mut None, is_super);
990+
let all_symbols = Symbol::all_members(&parent_sym, session, true, only_fields, only_methods, from_module.clone(), is_super);
993991
for (_symbol_name, symbols) in all_symbols {
994992
//we could use symbol_name to remove duplicated names, but it would hide functions vs variables
995993
if _symbol_name.starts_with(attribute_name) {

0 commit comments

Comments
 (0)