Skip to content

Commit 97ff9c4

Browse files
mmahroussfda-odoo
authored andcommitted
[IMP] completion for inverse_name keyword argument
1 parent be03391 commit 97ff9c4

File tree

2 files changed

+45
-26
lines changed

2 files changed

+45
-26
lines changed

server/src/features/completion.rs

Lines changed: 44 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ pub enum ExpectedType {
3434
CLASS(Rc<RefCell<Symbol>>),
3535
SIMPLE_FIELD(Option<OYarn>),
3636
NESTED_FIELD(Option<OYarn>),
37+
EXTERNAL_FIELD(OYarn), // Like in inverse_name='field_name', we attach the comodel_name
3738
METHOD_NAME,
3839
INHERITS,
3940
}
@@ -641,35 +642,44 @@ fn complete_call(session: &mut SessionInfo, file: &Rc<RefCell<Symbol>>, expr_cal
641642
return complete_expr(arg, session, file, offset, is_param, &vec![]);
642643
}
643644
}
644-
for keyword in expr_call.arguments.keywords.iter(){
645-
if offset <= keyword.value.range().start().to_usize() || offset > keyword.value.range().end().to_usize() {
645+
let Some(keyword) = expr_call.arguments.keywords.iter().find(|arg|
646+
offset > arg.range().start().to_usize() && offset <= arg.range().end().to_usize()) else {
647+
return None;
648+
};
649+
for callable_eval in callable_evals.iter() {
650+
let callable = callable_eval.symbol.get_symbol_as_weak(session, &mut None, &mut vec![], None);
651+
let Some(callable_sym) = callable.weak.upgrade() else {continue};
652+
if callable_sym.borrow().typ() != SymType::CLASS || !callable_sym.borrow().is_field_class(session){
646653
continue;
647654
}
648-
for callable_eval in callable_evals.iter() {
649-
let callable = callable_eval.symbol.get_symbol_as_weak(session, &mut None, &mut vec![], None);
650-
let Some(callable_sym) = callable.weak.upgrade() else {continue};
651-
if callable_sym.borrow().typ() != SymType::CLASS || !callable_sym.borrow().is_field_class(session){
652-
continue;
655+
let Some(expected_type) = keyword.arg.as_ref().and_then(|kw_arg_id|
656+
match kw_arg_id.id.as_str() {
657+
"related" => Some(vec![ExpectedType::NESTED_FIELD(Some(oyarn!("{}", callable_sym.borrow().name())))]),
658+
"comodel_name" => if callable_sym.borrow().is_specific_field_class(session, &["Many2one", "One2many", "Many2many"]){
659+
Some(vec![ExpectedType::MODEL_NAME])
660+
} else {
661+
None
662+
},
663+
"inverse_name" => {
664+
if let Some(Expr::StringLiteral(expr)) = expr_call.arguments.args.first() {
665+
Some(vec![ExpectedType::EXTERNAL_FIELD(Sy!(expr.value.to_string()))])
666+
} else {
667+
expr_call.arguments.keywords.iter().find(|kw| kw.arg.as_ref().map(|arg| arg.id == "comodel_name").unwrap_or(false))
668+
.and_then(|kw| match &kw.value {
669+
Expr::StringLiteral(expr) => Some(vec![ExpectedType::EXTERNAL_FIELD(Sy!(expr.value.to_string()))]),
670+
_ => None
671+
})
672+
}
673+
},
674+
"inverse" | "search" | "compute" => Some(vec![ExpectedType::METHOD_NAME]),
675+
_ => None,
653676
}
654-
let Some(expected_type) = keyword.arg.as_ref().and_then(|kw_arg_id|
655-
match kw_arg_id.id.as_str() {
656-
"related" => Some(vec![ExpectedType::NESTED_FIELD(Some(oyarn!("{}", callable_sym.borrow().name())))]),
657-
"comodel_name" => if callable_sym.borrow().is_specific_field_class(session, &["Many2one", "One2many", "Many2many"]){
658-
Some(vec![ExpectedType::MODEL_NAME])
659-
} else {
660-
None
661-
},
662-
"inverse" | "search" | "compute" => Some(vec![ExpectedType::METHOD_NAME]),
663-
_ => None,
664-
}
665-
) else {
666-
continue;
667-
};
668-
return complete_expr(&keyword.value, session, file, offset, is_param, &expected_type);
669-
}
670-
return complete_expr(&keyword.value, session, file, offset, is_param, &vec![]);
677+
) else {
678+
continue;
679+
};
680+
return complete_expr(&keyword.value, session, file, offset, is_param, &expected_type);
671681
}
672-
None
682+
return complete_expr(&keyword.value, session, file, offset, is_param, &vec![]);
673683
}
674684

675685
fn complete_string_literal(session: &mut SessionInfo, file: &Rc<RefCell<Symbol>>, expr_string_literal: &ruff_python_ast::ExprStringLiteral, _offset: usize, _is_param: bool, expected_type: &Vec<ExpectedType>) -> Option<CompletionResponse> {
@@ -774,6 +784,15 @@ fn complete_string_literal(session: &mut SessionInfo, file: &Rc<RefCell<Symbol>>
774784
_ => unreachable!()
775785
}
776786
},
787+
ExpectedType::EXTERNAL_FIELD(model_name) => {
788+
let Some(model) = session.sync_odoo.models.get(&oyarn!("{}", model_name)).cloned() else {
789+
break;
790+
};
791+
let main_syms = model.borrow().get_main_symbols(session, current_module.clone());
792+
main_syms.iter().for_each(|model_sym| {
793+
add_model_attributes(session, &mut items, current_module.clone(), model_sym.clone(), false, true, false, expr_string_literal.value.to_str(), &Some(S!("Many2one")))
794+
});
795+
},
777796
ExpectedType::CLASS(_) => {},
778797
ExpectedType::INHERITS => {},
779798
}

server/src/features/features_utils.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ impl FeaturesUtils {
5353
call_expr: &ExprCall,
5454
offset: &usize,
5555
) -> Vec<Rc<RefCell<Symbol>>>{
56-
if let Some((_, keyword)) = call_expr.arguments.keywords.iter().enumerate().find(|(_, arg)|
56+
if let Some(keyword) = call_expr.arguments.keywords.iter().find(|arg|
5757
*offset > arg.range().start().to_usize() && *offset <= arg.range().end().to_usize()
5858
){
5959
let Some(ref arg_id) = keyword.arg else {

0 commit comments

Comments
 (0)