Skip to content

Commit 7787829

Browse files
mmahroussfda-odoo
authored andcommitted
[IMP] gotodef display_name to compute methods
1 parent 6afc2ac commit 7787829

File tree

3 files changed

+80
-13
lines changed

3 files changed

+80
-13
lines changed

server/src/features/ast_utils.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::core::evaluation::{AnalyzeAstResult, Context, ContextValue, Evaluatio
66
use crate::core::odoo::SyncOdoo;
77
use crate::core::import_resolver::{resolve_from_stmt, resolve_import_stmt};
88
use crate::core::symbols::symbol::Symbol;
9-
use crate::core::file_mgr::FileInfo;
9+
use crate::core::file_mgr::{FileInfo, FileInfoAst};
1010
use crate::threads::SessionInfo;
1111
use crate::S;
1212
use ruff_python_ast::name::Name;
@@ -19,11 +19,9 @@ pub struct AstUtils {}
1919

2020
impl AstUtils {
2121

22-
pub fn get_symbols(session: &mut SessionInfo, file_symbol: &Rc<RefCell<Symbol>>, file_info: &Rc<RefCell<FileInfo>>, offset: u32) -> (AnalyzeAstResult, Option<TextRange>, Option<ExprCall>) {
23-
let mut expr: Option<ExprOrIdent> = None;
22+
pub fn get_expr<'a>(file_info_ast: &'a FileInfoAst, offset: u32) -> (Option<ExprOrIdent<'a>>, Option<ExprCall>) {
23+
let mut expr: Option<ExprOrIdent<'a>> = None;
2424
let mut call_expr: Option<ExprCall> = None;
25-
let file_info_ast = file_info.borrow().file_info_ast.clone();
26-
let file_info_ast = file_info_ast.borrow();
2725
for stmt in file_info_ast.get_stmts().unwrap().iter() {
2826
//we have to handle imports differently as symbols are not visible in file.
2927
if let Some(test_import) = Self::get_symbol_in_import(session, file_symbol, offset, stmt) {
@@ -34,10 +32,13 @@ impl AstUtils {
3432
break;
3533
}
3634
}
37-
let Some(expr) = expr else {
35+
if expr.is_none() {
3836
warn!("expr not found");
39-
return (AnalyzeAstResult::default(), None, None);
40-
};
37+
}
38+
(expr, call_expr)
39+
}
40+
41+
pub fn get_symbols(session: &mut SessionInfo, file_symbol: &Rc<RefCell<Symbol>>, offset: u32, expr: &ExprOrIdent) -> (AnalyzeAstResult, Option<TextRange>) {
4142
let parent_symbol = Symbol::get_scope_symbol(file_symbol.clone(), offset, matches!(expr, ExprOrIdent::Parameter(_)));
4243
AstUtils::build_scope(session, &parent_symbol);
4344
let from_module;
@@ -51,7 +52,7 @@ impl AstUtils {
5152
(S!("range"), ContextValue::RANGE(expr.range()))
5253
]));
5354
let analyse_ast_result: AnalyzeAstResult = Evaluation::analyze_ast(session, &expr, parent_symbol.clone(), &expr.range().end(), &mut context,false, &mut vec![]);
54-
(analyse_ast_result, Some(expr.range()), call_expr)
55+
(analyse_ast_result, Some(expr.range()))
5556

5657
}
5758

server/src/features/definition.rs

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@ use std::path::PathBuf;
55
use std::{cell::RefCell, rc::Rc};
66

77
use crate::constants::SymType;
8-
use crate::core::evaluation::{Evaluation, EvaluationValue};
8+
use crate::core::evaluation::{Evaluation, EvaluationValue, ExprOrIdent};
99
use crate::core::file_mgr::{FileInfo, FileMgr};
1010
use crate::core::odoo::SyncOdoo;
1111
use crate::core::python_odoo_builder::MAGIC_FIELDS;
1212
use crate::core::symbols::symbol::Symbol;
1313
use crate::features::ast_utils::AstUtils;
1414
use crate::features::features_utils::FeaturesUtils;
1515
use crate::features::xml_ast_utils::{XmlAstResult, XmlAstUtils};
16-
use crate::oyarn;
16+
use crate::{S, oyarn};
1717
use crate::threads::SessionInfo;
1818
use crate::utils::PathSanitizer as _;
1919

@@ -149,33 +149,91 @@ impl DefinitionFeature {
149149
compute_symbols.len() > 0
150150
}
151151

152+
pub fn add_display_name_compute_methods(session: &mut SessionInfo, links: &mut Vec<LocationLink>, expr: &ExprOrIdent, file_symbol: &Rc<RefCell<Symbol>>, offset: usize) {
153+
// now we want `_compute_display_name` definition(s)
154+
// we need the symbol of the model/ then we run get member symbol
155+
// to do that, we need the expr, match it to attribute, get the value, get its evals
156+
// with those evals, we run get_member_symbol on `_compute_display_name`
157+
let crate::core::evaluation::ExprOrIdent::Expr(Expr::Attribute(attr_expr)) = expr else {
158+
return;
159+
};
160+
let (analyse_ast_result, _range) = AstUtils::get_symbols(session, file_symbol, offset as u32, &crate::core::evaluation::ExprOrIdent::Expr(&attr_expr.value));
161+
let eval_ptrs = analyse_ast_result.evaluations.iter().flat_map(|eval| Symbol::follow_ref(eval.symbol.get_symbol_ptr(), session, &mut None, false, false, None)).collect::<Vec<_>>();
162+
let maybe_module = file_symbol.borrow().find_module();
163+
let symbols = eval_ptrs.iter().flat_map(|eval_ptr| {
164+
let Some(symbol) = eval_ptr.upgrade_weak() else {
165+
return vec![];
166+
};
167+
symbol.borrow().get_member_symbol(session, &S!("_compute_display_name"), maybe_module.clone(), false, false, true, false).0
168+
}).collect::<Vec<_>>();
169+
for symbol in symbols {
170+
if let Some(file) = symbol.borrow().get_file() {
171+
for path in file.upgrade().unwrap().borrow().paths().iter() {
172+
let full_path = match file.upgrade().unwrap().borrow().typ() {
173+
SymType::PACKAGE(_) => PathBuf::from(path).join(format!("__init__.py{}", file.upgrade().unwrap().borrow().as_package().i_ext())).sanitize(),
174+
_ => path.clone()
175+
};
176+
let range = if symbol.borrow().has_range() {
177+
if symbol.borrow().range().contains(TextSize::new(offset as u32)) {
178+
continue; //skip if we are already on the definition
179+
}
180+
session.sync_odoo.get_file_mgr().borrow().text_range_to_range(session, &full_path, &symbol.borrow().range())
181+
} else {
182+
Range::default()
183+
};
184+
links.push(LocationLink{
185+
origin_selection_range: None,
186+
target_uri: FileMgr::pathname2uri(&full_path),
187+
target_selection_range: range,
188+
target_range: range,
189+
});
190+
}
191+
}
192+
}
193+
}
194+
152195
pub fn get_location(session: &mut SessionInfo,
153196
file_symbol: &Rc<RefCell<Symbol>>,
154197
file_info: &Rc<RefCell<FileInfo>>,
155198
line: u32,
156199
character: u32
157200
) -> Option<GotoDefinitionResponse> {
158201
let offset = file_info.borrow().position_to_offset(line, character);
159-
let (analyse_ast_result, _range, call_expr) = AstUtils::get_symbols(session, file_symbol, file_info, offset as u32);
202+
let file_info_ast_clone = file_info.borrow().file_info_ast.clone();
203+
let file_info_ast_ref = file_info_ast_clone.borrow();
204+
let (expr, call_expr) = AstUtils::get_expr(&file_info_ast_ref, offset as u32);
205+
let Some(expr) = expr else {
206+
return None;
207+
};
208+
let (analyse_ast_result, _range) = AstUtils::get_symbols(session, file_symbol, offset as u32, &expr);
160209
if analyse_ast_result.evaluations.is_empty() {
161210
return None;
162211
}
163212
let mut links = vec![];
164213
let mut evaluations = analyse_ast_result.evaluations.clone();
165214
// Filter out magic fields
215+
let mut dislay_name_found = false;
166216
evaluations.retain(|eval| {
167217
// Filter out, variables, whose parents are a class, whose name is one of the magic fields, and have the same range as their parent
168218
let eval_sym = eval.symbol.get_symbol(session, &mut None, &mut vec![], None);
169219
let Some(eval_sym) = eval_sym.upgrade_weak() else { return true; };
170220
if !MAGIC_FIELDS.contains(&eval_sym.borrow().name().as_str()) || eval_sym.borrow().typ() != SymType::VARIABLE || !eval_sym.borrow().is_field(session) {
171221
return true;
172222
}
223+
if eval_sym.borrow().name() == "display_name" {
224+
dislay_name_found = true;
225+
}
173226
let Some(parent_sym) = eval_sym.borrow().parent().and_then(|parent| parent.upgrade()) else { return true; };
174227
if parent_sym.borrow().typ() != SymType::CLASS {
175228
return true;
176229
}
177230
eval_sym.borrow().range() != parent_sym.borrow().range()
178231
});
232+
if dislay_name_found {
233+
DefinitionFeature::add_display_name_compute_methods(session, &mut links, &expr, file_symbol, offset);
234+
}
235+
drop(expr);
236+
drop(file_info_ast_ref);
179237
let mut index = 0;
180238
while index < evaluations.len() {
181239
let eval = evaluations[index].clone();

server/src/features/hover.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,19 @@ impl HoverFeature {
1616

1717
pub fn hover_python(session: &mut SessionInfo, file_symbol: &Rc<RefCell<Symbol>>, file_info: &Rc<RefCell<FileInfo>>, line: u32, character: u32) -> Option<Hover> {
1818
let offset = file_info.borrow().position_to_offset(line, character);
19-
let (analyse_ast_result, range, call_expr) = AstUtils::get_symbols(session, file_symbol, file_info, offset as u32);
19+
let file_info_ast_clone = file_info.borrow().file_info_ast.clone();
20+
let file_info_ast_ref = file_info_ast_clone.borrow();
21+
let (expr, call_expr) = AstUtils::get_expr(&file_info_ast_ref, offset as u32);
22+
let Some(expr) = expr else {
23+
return None;
24+
};
25+
let (analyse_ast_result, range) = AstUtils::get_symbols(session, file_symbol, offset as u32, &expr);
2026
let evals = analyse_ast_result.evaluations;
2127
if evals.is_empty() {
2228
return None;
2329
};
30+
drop(expr);
31+
drop(file_info_ast_ref);
2432
let range = Some(file_info.borrow().text_range_to_range(&range.unwrap()));
2533
Some(Hover { contents:
2634
HoverContents::Markup(MarkupContent {

0 commit comments

Comments
 (0)