Skip to content
Open
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: 52 additions & 49 deletions server/src/features/completion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -590,67 +590,70 @@ fn complete_call(session: &mut SessionInfo, file: &Rc<RefCell<Symbol>>, expr_cal
let scope = Symbol::get_scope_symbol(file.clone(), offset as u32, is_param);
AstUtils::build_scope(session, &scope);
let callable_evals = Evaluation::eval_from_ast(session, &expr_call.func, scope, &expr_call.func.range().start(), false, &mut vec![]).0;
for (arg_index, arg) in expr_call.arguments.args.iter().enumerate() {
if offset > arg.range().start().to_usize() && offset <= arg.range().end().to_usize() {
for callable_eval in callable_evals.iter() {
let callable = callable_eval.symbol.get_symbol_as_weak(session, &mut None, &mut vec![], None);
let Some(callable_sym) = callable.weak.upgrade() else {continue};
match callable_sym.borrow().typ(){
SymType::FUNCTION => {
let func = callable_sym.borrow();
let func = func.as_func();
let func_arg = func.get_indexed_arg_in_call(
expr_call,
arg_index as u32,
callable.context.get(&S!("is_attr_of_instance")).map(|v| v.as_bool()));
if let Some(func_arg) = func_arg {
if let Some(func_arg_sym) = func_arg.symbol.upgrade() {
let mut expected_type = vec![];
for evaluation in func_arg_sym.borrow().evaluations().unwrap().iter() {
match evaluation.symbol.get_symbol_ptr() {
EvaluationSymbolPtr::WEAK(_weak) => {
//if weak, use get_symbol
let symbol= evaluation.symbol.get_symbol_as_weak(session, &mut None, &mut vec![], None);
if let Some(evaluation) = symbol.weak.upgrade() {
if evaluation.borrow().typ() == SymType::CLASS {
expected_type.push(ExpectedType::CLASS(evaluation.clone()));
}
}
},
EvaluationSymbolPtr::DOMAIN => {
if let Some(parent) = callable.context.get(&S!("base_attr"))
.and_then(|parent_value| parent_value.as_symbol().upgrade()) {
expected_type.push(ExpectedType::DOMAIN(parent));
let callable_eval_sym_ptrs = callable_evals.iter().flat_map(|callable_eval|
Symbol::follow_ref(&callable_eval.symbol.get_symbol(session, &mut None, &mut vec![], None), session, &mut None, false, false, None, None)
).collect::<Vec<_>>();
if let Some((arg_index, arg)) = expr_call.arguments.args.iter().find_position(|arg|
offset > arg.range().start().to_usize() && offset <= arg.range().end().to_usize()
){
for callable_eval in callable_evals.iter() {
let callable = callable_eval.symbol.get_symbol_as_weak(session, &mut None, &mut vec![], None);
let Some(callable_sym) = callable.weak.upgrade() else {continue};
match callable_sym.borrow().typ(){
SymType::FUNCTION => {
let func = callable_sym.borrow();
let func = func.as_func();
let func_arg = func.get_indexed_arg_in_call(
expr_call,
arg_index as u32,
callable.context.get(&S!("is_attr_of_instance")).map(|v| v.as_bool()));
if let Some(func_arg) = func_arg {
if let Some(func_arg_sym) = func_arg.symbol.upgrade() {
let mut expected_type = vec![];
for evaluation in func_arg_sym.borrow().evaluations().unwrap().iter() {
match evaluation.symbol.get_symbol_ptr() {
EvaluationSymbolPtr::WEAK(_weak) => {
//if weak, use get_symbol
let symbol= evaluation.symbol.get_symbol_as_weak(session, &mut None, &mut vec![], None);
if let Some(evaluation) = symbol.weak.upgrade() {
if evaluation.borrow().typ() == SymType::CLASS {
expected_type.push(ExpectedType::CLASS(evaluation.clone()));
}
}
_ => {}
},
EvaluationSymbolPtr::DOMAIN => {
if let Some(parent) = callable.context.get(&S!("base_attr"))
.and_then(|parent_value| parent_value.as_symbol().upgrade()) {
expected_type.push(ExpectedType::DOMAIN(parent));
}
}
_ => {}
}
return complete_expr(arg, session, file, offset, is_param, &expected_type);
}
return complete_expr(arg, session, file, offset, is_param, &expected_type);
}
},
SymType::CLASS => {
// check for completion of first positional argument for comodel_name
if arg_index != 0 || !callable_sym.borrow().is_specific_field_class(session, &["Many2one", "One2many", "Many2many"]) {
break;
}
return complete_expr(arg, session, file, offset, is_param, &vec![ExpectedType::MODEL_NAME]);
},
_ => {}
};
}
//if we didn't find anything, still try to complete
return complete_expr(arg, session, file, offset, is_param, &vec![]);
}
},
SymType::CLASS => {
// check for completion of first positional argument for comodel_name
if arg_index != 0 || !callable_sym.borrow().is_specific_field_class(session, &["Many2one", "One2many", "Many2many"]) {
break;
}
return complete_expr(arg, session, file, offset, is_param, &vec![ExpectedType::MODEL_NAME]);
},
_ => {}
};
}
//if we didn't find anything, still try to complete
return complete_expr(arg, session, file, offset, is_param, &vec![]);
}
let Some(keyword) = expr_call.arguments.keywords.iter().find(|arg|
offset > arg.range().start().to_usize() && offset <= arg.range().end().to_usize()) else {
return None;
};
for callable_eval in callable_evals.iter() {
let callable = callable_eval.symbol.get_symbol_as_weak(session, &mut None, &mut vec![], None);
let Some(callable_sym) = callable.weak.upgrade() else {continue};
for callable_eval_sym_ptr in callable_eval_sym_ptrs.iter() {
let callable = callable_eval_sym_ptr.upgrade_weak();
let Some(callable_sym) = callable else {return None;};
if callable_sym.borrow().typ() != SymType::CLASS || !callable_sym.borrow().is_field_class(session){
continue;
}
Expand Down