Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 62 additions & 39 deletions server/src/core/evaluation.rs

Large diffs are not rendered by default.

25 changes: 25 additions & 0 deletions server/src/core/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,4 +305,29 @@ impl Model {
}
}
}

pub fn inherits_from(&self, session: &mut SessionInfo, base: &Rc<RefCell<Model>>) -> bool {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is very inefficient, and it is not really used now, it may or not be useful in the future, but it will need some caching of inherit on a class to be efficient.

fn inner(this: &Model, session: &mut SessionInfo, base: &Rc<RefCell<Model>>, checked: &mut HashSet<OYarn>) -> bool {
if checked.contains(&this.name) {
return false;
}
checked.insert(this.name.clone());
for symbol in this.symbols.iter() {
let sym_ref = symbol.borrow();
let Some(model_data) = &sym_ref.as_class_sym()._model else {continue};
for inherit in model_data.inherit.iter() {
if inherit == &base.borrow().name {
return true;
}
if let Some(model) = session.sync_odoo.models.get(inherit).cloned() {
if inner(&model.borrow(), session, base, checked) {
return true;
}
}
}
}
false
}
inner(self, session, base, &mut HashSet::new())
}
}
8 changes: 6 additions & 2 deletions server/src/core/python_arch_eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -743,7 +743,7 @@ impl PythonArchEval {
let mut var_bw = function_sym.borrow_mut();
let is_class_method = var_bw.as_func().is_class_method;
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
symbol.borrow_mut().evaluations_mut().unwrap().push(Evaluation::eval_from_symbol(&Rc::downgrade(self.sym_stack.last().unwrap()), Some(!is_class_method)));
symbol.borrow_mut().evaluations_mut().unwrap().push(Evaluation::new_self(Rc::downgrade(self.sym_stack.last().unwrap()), Some(!is_class_method)));
is_first = false;
continue;
}
Expand Down Expand Up @@ -1011,7 +1011,11 @@ impl PythonArchEval {
None
).len() > 0
){
func_sym.borrow_mut().set_evaluations(vec![Evaluation::new_self()]);
let mut func_ref_mut = func_sym.borrow_mut();
if let Some(base) = func_ref_mut.get_in_parents(&vec![SymType::CLASS], true){
let is_class_method = func_ref_mut.as_func().is_class_method.clone();
func_ref_mut.set_evaluations(vec![Evaluation::new_self(base, Some(!is_class_method))]);
}
return;
}
for eval in evaluations.iter_mut() { //as this is an evaluation, we need to set the instance to true
Expand Down
88 changes: 59 additions & 29 deletions server/src/core/python_arch_eval_hooks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,19 @@ use super::python_arch_eval::PythonArchEval;

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

fn get_base_model_symbol(odoo: &mut SyncOdoo) -> Option<Rc<RefCell<Symbol>>> {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it worth caching that? it is only called a handful of times in the hooks? what do you think ?

let base_model_tree = if compare_semver(odoo.full_version.as_str(), "18.1") >= Ordering::Equal {
(vec![Sy!("odoo"), Sy!("orm"), Sy!("models")], vec![Sy!("BaseModel")])
} else {
(vec![Sy!("odoo"), Sy!("models")], vec![Sy!("BaseModel")])
};
let base_model_symbol = odoo.get_symbol(odoo.config.odoo_path.as_ref().unwrap(), &base_model_tree, u32::MAX);
if !base_model_symbol.is_empty() {
base_model_symbol.first().cloned()
} else {
None
}
}
pub struct PythonArchEvalFileHook {
pub odoo_entry: bool,
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
Expand Down Expand Up @@ -301,7 +314,7 @@ static arch_eval_file_hooks: Lazy<Vec<PythonArchEvalFileHook>> = Lazy::new(|| {v
}
if let Some(boolean) = boolean_field.first() {
let mut eval = Evaluation::eval_from_symbol(&Rc::downgrade(&boolean), Some(true));
let weak = eval.symbol.get_mut_symbol_ptr().as_mut_weak();
let weak = eval.symbol.get_mut_symbol_ptr().get_mut_weak();
weak.context.insert(S!("compute"), ContextValue::STRING(S!("_compute_global")));
symbol.borrow_mut().set_evaluations(vec![eval]);
}
Expand Down Expand Up @@ -469,57 +482,65 @@ static arch_eval_function_hooks: Lazy<Vec<PythonArchEvalFunctionHook>> = Lazy::n
tree: vec![(Sy!("0.0"), Sy!("18.1"), (vec![Sy!("odoo"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("__iter__")])),
(Sy!("18.1"), Sy!("999.0"), (vec![Sy!("odoo"), Sy!("orm"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("__iter__")]))],
if_exist_only: true,
func: |_odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self()]);
func: |odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
let base_model = get_base_model_symbol(odoo);
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self(Rc::downgrade(&base_model.unwrap()), Some(true))]);
}},
PythonArchEvalFunctionHook {odoo_entry: true,
tree: vec![(Sy!("0.0"), Sy!("18.1"), (vec![Sy!("odoo"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("__getitem__")])),
(Sy!("18.1"), Sy!("999.0"), (vec![Sy!("odoo"), Sy!("orm"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("__getitem__")]))],
if_exist_only: true,
func: |_odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self()]);
func: |odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
let base_model = get_base_model_symbol(odoo);
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self(Rc::downgrade(&base_model.unwrap()), Some(true))]);
}},
PythonArchEvalFunctionHook {odoo_entry: true,
tree: vec![(Sy!("0.0"), Sy!("18.1"), (vec![Sy!("odoo"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("with_env")])),
(Sy!("18.1"), Sy!("999.0"), (vec![Sy!("odoo"), Sy!("orm"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("with_env")]))],
if_exist_only: true,
func: |_odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self()]);
func: |odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
let base_model = get_base_model_symbol(odoo);
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self(Rc::downgrade(&base_model.unwrap()), Some(true))]);
}},
PythonArchEvalFunctionHook {odoo_entry: true,
tree: vec![(Sy!("0.0"), Sy!("18.1"), (vec![Sy!("odoo"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("sudo")])),
(Sy!("18.1"), Sy!("999.0"), (vec![Sy!("odoo"), Sy!("orm"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("sudo")]))],
if_exist_only: true,
func: |_odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self()]);
func: |odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
let base_model = get_base_model_symbol(odoo);
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self(Rc::downgrade(&base_model.unwrap()), Some(true))]);
}},
PythonArchEvalFunctionHook {odoo_entry: true,
tree: vec![(Sy!("0.0"), Sy!("18.1"), (vec![Sy!("odoo"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("create")])),
(Sy!("18.1"), Sy!("999.0"), (vec![Sy!("odoo"), Sy!("orm"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("create")]))],
if_exist_only: true,
func: |_odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self()]);
func: |odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
let base_model = get_base_model_symbol(odoo);
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self(Rc::downgrade(&base_model.unwrap()), Some(true))]);
}},
PythonArchEvalFunctionHook {odoo_entry: true,
tree: vec![(Sy!("0.0"), Sy!("18.1"), (vec![Sy!("odoo"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("filtered")])),
(Sy!("18.1"), Sy!("999.0"), (vec![Sy!("odoo"), Sy!("orm"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("filtered")]))],
if_exist_only: true,
func: |_odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self()]);
func: |odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
let base_model = get_base_model_symbol(odoo);
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self(Rc::downgrade(&base_model.unwrap()), Some(true))]);
}},
PythonArchEvalFunctionHook {odoo_entry: true,
tree: vec![(Sy!("0.0"), Sy!("18.1"), (vec![Sy!("odoo"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("filtered_domain")])),
(Sy!("18.1"), Sy!("999.0"), (vec![Sy!("odoo"), Sy!("orm"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("filtered_domain")]))],
if_exist_only: true,
func: |_odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self()]);
func: |odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
let base_model = get_base_model_symbol(odoo);
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self(Rc::downgrade(&base_model.unwrap()), Some(true))]);
}},
PythonArchEvalFunctionHook {odoo_entry: true,
tree: vec![(Sy!("0.0"), Sy!("18.1"), (vec![Sy!("odoo"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("search")])),
(Sy!("18.1"), Sy!("999.0"), (vec![Sy!("odoo"), Sy!("orm"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("search")]))],
if_exist_only: true,
func: |odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self()]);
let base_model = get_base_model_symbol(odoo);
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self(Rc::downgrade(&base_model.unwrap()), Some(true))]);
let search = symbol.borrow();
let func = search.as_func();
if func.args.len() > 1 {
Expand All @@ -536,43 +557,49 @@ static arch_eval_function_hooks: Lazy<Vec<PythonArchEvalFunctionHook>> = Lazy::n
tree: vec![(Sy!("0.0"), Sy!("18.1"), (vec![Sy!("odoo"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("browse")])),
(Sy!("18.1"), Sy!("999.0"), (vec![Sy!("odoo"), Sy!("orm"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("browse")]))],
if_exist_only: true,
func: |_odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self()]);
func: |odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
let base_model = get_base_model_symbol(odoo);
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self(Rc::downgrade(&base_model.unwrap()), Some(true))]);
}},
PythonArchEvalFunctionHook {odoo_entry: true,
tree: vec![(Sy!("0.0"), Sy!("18.1"), (vec![Sy!("odoo"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("with_company")])),
(Sy!("18.1"), Sy!("999.0"), (vec![Sy!("odoo"), Sy!("orm"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("with_company")]))],
if_exist_only: true,
func: |_odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self()]);
func: |odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
let base_model = get_base_model_symbol(odoo);
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self(Rc::downgrade(&base_model.unwrap()), Some(true))]);
}},
PythonArchEvalFunctionHook {odoo_entry: true,
tree: vec![(Sy!("0.0"), Sy!("18.1"), (vec![Sy!("odoo"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("with_context")])),
(Sy!("18.1"), Sy!("999.0"), (vec![Sy!("odoo"), Sy!("orm"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("with_context")]))],
if_exist_only: true,
func: |_odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self()]);
func: |odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
let base_model = get_base_model_symbol(odoo);
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self(Rc::downgrade(&base_model.unwrap()), Some(true))]);
}},
PythonArchEvalFunctionHook {odoo_entry: true,
tree: vec![(Sy!("0.0"), Sy!("18.1"), (vec![Sy!("odoo"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("with_prefetch")])),
(Sy!("18.1"), Sy!("999.0"), (vec![Sy!("odoo"), Sy!("orm"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("with_prefetch")]))],
if_exist_only: true,
func: |_odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self()]);
func: |odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
let base_model = get_base_model_symbol(odoo);
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self(Rc::downgrade(&base_model.unwrap()), Some(true))]);
}},
PythonArchEvalFunctionHook {odoo_entry: true,
tree: vec![(Sy!("0.0"), Sy!("18.1"), (vec![Sy!("odoo"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("with_user")])),
(Sy!("18.1"), Sy!("999.0"), (vec![Sy!("odoo"), Sy!("orm"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("with_user")]))],
if_exist_only: true,
func: |_odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self()]);
func: |odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
let base_model = get_base_model_symbol(odoo);
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self(Rc::downgrade(&base_model.unwrap()), Some(true))]);
}},
PythonArchEvalFunctionHook {odoo_entry: true,
tree: vec![(Sy!("0.0"), Sy!("18.1"), (vec![Sy!("odoo"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("exists")])),
(Sy!("18.1"), Sy!("999.0"), (vec![Sy!("odoo"), Sy!("orm"), Sy!("models")], vec![Sy!("BaseModel"), Sy!("exists")]))],
if_exist_only: true,
func: |_odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self()]);
func: |odoo: &mut SyncOdoo, _entry_point: &Rc<RefCell<EntryPoint>>, symbol: Rc<RefCell<Symbol>>| {
let base_model = get_base_model_symbol(odoo);
symbol.borrow_mut().set_evaluations(vec![Evaluation::new_self(Rc::downgrade(&base_model.unwrap()), Some(true))]);
}},
PythonArchEvalFunctionHook {odoo_entry: true,
tree: vec![(Sy!("0.0"), Sy!("18.1"), (vec![Sy!("odoo"), Sy!("fields")], vec![Sy!("Id"), Sy!("__get__")])),
Expand Down Expand Up @@ -1145,7 +1172,10 @@ impl PythonArchEvalHooks {
let Some(Expr::StringLiteral(expr)) = arguments.args.first() else {return diagnostics};
let returns_str = expr.value.to_string();
if returns_str == S!("self"){
func_sym.borrow_mut().set_evaluations(vec![Evaluation::new_self()]);
if let Some(base) = func_sym.borrow().get_in_parents(&vec![SymType::CLASS], true){
let is_class_method = func_sym.borrow().as_func().is_class_method.clone();
func_sym.borrow_mut().set_evaluations(vec![Evaluation::new_self(base, Some(!is_class_method))]);
}
return diagnostics;
}
let Some(model) = session.sync_odoo.models.get(&oyarn!("{}", returns_str)).cloned() else {
Expand Down
2 changes: 1 addition & 1 deletion server/src/core/python_odoo_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ impl PythonOdooBuilder {
// base_model_syms empty so sym cannot be a model, otherwise we would have found it earlier
return false;
}
if !symbol.borrow().as_class_sym().inherits(&base_model_syms[0], &mut None) {
if !symbol.borrow().as_class_sym().inherits(session, &base_model_syms[0], &mut None) {
return false;
}
// Check if we have a _register = False
Expand Down
Loading