From d1af2d1e176087aed1e1e82099e99c6be0094e40 Mon Sep 17 00:00:00 2001 From: M Mahrous Date: Wed, 15 Oct 2025 15:55:55 +0200 Subject: [PATCH] [IMP] hover and definition for module names in manifest --- server/src/core/symbols/module_symbol.rs | 4 ++++ server/src/features/definition.rs | 30 +++++++++++++++++++++++- server/src/features/features_utils.rs | 18 ++++++++++++-- 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/server/src/core/symbols/module_symbol.rs b/server/src/core/symbols/module_symbol.rs index 0d3be8f9..fccf1da9 100644 --- a/server/src/core/symbols/module_symbol.rs +++ b/server/src/core/symbols/module_symbol.rs @@ -415,6 +415,10 @@ impl ModuleSymbol { symbol.borrow().as_module_package().dir_name == *dir_name || symbol.borrow().as_module_package().all_depends.contains(dir_name) } + pub fn get_all_depends(&self) -> &HashSet { + &self.all_depends + } + pub fn get_dependencies(&self, step: usize, level: usize) -> Option<&PtrWeakHashSet>>> { self.dependencies.get(step)?.get(level)?.as_ref() diff --git a/server/src/features/definition.rs b/server/src/features/definition.rs index ce604067..92dd12bc 100644 --- a/server/src/features/definition.rs +++ b/server/src/features/definition.rs @@ -4,7 +4,7 @@ use ruff_text_size::TextSize; use std::path::PathBuf; use std::{cell::RefCell, rc::Rc}; -use crate::constants::SymType; +use crate::constants::{PackageType, SymType}; use crate::core::evaluation::{Evaluation, EvaluationValue}; use crate::core::file_mgr::{FileInfo, FileMgr}; use crate::core::odoo::SyncOdoo; @@ -90,6 +90,33 @@ impl DefinitionFeature { model_found } + fn check_for_module_string(session: &mut SessionInfo, eval: &Evaluation, file_symbol: &Rc>, links: &mut Vec) -> bool { + if file_symbol.borrow().typ() != SymType::PACKAGE(PackageType::MODULE) { + // If not on manifest, we don't check for modules + return false; + }; + let value = if let Some(eval_value) = eval.value.as_ref() { + if let EvaluationValue::CONSTANT(Expr::StringLiteral(expr)) = eval_value { + oyarn!("{}", expr.value.to_string()) + } else { + return false; + } + } else { + return false; + }; + let Some(module) = session.sync_odoo.modules.get(&oyarn!("{}", value)).and_then(|m| m.upgrade()) else { + return false; + }; + let path = PathBuf::from(module.borrow().paths()[0].clone()).join("__manifest__.py").sanitize(); + links.push(LocationLink{ + origin_selection_range: None, + target_uri: FileMgr::pathname2uri(&path), + target_selection_range: Range::default(), + target_range: Range::default(), + }); + true + } + fn check_for_xml_id_string(session: &mut SessionInfo, eval: &Evaluation, file_symbol: &Rc>, links: &mut Vec) -> bool { let value = if let Some(eval_value) = eval.value.as_ref() { if let EvaluationValue::CONSTANT(Expr::StringLiteral(expr)) = eval_value { @@ -166,6 +193,7 @@ impl DefinitionFeature { let eval = evaluations[index].clone(); if DefinitionFeature::check_for_domain_field(session, &eval, file_symbol, &call_expr, offset, &mut links) || DefinitionFeature::check_for_compute_string(session, &eval, file_symbol,&call_expr, offset, &mut links) || + DefinitionFeature::check_for_module_string(session, &eval, file_symbol, &mut links) || DefinitionFeature::check_for_model_string(session, &eval, file_symbol, &mut links) || DefinitionFeature::check_for_xml_id_string(session, &eval, file_symbol, &mut links) { index += 1; diff --git a/server/src/features/features_utils.rs b/server/src/features/features_utils.rs index 401fe935..1a5757ed 100644 --- a/server/src/features/features_utils.rs +++ b/server/src/features/features_utils.rs @@ -11,7 +11,7 @@ use std::path::PathBuf; use std::rc::Weak; use std::{cell::RefCell, rc::Rc}; -use crate::constants::SymType; +use crate::constants::{PackageType, SymType}; use crate::constants::OYarn; use crate::core::evaluation::{Context, ContextValue, Evaluation, EvaluationSymbolPtr, EvaluationSymbolWeak, EvaluationValue}; use crate::core::symbols::symbol::Symbol; @@ -339,6 +339,20 @@ impl FeaturesUtils { if let Some(EvaluationValue::CONSTANT(Expr::StringLiteral(expr))) = eval.value.as_ref() { let mut block = S!(""); let str = expr.value.to_string(); + if let Some(SymType::PACKAGE(PackageType::MODULE)) = file_symbol.as_ref().map(|fs| fs.borrow().typ()) { + // If we are in manifest, we check if the string is a module and list the underlying module dependencies + if let Some(module) = session.sync_odoo.modules.get(&oyarn!("{}", str)).and_then(|m| m.upgrade()) { + block += format!("Module: {}", module.borrow().name()).as_str(); + let module_ref = module.borrow(); + let dependencies = module_ref.as_module_package().get_all_depends(); + if !dependencies.is_empty() { + block += " \n*** \nDependencies: \n"; + block += &dependencies.iter().map(|dep| format!("- {}", dep)).join(" \n"); + } + } + blocks.push(block); + continue; + } let from_module = file_symbol.as_ref().and_then(|file_symbol| file_symbol.borrow().find_module()); if let (Some(call_expression), Some(file_sym), Some(offset)) = (call_expr, file_symbol.as_ref(), offset){ let mut special_string_syms = FeaturesUtils::check_for_string_special_syms(session, &str, call_expression, offset, expr.range, file_sym); @@ -622,7 +636,7 @@ impl FeaturesUtils { } /// Finds and returns useful links for an evaluation - fn get_useful_link(session: &mut SessionInfo, typ: &EvaluationSymbolPtr) -> String { + fn get_useful_link(_session: &mut SessionInfo, typ: &EvaluationSymbolPtr) -> String { // Possibly add more links in the future let Some(typ) = typ.upgrade_weak() else { return S!("")