Skip to content

Commit 089c0c8

Browse files
committed
[IMP] server: record - validate model. Add validation step to xml files
1 parent 45b157e commit 089c0c8

11 files changed

+204
-54
lines changed

server/src/core/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@ pub mod python_utils;
1616
pub mod symbols;
1717
pub mod xml_arch_builder;
1818
pub mod xml_arch_builder_rng_validation;
19-
pub mod xml_data;
19+
pub mod xml_data;
20+
pub mod xml_validation;

server/src/core/odoo.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::core::entry_point::EntryPointType;
2+
use crate::core::xml_validation::XmlValidator;
23
use crate::features::document_symbols::DocumentSymbolFeature;
34
use crate::threads::SessionInfo;
45
use crate::features::completion::CompletionFeature;
@@ -597,8 +598,17 @@ impl SyncOdoo {
597598
session.sync_odoo.add_to_validations(sym_rc.clone());
598599
return true;
599600
}
600-
let mut validator = PythonValidator::new(entry.unwrap(), sym_rc);
601-
validator.validate(session);
601+
let typ = sym_rc.borrow().typ();
602+
match typ {
603+
SymType::XML_FILE => {
604+
let mut validator = XmlValidator::new(entry.as_ref().unwrap(), sym_rc);
605+
validator.validate(session);
606+
},
607+
_ => {
608+
let mut validator = PythonValidator::new(entry.unwrap(), sym_rc);
609+
validator.validate(session);
610+
}
611+
}
602612
continue;
603613
}
604614
}

