Skip to content

Commit a7c3fb8

Browse files
committed
WIP: [IMP] propagate SELF evaluations
Working WIP, but many things need to be considered before we can say it is ready to merge
1 parent a5e855b commit a7c3fb8

File tree

17 files changed

+278
-110
lines changed

17 files changed

+278
-110
lines changed

server/src/core/evaluation.rs

Lines changed: 70 additions & 42 deletions
Large diffs are not rendered by default.

server/src/core/model.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,4 +305,29 @@ impl Model {
305305
}
306306
}
307307
}
308+
309+
pub fn inherits_from(&self, session: &mut SessionInfo, base: &Rc<RefCell<Model>>) -> bool {
310+
fn inner(this: &Model, session: &mut SessionInfo, base: &Rc<RefCell<Model>>, checked: &mut HashSet<OYarn>) -> bool {
311+
if checked.contains(&this.name) {
312+
return false;
313+
}
314+
checked.insert(this.name.clone());
315+
for symbol in this.symbols.iter() {
316+
let sym_ref = symbol.borrow();
317+
let Some(model_data) = &sym_ref.as_class_sym()._model else {continue};
318+
for inherit in model_data.inherit.iter() {
319+
if inherit == &base.borrow().name {
320+
return true;
321+
}
322+
if let Some(model) = session.sync_odoo.models.get(inherit).cloned() {
323+
if inner(&model.borrow(), session, base, checked) {
324+
return true;
325+
}
326+
}
327+
}
328+
}
329+
false
330+
}
331+
inner(self, session, base, &mut HashSet::new())
332+
}
308333
}

