Skip to content

Commit 0480b5e

Browse files
mmahroussfda-odoo
authored andcommitted
[FIX] server: fix is_field_class check
also add some instance values when needed and evaluate generic types naïvely
1 parent 08be586 commit 0480b5e

File tree

3 files changed

+82
-15
lines changed

3 files changed

+82
-15
lines changed

server/src/core/evaluation.rs

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,7 +1005,11 @@ impl Evaluation {
10051005
if !attributes.is_empty() {
10061006
let is_instance = ibase.as_weak().instance.unwrap_or(false);
10071007
attributes.iter().for_each(|attribute|{
1008-
let mut eval = Evaluation::eval_from_symbol(&Rc::downgrade(attribute), None);
1008+
let instance = match attribute.borrow().typ() {
1009+
SymType::CLASS => Some(false),
1010+
_ => None
1011+
};
1012+
let mut eval = Evaluation::eval_from_symbol(&Rc::downgrade(attribute), instance);
10091013
match eval.symbol.sym {
10101014
EvaluationSymbolPtr::WEAK(ref mut weak) => {
10111015
weak.context.insert(S!("base_attr"), ContextValue::SYMBOL(Rc::downgrade(&base_loc)));
@@ -1059,13 +1063,17 @@ impl Evaluation {
10591063
return AnalyzeAstResult::from_only_diagnostics(diagnostics);
10601064
}
10611065
for inferred_sym in inferred_syms.symbols.iter() {
1062-
evals.push(Evaluation::eval_from_symbol(&Rc::downgrade(inferred_sym), None));
1066+
let instance = match inferred_sym.borrow().typ() {
1067+
SymType::CLASS => Some(false),
1068+
_ => None
1069+
};
1070+
evals.push(Evaluation::eval_from_symbol(&Rc::downgrade(inferred_sym), instance));
10631071
}
10641072
if !inferred_syms.always_defined{
10651073
evals.push(Evaluation::new_unbound(name));
10661074
}
10671075
},
1068-
ExprOrIdent::Expr(Expr::Subscript(sub)) => {
1076+
ExprOrIdent::Expr(Expr::Subscript(sub)) => 'subscript_block: {
10691077
let (eval_left, diags) = Evaluation::eval_from_ast(session, &sub.value, parent.clone(), max_infer, required_dependencies);
10701078
diagnostics.extend(diags);
10711079
// TODO handle multiple eval_left
@@ -1080,20 +1088,38 @@ impl Evaluation {
10801088
if bases.len() != 1 {
10811089
return AnalyzeAstResult::from_only_diagnostics(diagnostics);
10821090
}
1083-
let parent_file_or_func = parent.clone().borrow().parent_file_or_function().as_ref().unwrap().upgrade().unwrap();
1084-
let is_in_validation = match parent_file_or_func.borrow().typ().clone() {
1085-
SymType::FILE | SymType::PACKAGE(_) | SymType::FUNCTION => {
1086-
parent_file_or_func.borrow().build_status(BuildSteps::VALIDATION) == BuildStatus::IN_PROGRESS
1087-
},
1088-
_ => {false}
1089-
};
1091+
let base = &bases[0];
1092+
match base {
1093+
EvaluationSymbolPtr::WEAK(base_sym_weak_eval) if base_sym_weak_eval.instance == Some(false) => {
1094+
if let Some(SymType::CLASS) = base.upgrade_weak().map(|s| s.borrow().typ()) {
1095+
// This is a Generic type (Field[int], or List[int]), for now we just return the main type/Class (Field/List)
1096+
// TODO: handle generic types
1097+
evals.push(Evaluation {
1098+
symbol: EvaluationSymbol {
1099+
sym: base.clone(),
1100+
get_symbol_hook: None,
1101+
},
1102+
value: None,
1103+
range: Some(sub.range())
1104+
});
1105+
break 'subscript_block;
1106+
}
1107+
}
1108+
_ => {}
1109+
}
10901110
let value = Evaluation::expr_to_str(session, &sub.slice, parent.clone(), max_infer, &mut diagnostics);
10911111
diagnostics.extend(value.1);
10921112
if let Some(value) = value.0 {
1093-
let base = &bases[0];
10941113
if !base.is_weak() {
10951114
return AnalyzeAstResult::from_only_diagnostics(diagnostics);
10961115
}
1116+
let parent_file_or_func = parent.clone().borrow().parent_file_or_function().as_ref().unwrap().upgrade().unwrap();
1117+
let is_in_validation = match parent_file_or_func.borrow().typ().clone() {
1118+
SymType::FILE | SymType::PACKAGE(_) | SymType::FUNCTION => {
1119+
parent_file_or_func.borrow().build_status(BuildSteps::VALIDATION) == BuildStatus::IN_PROGRESS
1120+
},
1121+
_ => {false}
1122+
};
10971123
let base = base.upgrade_weak().unwrap();
10981124
let get_item = base.borrow().get_content_symbol("__getitem__", u32::MAX).symbols;
10991125
if get_item.len() == 1 {

server/src/core/python_arch_eval.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,11 @@ impl PythonArchEval {
394394
let import_sym_ref = _import_result.symbol.clone();
395395
let has_loop = self.check_for_loop_evaluation(session, import_sym_ref, &variable);
396396
if !has_loop { //anti-loop. We want to be sure we are not evaluating to the same sym
397-
variable.borrow_mut().set_evaluations(vec![Evaluation::eval_from_symbol(&Rc::downgrade(&_import_result.symbol), None)]);
397+
let instance = match _import_result.symbol.borrow().typ() {
398+
SymType::CLASS => Some(false),
399+
_ => None
400+
};
401+
variable.borrow_mut().set_evaluations(vec![Evaluation::eval_from_symbol(&Rc::downgrade(&_import_result.symbol), instance)]);
398402
let file_of_import_symbol = _import_result.symbol.borrow().get_file();
399403
if let Some(import_file) = file_of_import_symbol {
400404
let import_file = import_file.upgrade().unwrap();

server/src/core/symbols/symbol.rs

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2477,11 +2477,43 @@ impl Symbol {
24772477
}
24782478
}
24792479

2480+
pub fn is_inheriting_from_field(&self, session: &mut SessionInfo) -> bool {
2481+
// if not class return false
2482+
if !matches!(self.typ(), SymType::CLASS) {
2483+
return false;
2484+
}
2485+
let tree = flatten_tree(&self.get_main_entry_tree(session));
2486+
if session.sync_odoo.full_version <= S!("18.0") {
2487+
if tree.len() == 3 && tree[0] == "odoo" && tree[1] == "fields" {
2488+
if tree[2].as_str() == "Field" {
2489+
return true;
2490+
}
2491+
}
2492+
} else {
2493+
if tree.len() == 4 && tree[0] == "odoo" && tree[1] == "orm" && (
2494+
tree[2] == "fields" && tree[3] == "Field"
2495+
){
2496+
return true;
2497+
}
2498+
}
2499+
// Follow class inheritance
2500+
for base in self.as_class_sym().bases.iter().map(|weak_base| weak_base.upgrade()).flatten() {
2501+
if base.borrow().is_inheriting_from_field(session) {
2502+
return true;
2503+
}
2504+
}
2505+
false
2506+
}
2507+
24802508
pub fn is_field_class(&self, session: &mut SessionInfo) -> bool {
2509+
// if not class return false
2510+
if !matches!(self.typ(), SymType::CLASS) {
2511+
return false;
2512+
}
24812513
let tree = flatten_tree(&self.get_main_entry_tree(session));
24822514
if compare_semver(session.sync_odoo.full_version.as_str(), "18.1.0") >= Ordering::Equal {
2483-
if tree.len() == 4 && tree[0] == "odoo" && tree[1] == "orm" {
2484-
return tree[2] == "fields_misc" && tree[3] == "Boolean" ||
2515+
if tree.len() == 4 && tree[0] == "odoo" && tree[1] == "orm" && (
2516+
tree[2] == "fields_misc" && tree[3] == "Boolean" ||
24852517
tree[2] == "fields_numeric" && tree[3] == "Integer" ||
24862518
tree[2] == "fields_numeric" && tree[3] == "Float" ||
24872519
tree[2] == "fields_numeric" && tree[3] == "Monetary" ||
@@ -2501,7 +2533,9 @@ impl Symbol {
25012533
tree[2] == "fields_properties" && tree[3] == "PropertiesDefinition" ||
25022534
tree[2] == "fields_relational" && tree[3] == "One2many" ||
25032535
tree[2] == "fields_relational" && tree[3] == "Many2many" ||
2504-
tree[2] == "fields_misc" && tree[3] == "Id";
2536+
tree[2] == "fields_misc" && tree[3] == "Id"
2537+
){
2538+
return true;
25052539
}
25062540
} else {
25072541
if tree.len() == 3 && tree[0] == "odoo" && tree[1] == "fields" {
@@ -2511,6 +2545,9 @@ impl Symbol {
25112545
}
25122546
}
25132547
}
2548+
if self.is_inheriting_from_field(session) {
2549+
return true;
2550+
}
25142551
false
25152552
}
25162553

0 commit comments

Comments
 (0)