Skip to content

Commit de0acbc

Browse files
committed
[IMP] gotodef display_name to compute methods
1 parent e1a695c commit de0acbc

File tree

4 files changed

+89
-29
lines changed

4 files changed

+89
-29
lines changed

server/src/core/evaluation.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,13 @@ pub struct Evaluation {
7575
}
7676

7777
#[derive(Debug)]
78-
pub enum ExprOrIdent<'a> {
79-
Expr(&'a Expr),
80-
Ident(&'a Identifier),
81-
Parameter(&'a Parameter),
78+
pub enum ExprOrIdent {
79+
Expr(Expr),
80+
Ident(Identifier),
81+
Parameter(Parameter),
8282
}
8383

84-
impl ExprOrIdent<'_> {
84+
impl ExprOrIdent {
8585

8686
pub fn range(&self) -> TextRange{
8787
match self {
@@ -575,7 +575,7 @@ impl Evaluation {
575575
(S!("module"), from_module),
576576
(S!("range"), ContextValue::RANGE(ast.range()))
577577
]));
578-
let analyze_result = Evaluation::analyze_ast(session, &ExprOrIdent::Expr(ast), parent, max_infer, &mut context, for_annotation, required_dependencies);
578+
let analyze_result = Evaluation::analyze_ast(session, &ExprOrIdent::Expr(ast.clone()), parent, max_infer, &mut context, for_annotation, required_dependencies);
579579
return (analyze_result.evaluations, analyze_result.diagnostics)
580580
}
581581

@@ -591,7 +591,7 @@ impl Evaluation {
591591
(S!("module"), from_module),
592592
(S!("range"), ContextValue::RANGE(ast.range()))
593593
]));
594-
let value = Evaluation::analyze_ast(session, &ExprOrIdent::Expr(ast), parent, max_infer, &mut context, for_annotation, &mut vec![]);
594+
let value = Evaluation::analyze_ast(session, &ExprOrIdent::Expr(ast.clone()), parent, max_infer, &mut context, for_annotation, &mut vec![]);
595595
if value.evaluations.len() == 1 { //only handle strict evaluations
596596
let eval = &value.evaluations[0];
597597
let v = eval.follow_ref_and_get_value(session, &mut None, diagnostics);
@@ -624,7 +624,7 @@ impl Evaluation {
624624
(S!("module"), from_module),
625625
(S!("range"), ContextValue::RANGE(ast.range()))
626626
]));
627-
let value = Evaluation::analyze_ast(session, &ExprOrIdent::Expr(ast), parent, max_infer, &mut context, for_annotation, &mut vec![]);
627+
let value = Evaluation::analyze_ast(session, &ExprOrIdent::Expr(ast.clone()), parent, max_infer, &mut context, for_annotation, &mut vec![]);
628628
if value.evaluations.len() == 1 { //only handle strict evaluations
629629
let eval = &value.evaluations[0];
630630
let v = eval.follow_ref_and_get_value(session, &mut None, diagnostics);

server/src/features/ast_utils.rs

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ pub struct AstUtils {}
1717

1818
impl AstUtils {
1919

20-
pub fn get_symbols(session: &mut SessionInfo, file_symbol: &Rc<RefCell<Symbol>>, file_info: &Rc<RefCell<FileInfo>>, offset: u32) -> (AnalyzeAstResult, Option<TextRange>, Option<ExprCall>) {
20+
pub fn get_expr(file_info: &Rc<RefCell<FileInfo>>, offset: u32) -> (Option<ExprOrIdent>, Option<ExprCall>) {
2121
let mut expr: Option<ExprOrIdent> = None;
2222
let mut call_expr: Option<ExprCall> = None;
2323
let file_info_ast = file_info.borrow().file_info_ast.clone();
@@ -28,10 +28,13 @@ impl AstUtils {
2828
break;
2929
}
3030
}
31-
let Some(expr) = expr else {
31+
if expr.is_none() {
3232
warn!("expr not found");
33-
return (AnalyzeAstResult::default(), None, None);
34-
};
33+
}
34+
(expr, call_expr)
35+
}
36+
37+
pub fn get_symbols(session: &mut SessionInfo, file_symbol: &Rc<RefCell<Symbol>>, offset: u32, expr: &ExprOrIdent) -> (AnalyzeAstResult, Option<TextRange>) {
3538
let parent_symbol = Symbol::get_scope_symbol(file_symbol.clone(), offset, matches!(expr, ExprOrIdent::Parameter(_)));
3639
AstUtils::build_scope(session, &parent_symbol);
3740
let from_module;
@@ -45,7 +48,7 @@ impl AstUtils {
4548
(S!("range"), ContextValue::RANGE(expr.range()))
4649
]));
4750
let analyse_ast_result: AnalyzeAstResult = Evaluation::analyze_ast(session, &expr, parent_symbol.clone(), &expr.range().end(), &mut context,false, &mut vec![]);
48-
(analyse_ast_result, Some(expr.range()), call_expr)
51+
(analyse_ast_result, Some(expr.range()))
4952

5053
}
5154