server/src/core/python_odoo_builder.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,20 @@ impl PythonOdooBuilder {
5252
None => {
5353
let model = Model::new(model_name.clone(), sym.clone());
5454
session.sync_odoo.modules.get("base").map(|module| {
55+
let file = self.symbol.borrow().get_file().unwrap().upgrade().unwrap();
5556
let xml_id_model_name = oyarn!("model_{}", model_name.replace(".", "_").as_str());
5657
let module = module.upgrade().unwrap();
5758
let mut module = module.borrow_mut();
58-
let set = module.as_module_package_mut().xml_ids.entry(xml_id_model_name.clone()).or_insert(vec![]);
59-
set.push(XmlData::RECORD(XmlDataRecord {
60-
xml_symbol: sym.clone(),
61-
model: Sy!("ir.model"),
59+
let set = module.as_module_package_mut().xml_ids.entry(xml_id_model_name.clone()).or_insert(PtrWeakHashSet::new());
60+
set.insert(file.clone());
61+
let mut file = file.borrow_mut();
62+
let file = file.as_file_mut();
63+
file.xml_ids.entry(xml_id_model_name.clone()).or_insert(vec![]).push(XmlData::RECORD(XmlDataRecord {
64+
file_symbol: Rc::downgrade(&sym),
65+
model: (Sy!("ir.model"), std::ops::Range::<usize> {
66+
start: 0,
67+
end: 1,
68+
}),
6269
xml_id: Some(xml_id_model_name),
6370
}));
6471
});

server/src/core/symbols/file_symbol.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use weak_table::{PtrWeakHashSet, PtrWeakKeyHashMap};
22

3-
use crate::{constants::{BuildStatus, BuildSteps, OYarn}, core::{file_mgr::NoqaInfo, model::Model}, oyarn};
3+
use crate::{constants::{BuildStatus, BuildSteps, OYarn}, core::{file_mgr::NoqaInfo, model::Model, xml_data::XmlData}, oyarn};
44
use std::{cell::RefCell, collections::HashMap, rc::{Rc, Weak}};
55

66
use super::{symbol::Symbol, symbol_mgr::{SectionRange, SymbolMgr}};
@@ -17,6 +17,7 @@ pub struct FileSymbol {
1717
pub odoo_status: BuildStatus,
1818
pub validation_status: BuildStatus,
1919
pub not_found_paths: Vec<(BuildSteps, Vec<OYarn>)>,
20+
pub xml_ids: HashMap<OYarn, Vec<XmlData>>, //used for dynamic XML_ID records, like ir.models
2021
in_workspace: bool,
2122
pub self_import: bool,
2223
pub model_dependencies: PtrWeakHashSet<Weak<RefCell<Model>>>, //always on validation level, as odoo step is always required
@@ -47,6 +48,7 @@ impl FileSymbol {
4748
odoo_status: BuildStatus::PENDING,
4849
validation_status: BuildStatus::PENDING,
4950
not_found_paths: vec![],
51+
xml_ids: HashMap::new(),
5052
in_workspace: false,
5153
self_import: false,
5254
sections: vec![],

server/src/core/symbols/module_symbol.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ pub struct ModuleSymbol {
4242
all_depends: HashSet<OYarn>, //computed all depends to avoid too many recomputations
4343
data: Vec<(String, TextRange)>, // TODO
4444
pub module_symbols: HashMap<OYarn, Rc<RefCell<Symbol>>>,
45-
pub xml_ids: HashMap<OYarn, Vec<XmlData>>,
45+
pub xml_ids: HashMap<OYarn, PtrWeakHashSet<Weak<RefCell<Symbol>>>>, //contains all xml_file_symbols that contains the xml_id. Needed because it can be in another module.
4646
pub arch_status: BuildStatus,
4747
pub arch_eval_status: BuildStatus,
4848
pub odoo_status: BuildStatus,
@@ -515,4 +515,18 @@ impl ModuleSymbol {
515515
result
516516
}
517517

518+
//given an xml_id without "module." part, return all XmlData that declare it ("this_module.xml_id"), regardless of the module declaring it.
519+
//For example, stock could create an xml_id called "account.my_xml_id", and so be returned by this function called on "account" module with xml_id "my_xml_id"
520+
pub fn get_xml_id(&self, xml_id: &OYarn) -> Vec<XmlData> {
521+
let mut res = vec![];
522+
if let Some(xml_file_set) = self.xml_ids.get(xml_id) {
523+
for xml_file in xml_file_set.iter() {
524+
if let Some(xml_data) = xml_file.borrow().as_xml_file_sym().xml_ids.get(xml_id) {
525+
res.extend(xml_data.iter().cloned());
526+
}
527+
}
528+
}
529+
res
530+
}
531+
518532
}

server/src/core/symbols/symbol.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,20 @@ impl Symbol {
546546
}
547547
}
548548

549+
pub fn as_xml_file_sym(&self) -> &XmlFileSymbol {
550+
match self {
551+
Symbol::XmlFileSymbol(x) => x,
552+
_ => {panic!("Not an XML file symbol")}
553+
}
554+
}
555+
556+
pub fn as_xml_file_sym_mut(&mut self) -> &mut XmlFileSymbol {
557+
match self {
558+
Symbol::XmlFileSymbol(x) => x,
559+
_ => {panic!("Not an XML file symbol")}
560+
}
561+
}
562+
549563
pub fn as_symbol_mgr(&self) -> &dyn SymbolMgr {
550564
match self {
551565
Symbol::File(f) => f,

server/src/core/symbols/xml_file_symbol.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use lsp_types::{Diagnostic, DiagnosticSeverity, NumberOrString, Position, Range}
22
use roxmltree::{Document, Error};
33
use weak_table::PtrWeakHashSet;
44

5-
use crate::{constants::{BuildStatus, BuildSteps, OYarn, EXTENSION_NAME}, core::{file_mgr::{FileInfo, NoqaInfo}, model::Model}, oyarn, S};
5+
use crate::{constants::{BuildStatus, BuildSteps, OYarn, EXTENSION_NAME}, core::{file_mgr::{FileInfo, NoqaInfo}, model::Model, xml_data::XmlData}, oyarn, S};
66
use std::{cell::RefCell, collections::HashMap, rc::{Rc, Weak}};
77

88
use super::{symbol::Symbol, symbol_mgr::{SectionRange, SymbolMgr}};
@@ -17,6 +17,7 @@ pub struct XmlFileSymbol {
1717
pub arch_status: BuildStatus,
1818
pub validation_status: BuildStatus,
1919
pub not_found_paths: Vec<(BuildSteps, Vec<OYarn>)>,
20+
pub xml_ids: HashMap<OYarn, Vec<XmlData>>,
2021
in_workspace: bool,
2122
pub self_import: bool,
2223
pub model_dependencies: PtrWeakHashSet<Weak<RefCell<Model>>>, //always on validation level, as odoo step is always required
@@ -44,6 +45,7 @@ impl XmlFileSymbol {
4445
arch_status: BuildStatus::PENDING,
4546
validation_status: BuildStatus::PENDING,
4647
not_found_paths: vec![],
48+
xml_ids: HashMap::new(),
4749
in_workspace: false,
4850
self_import: false,
4951
sections: vec![],

server/src/core/xml_arch_builder.rs

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ impl XmlArchBuilder {
3737
self.load_odoo_openerp_data(session, node, &mut diagnostics);
3838
self.xml_symbol.borrow_mut().set_build_status(BuildSteps::ARCH, BuildStatus::DONE);
3939
file_info.replace_diagnostics(BuildSteps::ARCH, diagnostics);
40+
session.sync_odoo.add_to_validations(self.xml_symbol.clone());
4041
}
4142

4243
pub fn on_operation_creation(
@@ -81,18 +82,18 @@ impl XmlArchBuilder {
8182
xml_module = m.upgrade().unwrap();
8283
}
8384
}
84-
if xml_module.borrow().as_module_package().xml_ids.get(&Sy!(id.clone())).is_none() {
85-
xml_module.borrow_mut().as_module_package_mut().xml_ids.insert(Sy!(id.clone()), vec![]);
86-
}
87-
xml_data.set_symbol(self.xml_symbol.clone());
88-
xml_module.borrow_mut().as_module_package_mut().xml_ids.get_mut(&Sy!(id)).unwrap().push(xml_data);
85+
xml_data.set_file_symbol(&self.xml_symbol);
86+
xml_module.borrow_mut().as_module_package_mut().xml_ids.entry(Sy!(id.clone())).or_insert(PtrWeakHashSet::new()).insert(self.xml_symbol.clone());
87+
self.xml_symbol.borrow_mut().as_xml_file_sym_mut().xml_ids.entry(Sy!(id.clone())).or_insert(vec![]).push(xml_data);
8988
}
9089
}
9190

91+
/**
92+
* search for an xml_id in the already registered xml files.
93+
* */
9294
pub fn get_xml_ids(&self, session: &mut SessionInfo, xml_id: &str, attr: &Attribute, diagnostics: &mut Vec<Diagnostic>) -> Vec<XmlData> {
93-
let mut res = vec![];
9495
if !self.is_in_main_ep {
95-
return res;
96+
return vec![];
9697
}
9798
let id_split = xml_id.split(".").collect::<Vec<&str>>();
9899
let mut module = None;
@@ -117,17 +118,15 @@ impl XmlArchBuilder {
117118
None,
118119
None
119120
));
120-
return res;
121+
return vec![];
121122
}
122123
if module.is_none() {
123124
warn!("Module not found for id: {}", xml_id);
124-
return res;
125+
return vec![];
125126
}
126127
let module = module.unwrap();
127-
if let Some(xml) = module.borrow().as_module_package().xml_ids.get(&oyarn!("{}", id_split.last().unwrap())) {
128-
res.extend(xml.iter().map(|x| x.clone()));
129-
}
130-
res
128+
let module = module.borrow();
129+
module.as_module_package().get_xml_id(&oyarn!("{}", id_split.last().unwrap()))
131130
}
132131

133132
pub fn get_group_ids(&self, session: &mut SessionInfo, xml_id: &str, attr: &Attribute, diagnostics: &mut Vec<Diagnostic>) -> Vec<XmlData> {
@@ -136,7 +135,7 @@ impl XmlArchBuilder {
136135
for data in xml_ids.iter() {
137136
match data {
138137
XmlData::RECORD(r) => {
139-
if r.model == "res.groups" {
138+
if r.model.0 == "res.groups" {
140139
res.push(data.clone());
141140
}
142141
},

server/src/core/xml_arch_builder_rng_validation.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ impl XmlArchBuilder {
198198
}
199199
}
200200
let data = XmlData::MENUITEM(XmlDataMenuItem {
201-
xml_symbol: self.xml_symbol.clone(),
201+
file_symbol: Rc::downgrade(&self.xml_symbol),
202202
xml_id: found_id.clone().map(|id| oyarn!("{}", id)),
203203
});
204204
self.on_operation_creation(session, found_id, node, data, diagnostics);
@@ -254,8 +254,8 @@ impl XmlArchBuilder {
254254
}
255255
}
256256
let data = XmlData::RECORD(XmlDataRecord {
257-
xml_symbol: self.xml_symbol.clone(),
258-
model: oyarn!("{}", node.attribute("model").unwrap()),
257+
file_symbol: Rc::downgrade(&self.xml_symbol),
258+
model: (oyarn!("{}", node.attribute("model").unwrap()), node.attribute_node("model").unwrap().range()),
259259
xml_id: found_id.clone().map(|id| oyarn!("{}", id)),
260260
});
261261
self.on_operation_creation(session, found_id, node, data, diagnostics);
@@ -508,7 +508,7 @@ impl XmlArchBuilder {
508508
//no interesting rule to check, as 'any' is valid
509509
let found_id = node.attribute("id").map(|s| s.to_string());
510510
let data = XmlData::TEMPLATE(XmlDataTemplate {
511-
xml_symbol: self.xml_symbol.clone(),
511+
file_symbol: Rc::downgrade(&self.xml_symbol),
512512
xml_id: found_id.clone().map(|id| oyarn!("{}", id)),
513513
});
514514
self.on_operation_creation(session, found_id, node, data, diagnostics);
@@ -550,7 +550,7 @@ impl XmlArchBuilder {
550550
None));
551551
}
552552
let data = XmlData::DELETE(XmlDataDelete {
553-
xml_symbol: self.xml_symbol.clone(),
553+
file_symbol: Rc::downgrade(&self.xml_symbol),
554554
xml_id: found_id.clone().map(|id| oyarn!("{}", id)),
555555
model: Sy!(node.attribute("model").unwrap().to_string()),
556556
});
@@ -627,7 +627,7 @@ impl XmlArchBuilder {
627627
None));
628628
}
629629
let data = XmlData::ACT_WINDOW(XmlDataActWindow {
630-
xml_symbol: self.xml_symbol.clone(),
630+
file_symbol: Rc::downgrade(&self.xml_symbol),
631631
xml_id: found_id.clone().map(|id| oyarn!("{}", id)),
632632
res_model: Sy!(node.attribute("res_model").unwrap().to_string()),
633633
name: Sy!(node.attribute("name").unwrap().to_string()),
@@ -679,7 +679,7 @@ impl XmlArchBuilder {
679679
None));
680680
}
681681
let data = XmlData::REPORT(XmlDataReport {
682-
xml_symbol: self.xml_symbol.clone(),
682+
file_symbol: Rc::downgrade(&self.xml_symbol),
683683
xml_id: found_id.clone().map(|id| oyarn!("{}", id)),
684684
name: Sy!(node.attribute("name").unwrap().to_string()),
685685
model: Sy!(node.attribute("model").unwrap().to_string()),

0 commit comments

Comments
 (0)