Skip to content

Commit 2da5a58

Browse files
committed
[FIX] server: fix is_field_class check
also add some instance values when needed and evaluate generic types naïvely
1 parent f051895 commit 2da5a58

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
@@ -1012,7 +1012,11 @@ impl Evaluation {
10121012
if !attributes.is_empty() {
10131013
let is_instance = ibase.as_weak().instance.unwrap_or(false);
10141014
attributes.iter().for_each(|attribute|{
1015-
let mut eval = Evaluation::eval_from_symbol(&Rc::downgrade(attribute), None);
1015+
let instance = match attribute.borrow().typ() {
1016+
SymType::CLASS => Some(false),
1017+
_ => None
1018+
};
1019+
let mut eval = Evaluation::eval_from_symbol(&Rc::downgrade(attribute), instance);
10161020
match eval.symbol.sym {
10171021
EvaluationSymbolPtr::WEAK(ref mut weak) => {
10181022
weak.context.insert(S!("base_attr"), ContextValue::SYMBOL(Rc::downgrade(&base_loc)));
@@ -1066,13 +1070,17 @@ impl Evaluation {
10661070
return AnalyzeAstResult::from_only_diagnostics(diagnostics);
10671071
}
10681072
for inferred_sym in inferred_syms.symbols.iter() {
1069-
evals.push(Evaluation::eval_from_symbol(&Rc::downgrade(inferred_sym), None));
1073+
let instance = match inferred_sym.borrow().typ() {
1074+
SymType::CLASS => Some(false),
1075+
_ => None
1076+
};
1077+
evals.push(Evaluation::eval_from_symbol(&Rc::downgrade(inferred_sym), instance));
10701078
}
10711079
if !inferred_syms.always_defined{
10721080
evals.push(Evaluation::new_unbound(name));
10731081
}
10741082
},
1075-
ExprOrIdent::Expr(Expr::Subscript(sub)) => {
1083+
ExprOrIdent::Expr(Expr::Subscript(sub)) => 'subscript_block: {
10761084
let (eval_left, diags) = Evaluation::eval_from_ast(session, &sub.value, parent.clone(), max_infer, required_dependencies);
10771085
diagnostics.extend(diags);
10781086
// TODO handle multiple eval_left
@@ -1087,20 +1095,38 @@ impl Evaluation {
10871095
if bases.len() != 1 {
10881096
return AnalyzeAstResult::from_only_diagnostics(diagnostics);
10891097
}
1090-
let parent_file_or_func = parent.clone().borrow().parent_file_or_function().as_ref().unwrap().upgrade().unwrap();
1091-
let is_in_validation = match parent_file_or_func.borrow().typ().clone() {
1092-
SymType::FILE | SymType::PACKAGE(_) | SymType::FUNCTION => {
1093-
parent_file_or_func.borrow().build_status(BuildSteps::VALIDATION) == BuildStatus::IN_PROGRESS
1094-
},
1095-
_ => {false}
1096-
};
1098+
let base = &bases[0];
1099+
match base {
1100+
EvaluationSymbolPtr::WEAK(base_sym_weak_eval) if base_sym_weak_eval.instance == Some(false) => {
1101+
if let Some(SymType::CLASS) = base.upgrade_weak().map(|s| s.borrow().typ()) {
1102+
// This is a Generic type (Field[int], or List[int]), for now we just return the main type/Class (Field/List)
1103+
// TODO: handle generic types
1104+
evals.push(Evaluation {
1105+
symbol: EvaluationSymbol {
1106+
sym: base.clone(),
1107+
get_symbol_hook: None,
1108+
},
1109+
value: None,
1110+
range: Some(sub.range())
1111+
});
1112+
break 'subscript_block;
1113+
}
1114+
}
1115+
_ => {}
1116+
}
10971117
let value = Evaluation::expr_to_str(session, &sub.slice, parent.clone(), max_infer, &mut diagnostics);
10981118
diagnostics.extend(value.1);
10991119
if let Some(value) = value.0 {
1100-
let base = &bases[0];
11011120
if !base.is_weak() {
11021121
return AnalyzeAstResult::from_only_diagnostics(diagnostics);
11031122
}
1123+
let parent_file_or_func = parent.clone().borrow().parent_file_or_function().as_ref().unwrap().upgrade().unwrap();
1124+
let is_in_validation = match parent_file_or_func.borrow().typ().clone() {
1125+
SymType::FILE | SymType::PACKAGE(_) | SymType::FUNCTION => {
1126+
parent_file_or_func.borrow().build_status(BuildSteps::VALIDATION) == BuildStatus::IN_PROGRESS
1127+
},
1128+
_ => {false}
1129+
};
11041130
let base = base.upgrade_weak().unwrap();
11051131
let get_item = base.borrow().get_content_symbol("__getitem__", u32::MAX).symbols;
11061132
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
@@ -393,7 +393,11 @@ impl PythonArchEval {
393393
let import_sym_ref = _import_result.symbol.clone();
394394
let has_loop = self.check_for_loop_evaluation(session, import_sym_ref, &variable);
395395
if !has_loop { //anti-loop. We want to be sure we are not evaluating to the same sym
396-
variable.borrow_mut().set_evaluations(vec![Evaluation::eval_from_symbol(&Rc::downgrade(&_import_result.symbol), None)]);
396+
let instance = match _import_result.symbol.borrow().typ() {
397+
SymType::CLASS => Some(false),
398+
_ => None
399+
};
400+
variable.borrow_mut().set_evaluations(vec![Evaluation::eval_from_symbol(&Rc::downgrade(&_import_result.symbol), instance)]);
397401
let file_of_import_symbol = _import_result.symbol.borrow().get_file();
398402
if let Some(import_file) = file_of_import_symbol {
399403
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
@@ -2476,11 +2476,43 @@ impl Symbol {
24762476
}
24772477
}
24782478

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

0 commit comments

Comments
 (0)