server/src/core/python_arch_eval.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -743,7 +743,7 @@ impl PythonArchEval {
743743
let mut var_bw = function_sym.borrow_mut();
744744
let is_class_method = var_bw.as_func().is_class_method;
745745
let symbol = var_bw.as_func_mut().symbols.get(&OYarn::from(arg.parameter.name.id.to_string())).unwrap().get(&0).unwrap().get(0).unwrap(); //get first declaration
746-
symbol.borrow_mut().evaluations_mut().unwrap().push(Evaluation::eval_from_symbol(&Rc::downgrade(self.sym_stack.last().unwrap()), Some(!is_class_method)));
746+
symbol.borrow_mut().evaluations_mut().unwrap().push(Evaluation::new_self(Rc::downgrade(self.sym_stack.last().unwrap()), Some(!is_class_method)));
747747
is_first = false;
748748
continue;
749749
}
@@ -1011,7 +1011,11 @@ impl PythonArchEval {
10111011
None
10121012
).len() > 0
10131013
){
1014-
func_sym.borrow_mut().set_evaluations(vec![Evaluation::new_self()]);
1014+
let mut func_ref_mut = func_sym.borrow_mut();
1015+
if let Some(base) = func_ref_mut.get_in_parents(&vec![SymType::CLASS], true){
1016+
let is_class_method = func_ref_mut.as_func().is_class_method.clone();
1017+
func_ref_mut.set_evaluations(vec![Evaluation::new_self(base, Some(!is_class_method))]);
1018+
}
10151019
return;
10161020
}
10171021
for eval in evaluations.iter_mut() { //as this is an evaluation, we need to set the instance to true

server/src/core/python_arch_eval_hooks.rs

Lines changed: 59 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,19 @@ use super::python_arch_eval::PythonArchEval;
3131

3232
type PythonArchEvalHookFile = fn (odoo: &mut SessionInfo, entry: &Rc<RefCell<EntryPoint>>, file_symbol: Rc<RefCell<Symbol>>, symbol: Rc<RefCell<Symbol>>);
3333

34+
fn get_base_model_symbol(odoo: &mut SyncOdoo) -> Option<Rc<RefCell<Symbol>>> {
35+
let base_model_tree = if compare_semver(odoo.full_version.as_str(), "18.1") >= Ordering::Equal {
36+
(vec![Sy!("odoo"), Sy!("orm"), Sy!("models")], vec![Sy!("BaseModel")])
37+
} else {
38+
(vec![Sy!("odoo"), Sy!("models")], vec![Sy!("BaseModel")])
39+
};
40+
let base_model_symbol = odoo.get_symbol(odoo.config.odoo_path.as_ref().unwrap(), &base_model_tree, u32::MAX);
41+
if !base_model_symbol.is_empty() {
42+
base_model_symbol.first().cloned()
43+
} else {
44+
None
45+
}
46+
}
3447
pub struct PythonArchEvalFileHook {
3548
pub odoo_entry: bool,
3649
pub trees: Vec<(OYarn, OYarn, (Vec<OYarn>, Vec<OYarn>))>, //if tree content is set, will provide symbol in file content instead of the file symbol to func
@@ -301,7 +314,7 @@ static arch_eval_file_hooks: Lazy<Vec<PythonArchEvalFileHook>> = Lazy::new(|| {v
301314
}
302315
if let Some(boolean) = boolean_field.first() {
303316
let mut eval = Evaluation::eval_from_symbol(&Rc::downgrade(&boolean), Some(true));
304-
let weak = eval.symbol.get_mut_symbol_ptr().as_mut_weak();
317+
let weak = eval.symbol.get_mut_symbol_ptr().get_mut_weak();
305318
weak.context.insert(S!("compute"), ContextValue::STRING(S!("_compute_global")));
306319
symbol.borrow_mut().set_evaluations(vec![eval]);
307320
}
@@ -469,57 +482,65 @@ static arch_eval_function_hooks: Lazy<Vec<PythonArchEvalFunctionHook>> = Lazy::n
469482
tree: vec![(Sy!("0.0"), Sy!("18.1"), (vec![Sy!("odoo"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("__iter__")])),
470483
(Sy!("18.1"), Sy!("999.0"), (vec![Sy!("odoo"), Sy!("orm"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("__iter__")]))],
471484
if_exist_only: true,
472-
func: |_odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
473-
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self()]);
485+
func: |odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
486+
let base_model = get_base_model_symbol(odoo);
487+
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self(Rc::downgrade(&base_model.unwrap()), Some(true))]);
474488
}},
475489
PythonArchEvalFunctionHook {odoo_entry: true,
476490
tree: vec![(Sy!("0.0"), Sy!("18.1"), (vec![Sy!("odoo"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("__getitem__")])),
477491
(Sy!("18.1"), Sy!("999.0"), (vec![Sy!("odoo"), Sy!("orm"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("__getitem__")]))],
478492
if_exist_only: true,
479-
func: |_odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
480-
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self()]);
493+
func: |odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
494+
let base_model = get_base_model_symbol(odoo);
495+
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self(Rc::downgrade(&base_model.unwrap()), Some(true))]);
481496
}},
482497
PythonArchEvalFunctionHook {odoo_entry: true,
483498
tree: vec![(Sy!("0.0"), Sy!("18.1"), (vec![Sy!("odoo"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("with_env")])),
484499
(Sy!("18.1"), Sy!("999.0"), (vec![Sy!("odoo"), Sy!("orm"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("with_env")]))],
485500
if_exist_only: true,
486-
func: |_odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
487-
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self()]);
501+
func: |odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
502+
let base_model = get_base_model_symbol(odoo);
503+
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self(Rc::downgrade(&base_model.unwrap()), Some(true))]);
488504
}},
489505
PythonArchEvalFunctionHook {odoo_entry: true,
490506
tree: vec![(Sy!("0.0"), Sy!("18.1"), (vec![Sy!("odoo"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("sudo")])),
491507
(Sy!("18.1"), Sy!("999.0"), (vec![Sy!("odoo"), Sy!("orm"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("sudo")]))],
492508
if_exist_only: true,
493-
func: |_odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
494-
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self()]);
509+
func: |odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
510+
let base_model = get_base_model_symbol(odoo);
511+
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self(Rc::downgrade(&base_model.unwrap()), Some(true))]);
495512
}},
496513
PythonArchEvalFunctionHook {odoo_entry: true,
497514
tree: vec![(Sy!("0.0"), Sy!("18.1"), (vec![Sy!("odoo"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("create")])),
498515
(Sy!("18.1"), Sy!("999.0"), (vec![Sy!("odoo"), Sy!("orm"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("create")]))],
499516
if_exist_only: true,
500-
func: |_odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
501-
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self()]);
517+
func: |odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
518+
let base_model = get_base_model_symbol(odoo);
519+
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self(Rc::downgrade(&base_model.unwrap()), Some(true))]);
502520
}},
503521
PythonArchEvalFunctionHook {odoo_entry: true,
504522
tree: vec![(Sy!("0.0"), Sy!("18.1"), (vec![Sy!("odoo"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("filtered")])),
505523
(Sy!("18.1"), Sy!("999.0"), (vec![Sy!("odoo"), Sy!("orm"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("filtered")]))],
506524
if_exist_only: true,
507-
func: |_odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
508-
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self()]);
525+
func: |odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
526+
let base_model = get_base_model_symbol(odoo);
527+
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self(Rc::downgrade(&base_model.unwrap()), Some(true))]);
509528
}},
510529
PythonArchEvalFunctionHook {odoo_entry: true,
511530
tree: vec![(Sy!("0.0"), Sy!("18.1"), (vec![Sy!("odoo"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("filtered_domain")])),
512531
(Sy!("18.1"), Sy!("999.0"), (vec![Sy!("odoo"), Sy!("orm"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("filtered_domain")]))],
513532
if_exist_only: true,
514-
func: |_odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
515-
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self()]);
533+
func: |odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
534+
let base_model = get_base_model_symbol(odoo);
535+
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self(Rc::downgrade(&base_model.unwrap()), Some(true))]);
516536
}},
517537
PythonArchEvalFunctionHook {odoo_entry: true,
518538
tree: vec![(Sy!("0.0"), Sy!("18.1"), (vec![Sy!("odoo"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("search")])),
519539
(Sy!("18.1"), Sy!("999.0"), (vec![Sy!("odoo"), Sy!("orm"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("search")]))],
520540
if_exist_only: true,
521541
func: |odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
522-
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self()]);
542+
let base_model = get_base_model_symbol(odoo);
543+
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self(Rc::downgrade(&base_model.unwrap()), Some(true))]);
523544
let search = symbol.borrow();
524545
let func = search.as_func();
525546
if func.args.len() > 1 {
@@ -536,43 +557,49 @@ static arch_eval_function_hooks: Lazy<Vec<PythonArchEvalFunctionHook>> = Lazy::n
536557
tree: vec![(Sy!("0.0"), Sy!("18.1"), (vec![Sy!("odoo"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("browse")])),
537558
(Sy!("18.1"), Sy!("999.0"), (vec![Sy!("odoo"), Sy!("orm"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("browse")]))],
538559
if_exist_only: true,
539-
func: |_odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
540-
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self()]);
560+
func: |odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
561+
let base_model = get_base_model_symbol(odoo);
562+
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self(Rc::downgrade(&base_model.unwrap()), Some(true))]);
541563
}},
542564
PythonArchEvalFunctionHook {odoo_entry: true,
543565
tree: vec![(Sy!("0.0"), Sy!("18.1"), (vec![Sy!("odoo"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("with_company")])),
544566
(Sy!("18.1"), Sy!("999.0"), (vec![Sy!("odoo"), Sy!("orm"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("with_company")]))],
545567
if_exist_only: true,
546-
func: |_odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
547-
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self()]);
568+
func: |odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
569+
let base_model = get_base_model_symbol(odoo);
570+
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self(Rc::downgrade(&base_model.unwrap()), Some(true))]);
548571
}},
549572
PythonArchEvalFunctionHook {odoo_entry: true,
550573
tree: vec![(Sy!("0.0"), Sy!("18.1"), (vec![Sy!("odoo"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("with_context")])),
551574
(Sy!("18.1"), Sy!("999.0"), (vec![Sy!("odoo"), Sy!("orm"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("with_context")]))],
552575
if_exist_only: true,
553-
func: |_odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
554-
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self()]);
576+
func: |odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
577+
let base_model = get_base_model_symbol(odoo);
578+
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self(Rc::downgrade(&base_model.unwrap()), Some(true))]);
555579
}},
556580
PythonArchEvalFunctionHook {odoo_entry: true,
557581
tree: vec![(Sy!("0.0"), Sy!("18.1"), (vec![Sy!("odoo"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("with_prefetch")])),
558582
(Sy!("18.1"), Sy!("999.0"), (vec![Sy!("odoo"), Sy!("orm"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("with_prefetch")]))],
559583
if_exist_only: true,
560-
func: |_odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
561-
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self()]);
584+
func: |odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
585+
let base_model = get_base_model_symbol(odoo);
586+
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self(Rc::downgrade(&base_model.unwrap()), Some(true))]);
562587
}},
563588
PythonArchEvalFunctionHook {odoo_entry: true,
564589
tree: vec![(Sy!("0.0"), Sy!("18.1"), (vec![Sy!("odoo"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("with_user")])),
565590
(Sy!("18.1"), Sy!("999.0"), (vec![Sy!("odoo"), Sy!("orm"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("with_user")]))],
566591
if_exist_only: true,
567-
func: |_odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
568-
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self()]);
592+
func: |odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
593+
let base_model = get_base_model_symbol(odoo);
594+
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self(Rc::downgrade(&base_model.unwrap()), Some(true))]);
569595
}},
570596
PythonArchEvalFunctionHook {odoo_entry: true,
571597
tree: vec![(Sy!("0.0"), Sy!("18.1"), (vec![Sy!("odoo"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("exists")])),
572598
(Sy!("18.1"), Sy!("999.0"), (vec![Sy!("odoo"), Sy!("orm"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("exists")]))],
573599
if_exist_only: true,
574-
func: |_odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
575-
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self()]);
600+
func: |odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
601+
let base_model = get_base_model_symbol(odoo);
602+
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self(Rc::downgrade(&base_model.unwrap()), Some(true))]);
576603
}},
577604
PythonArchEvalFunctionHook {odoo_entry: true,
578605
tree: vec![(Sy!("0.0"), Sy!("18.1"), (vec![Sy!("odoo"), Sy!("fields")], vec![Sy!("Id"), Sy!("__get__")])),
@@ -1145,7 +1172,10 @@ impl PythonArchEvalHooks {
11451172
let Some(Expr::StringLiteral(expr)) = arguments.args.first() else {return diagnostics};
11461173
let returns_str = expr.value.to_string();
11471174
if returns_str == S!("self"){
1148-
func_sym.borrow_mut().set_evaluations(vec![Evaluation::new_self()]);
1175+
if let Some(base) = func_sym.borrow().get_in_parents(&vec![SymType::CLASS], true){
1176+
let is_class_method = func_sym.borrow().as_func().is_class_method.clone();
1177+
func_sym.borrow_mut().set_evaluations(vec![Evaluation::new_self(base, Some(!is_class_method))]);
1178+
}
11491179
return diagnostics;
11501180
}
11511181
let Some(model) = session.sync_odoo.models.get(&oyarn!("{}", returns_str)).cloned() else {

server/src/core/python_odoo_builder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ impl PythonOdooBuilder {
369369
// base_model_syms empty so sym cannot be a model, otherwise we would have found it earlier
370370
return false;
371371
}
372-
if !symbol.borrow().as_class_sym().inherits(&base_model_syms[0], &mut None) {
372+
if !symbol.borrow().as_class_sym().inherits(session, &base_model_syms[0], &mut None) {
373373
return false;
374374
}
375375
// Check if we have a _register = False

0 commit comments

Comments
 (0)