@@ -80,7 +83,7 @@ impl AstUtils {
8083

8184
pub struct ExprFinderVisitor<'a> {
8285
offset: TextSize,
83-
expr: Option<ExprOrIdent<'a>>,
86+
expr: Option<ExprOrIdent>,
8487
last_call_expr: Option<&'a ExprCall>,
8588
}
8689

@@ -91,7 +94,7 @@ impl<'a> ExprFinderVisitor<'a> {
9194
expr: the expr being searched for
9295
last_call_expr: The last call expr preceding the expr we are searching for
9396
*/
94-
pub fn find_expr_at(stmt: &'a Stmt, offset: u32) -> (Option<ExprOrIdent<'a>>, Option<ExprCall>) {
97+
pub fn find_expr_at(stmt: &'a Stmt, offset: u32) -> (Option<ExprOrIdent>, Option<ExprCall>) {
9598
let mut visitor = Self {
9699
offset: TextSize::new(offset),
97100
expr: None,
@@ -114,7 +117,7 @@ impl<'a> Visitor<'a> for ExprFinderVisitor<'a> {
114117
}
115118
walk_expr(self, expr);
116119
if self.expr.is_none() {
117-
self.expr = Some(ExprOrIdent::Expr(expr));
120+
self.expr = Some(ExprOrIdent::Expr(expr.clone()));
118121
}
119122
} else {
120123
walk_expr(self, expr);
@@ -125,10 +128,10 @@ impl<'a> Visitor<'a> for ExprFinderVisitor<'a> {
125128
walk_alias(self, alias);
126129
if self.expr.is_none() {
127130
if alias.name.range().contains(self.offset) {
128-
self.expr = Some(ExprOrIdent::Ident(&alias.name));
131+
self.expr = Some(ExprOrIdent::Ident(alias.name.clone()));
129132
} else if let Some(ref asname) = alias.asname {
130133
if asname.range().contains(self.offset) {
131-
self.expr = Some(ExprOrIdent::Ident(asname))
134+
self.expr = Some(ExprOrIdent::Ident(asname.clone()))
132135
}
133136
}
134137
}
@@ -140,7 +143,7 @@ impl<'a> Visitor<'a> for ExprFinderVisitor<'a> {
140143
let ExceptHandler::ExceptHandler(ref handler) = *except_handler;
141144
if let Some(ref ident) = handler.name {
142145
if ident.clone().range().contains(self.offset) {
143-
self.expr = Some(ExprOrIdent::Ident(ident));
146+
self.expr = Some(ExprOrIdent::Ident(ident.clone()));
144147
}
145148
}
146149
} else {
@@ -151,7 +154,7 @@ impl<'a> Visitor<'a> for ExprFinderVisitor<'a> {
151154
fn visit_parameter(&mut self, parameter: &'a Parameter) {
152155
walk_parameter(self, parameter);
153156
if self.expr.is_none() && parameter.name.range().contains(self.offset) {
154-
self.expr = Some(ExprOrIdent::Parameter(parameter));
157+
self.expr = Some(ExprOrIdent::Parameter(parameter.clone()));
155158
}
156159
}
157160

@@ -161,7 +164,7 @@ impl<'a> Visitor<'a> for ExprFinderVisitor<'a> {
161164
if self.expr.is_none() {
162165
if let Some(ref ident) = keyword.arg {
163166
if ident.range().contains(self.offset) {
164-
self.expr = Some(ExprOrIdent::Ident(ident));
167+
self.expr = Some(ExprOrIdent::Ident(ident.clone()));
165168
}
166169
}
167170
} else {
@@ -173,7 +176,7 @@ impl<'a> Visitor<'a> for ExprFinderVisitor<'a> {
173176
walk_pattern_keyword(self, pattern_keyword);
174177

175178
if self.expr.is_none() && pattern_keyword.clone().attr.range().contains(self.offset) {
176-
self.expr = Some(ExprOrIdent::Ident(&pattern_keyword.attr));
179+
self.expr = Some(ExprOrIdent::Ident(pattern_keyword.attr.clone()));
177180
} else {
178181
walk_pattern_keyword(self, pattern_keyword);
179182
}
@@ -190,7 +193,7 @@ impl<'a> Visitor<'a> for ExprFinderVisitor<'a> {
190193
};
191194

192195
if ident.is_some() && ident.unwrap().range().contains(self.offset) {
193-
self.expr = Some(ExprOrIdent::Ident(ident.unwrap()));
196+
self.expr = Some(ExprOrIdent::Ident(ident.unwrap().clone()));
194197
}
195198

196199
}
@@ -212,7 +215,7 @@ impl<'a> Visitor<'a> for ExprFinderVisitor<'a> {
212215

213216
if let Some(ident) = ident {
214217
if ident.range().contains(self.offset) {
215-
self.expr = Some(ExprOrIdent::Ident(ident));
218+
self.expr = Some(ExprOrIdent::Ident(ident.clone()));
216219
}
217220
}
218221
}
@@ -233,7 +236,7 @@ impl<'a> Visitor<'a> for ExprFinderVisitor<'a> {
233236

234237
for ident in idents {
235238
if ident.range().contains(self.offset) {
236-
self.expr = Some(ExprOrIdent::Ident(ident));
239+
self.expr = Some(ExprOrIdent::Ident(ident.clone()));
237240
break;
238241
}
239242
}

server/src/features/definition.rs

Lines changed: 56 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,86 @@ 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 symbols = eval_ptrs.iter().flat_map(|eval_ptr| {
163+
let Some(symbol) = eval_ptr.upgrade_weak() else {
164+
return vec![];
165+
};
166+
symbol.borrow().get_member_symbol(session, &S!("_compute_display_name"), None/*TODO */, false, false, true, false).0
167+
}).collect::<Vec<_>>();
168+
for symbol in symbols {
169+
if let Some(file) = symbol.borrow().get_file() {
170+
for path in file.upgrade().unwrap().borrow().paths().iter() {
171+
let full_path = match file.upgrade().unwrap().borrow().typ() {
172+
SymType::PACKAGE(_) => PathBuf::from(path).join(format!("__init__.py{}", file.upgrade().unwrap().borrow().as_package().i_ext())).sanitize(),
173+
_ => path.clone()
174+
};
175+
let range = if symbol.borrow().has_range() {
176+
if symbol.borrow().range().contains(TextSize::new(offset as u32)) {
177+
continue; //skip if we are already on the definition
178+
}
179+
session.sync_odoo.get_file_mgr().borrow().text_range_to_range(session, &full_path, &symbol.borrow().range())
180+
} else {
181+
Range::default()
182+
};
183+
links.push(LocationLink{
184+
origin_selection_range: None,
185+
target_uri: FileMgr::pathname2uri(&full_path),
186+
target_selection_range: range,
187+
target_range: range,
188+
});
189+
}
190+
}
191+
}
192+
}
193+
152194
pub fn get_location(session: &mut SessionInfo,
153195
file_symbol: &Rc<RefCell<Symbol>>,
154196
file_info: &Rc<RefCell<FileInfo>>,
155197
line: u32,
156198
character: u32
157199
) -> Option<GotoDefinitionResponse> {
158200
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);
201+
let (expr, call_expr) = AstUtils::get_expr(file_info, offset as u32);
202+
let Some(expr) = expr else {
203+
return None;
204+
};
205+
let (analyse_ast_result, _range) = AstUtils::get_symbols(session, file_symbol, offset as u32, &expr);
160206
if analyse_ast_result.evaluations.is_empty() {
161207
return None;
162208
}
163209
let mut links = vec![];
164210
let mut evaluations = analyse_ast_result.evaluations.clone();
165211
// Filter out magic fields
212+
let mut dislay_name_found = false;
166213
evaluations.retain(|eval| {
167214
// Filter out, variables, whose parents are a class, whose name is one of the magic fields, and have the same range as their parent
168215
let eval_sym = eval.symbol.get_symbol(session, &mut None, &mut vec![], None);
169216
let Some(eval_sym) = eval_sym.upgrade_weak() else { return true; };
170217
if !MAGIC_FIELDS.contains(&eval_sym.borrow().name().as_str()) || eval_sym.borrow().typ() != SymType::VARIABLE || !eval_sym.borrow().is_field(session) {
171218
return true;
172219
}
220+
if eval_sym.borrow().name() == "display_name" {
221+
dislay_name_found = true;
222+
}
173223
let Some(parent_sym) = eval_sym.borrow().parent().and_then(|parent| parent.upgrade()) else { return true; };
174224
if parent_sym.borrow().typ() != SymType::CLASS {
175225
return true;
176226
}
177227
eval_sym.borrow().range() != parent_sym.borrow().range()
178228
});
229+
if dislay_name_found {
230+
DefinitionFeature::add_display_name_compute_methods(session, &mut links, expr, file_symbol, offset);
231+
}
179232
let mut index = 0;
180233
while index < evaluations.len() {
181234
let eval = evaluations[index].clone();

server/src/features/hover.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@ 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 (expr, call_expr) = AstUtils::get_expr(file_info, offset as u32);
20+
let Some(expr) = expr else {
21+
return None;
22+
};
23+
let (analyse_ast_result, range) = AstUtils::get_symbols(session, file_symbol, offset as u32, &expr);
2024
let evals = analyse_ast_result.evaluations;
2125
if evals.is_empty() {
2226
return None;

0 commit comments

Comments
 (0)