Skip to content

Commit 044bdf8

Browse files
committed
[IMP] server: record - validate model. Add validation step to xml files
1 parent 259b5d7 commit 044bdf8

11 files changed

+230
-60
lines changed

server/src/core/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,5 @@ pub mod python_utils;
1717
pub mod symbols;
1818
pub mod xml_arch_builder;
1919
pub mod xml_arch_builder_rng_validation;
20-
pub mod xml_data;
20+
pub mod xml_data;
21+
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;
@@ -599,8 +600,17 @@ impl SyncOdoo {
599600
session.sync_odoo.add_to_validations(sym_rc.clone());
600601
return true;
601602
}
602-
let mut validator = PythonValidator::new(entry.unwrap(), sym_rc);
603-
validator.validate(session);
603+
let typ = sym_rc.borrow().typ();
604+
match typ {
605+
SymType::XML_FILE => {
606+
let mut validator = XmlValidator::new(entry.as_ref().unwrap(), sym_rc);
607+
validator.validate(session);
608+
},
609+
_ => {
610+
let mut validator = PythonValidator::new(entry.unwrap(), sym_rc);
611+
validator.validate(session);
612+
}
613+
}
604614
continue;
605615
}
606616
}

server/src/core/python_odoo_builder.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,20 @@ impl PythonOdooBuilder {
8282
None => {
8383
let model = Model::new(model_name.clone(), sym.clone());
8484
session.sync_odoo.modules.get("base").map(|module| {
85+
let file = self.symbol.borrow().get_file().unwrap().upgrade().unwrap();
8586
let xml_id_model_name = oyarn!("model_{}", model_name.replace(".", "_").as_str());
8687
let module = module.upgrade().unwrap();
8788
let mut module = module.borrow_mut();
88-
let set = module.as_module_package_mut().xml_ids.entry(xml_id_model_name.clone()).or_insert(vec![]);
89-
set.push(XmlData::RECORD(XmlDataRecord {
90-
xml_symbol: sym.clone(),
91-
model: Sy!("ir.model"),
89+
let set = module.as_module_package_mut().xml_ids.entry(xml_id_model_name.clone()).or_insert(PtrWeakHashSet::new());
90+
set.insert(file.clone());
91+
let mut file = file.borrow_mut();
92+
let file = file.as_file_mut();
93+
file.xml_ids.entry(xml_id_model_name.clone()).or_insert(vec![]).push(XmlData::RECORD(XmlDataRecord {
94+
file_symbol: Rc::downgrade(&sym),
95+
model: (Sy!("ir.model"), std::ops::Range::<usize> {
96+
start: 0,
97+
end: 1,
98+
}),
9299
xml_id: Some(xml_id_model_name),
93100
}));
94101
});

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 & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ pub struct ModuleSymbol {
4141
all_depends: HashSet<OYarn>, //computed all depends to avoid too many recomputations
4242
data: Vec<(String, TextRange)>, // TODO
4343
pub module_symbols: HashMap<OYarn, Rc<RefCell<Symbol>>>,
44-
pub xml_ids: HashMap<OYarn, Vec<XmlData>>,
44+
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.
4545
pub arch_status: BuildStatus,
4646
pub arch_eval_status: BuildStatus,
4747
pub odoo_status: BuildStatus,
@@ -375,7 +375,6 @@ impl ModuleSymbol {
375375
let root = document.root_element();
376376
let mut xml_builder = XmlArchBuilder::new(xml_sym);
377377
xml_builder.load_arch(session, &mut file_info, &root);
378-
file_info.publish_diagnostics(session); //TODO do it only if diagnostics are not empty, else in validation
379378
} else if data.len() > 0 {
380379
let mut diagnostics = vec![];
381380
XmlFileSymbol::build_syntax_diagnostics(&session, &mut diagnostics, &mut file_info, &document.unwrap_err());
@@ -527,4 +526,18 @@ impl ModuleSymbol {
527526
result
528527
}
529528

529+
//given an xml_id without "module." part, return all XmlData that declare it ("this_module.xml_id"), regardless of the module declaring it.
530+
//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"
531+
pub fn get_xml_id(&self, xml_id: &OYarn) -> Vec<XmlData> {
532+
let mut res = vec![];
533+
if let Some(xml_file_set) = self.xml_ids.get(xml_id) {
534+
for xml_file in xml_file_set.iter() {
535+
if let Some(xml_data) = xml_file.borrow().as_xml_file_sym().xml_ids.get(xml_id) {
536+
res.extend(xml_data.iter().cloned());
537+
}
538+
}
539+
}
540+
res
541+
}
542+
530543
}

server/src/core/symbols/symbol.rs

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,20 @@ impl Symbol {
548548
}
549549
}
550550

551+
pub fn as_xml_file_sym(&self) -> &XmlFileSymbol {
552+
match self {
553+
Symbol::XmlFileSymbol(x) => x,
554+
_ => {panic!("Not an XML file symbol")}
555+
}
556+
}
557+
558+
pub fn as_xml_file_sym_mut(&mut self) -> &mut XmlFileSymbol {
559+
match self {
560+
Symbol::XmlFileSymbol(x) => x,
561+
_ => {panic!("Not an XML file symbol")}
562+
}
563+
}
564+
551565
pub fn as_symbol_mgr(&self) -> &dyn SymbolMgr {
552566
match self {
553567
Symbol::File(f) => f,
@@ -1074,7 +1088,7 @@ impl Symbol {
10741088
match step {
10751089
BuildSteps::SYNTAX => panic!(),
10761090
BuildSteps::ARCH => x.arch_status = status,
1077-
BuildSteps::ARCH_EVAL => panic!(),
1091+
BuildSteps::ARCH_EVAL => {},
10781092
BuildSteps::VALIDATION => x.validation_status = status,
10791093
}
10801094
},
@@ -1571,8 +1585,8 @@ impl Symbol {
15711585
}
15721586
}
15731587

1574-
//Add a symbol as dependency on the step of the other symbol for the build level.
1575-
//-> The build of the 'step' of self requires the build of 'dep_level' of the other symbol to be done
1588+
/**Add a symbol as dependency on the step of the other symbol for the build level.
1589+
* -> The build of the 'step' of self requires the build of 'dep_level' of the other symbol to be done */
15761590
pub fn add_dependency(&mut self, symbol: &mut Symbol, step:BuildSteps, dep_level:BuildSteps) {
15771591
if step == BuildSteps::SYNTAX || dep_level == BuildSteps::SYNTAX {
15781592
panic!("Can't add dependency for syntax step")
@@ -1651,9 +1665,9 @@ impl Symbol {
16511665
if let Some(hashset) = hashset {
16521666
for sym in hashset {
16531667
if !Symbol::is_symbol_in_parents(&sym, &ref_to_inv) {
1654-
if index == BuildSteps::ARCH_EVAL as usize {
1668+
if index + 1 == BuildSteps::ARCH_EVAL as usize {
16551669
session.sync_odoo.add_to_rebuild_arch_eval(sym.clone());
1656-
} else if index == BuildSteps::VALIDATION as usize {
1670+
} else if index + 1 == BuildSteps::VALIDATION as usize {
16571671
sym.borrow_mut().invalidate_sub_functions(session);
16581672
session.sync_odoo.add_to_validations(sym.clone());
16591673
}

server/src/core/symbols/xml_file_symbol.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ use lsp_types::Diagnostic;
22
use roxmltree::Error;
33
use weak_table::PtrWeakHashSet;
44

5-
use crate::{constants::{BuildStatus, BuildSteps, OYarn}, core::{diagnostics::DiagnosticCode, file_mgr::{FileInfo, NoqaInfo}, model::Model}, oyarn, threads::SessionInfo, S};
5+
use crate::{core::diagnostics::DiagnosticCode, threads::SessionInfo};
6+
use crate::{constants::{BuildStatus, BuildSteps, OYarn, EXTENSION_NAME}, core::{file_mgr::{FileInfo, NoqaInfo}, model::Model, xml_data::XmlData}, oyarn, S};
67
use std::{cell::RefCell, collections::HashMap, rc::{Rc, Weak}};
78

89
use super::{symbol::Symbol, symbol_mgr::SectionRange};
@@ -17,6 +18,7 @@ pub struct XmlFileSymbol {
1718
pub arch_status: BuildStatus,
1819
pub validation_status: BuildStatus,
1920
pub not_found_paths: Vec<(BuildSteps, Vec<OYarn>)>,
21+
pub xml_ids: HashMap<OYarn, Vec<XmlData>>,
2022
in_workspace: bool,
2123
pub self_import: bool,
2224
pub model_dependencies: PtrWeakHashSet<Weak<RefCell<Model>>>, //always on validation level, as odoo step is always required
@@ -44,6 +46,7 @@ impl XmlFileSymbol {
4446
arch_status: BuildStatus::PENDING,
4547
validation_status: BuildStatus::PENDING,
4648
not_found_paths: vec![],
49+
xml_ids: HashMap::new(),
4750
in_workspace: false,
4851
self_import: false,
4952
sections: vec![],

server/src/core/xml_arch_builder.rs

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

4344
pub fn on_operation_creation(
@@ -79,18 +80,18 @@ impl XmlArchBuilder {
7980
xml_module = m.upgrade().unwrap();
8081
}
8182
}
82-
if xml_module.borrow().as_module_package().xml_ids.get(&Sy!(id.clone())).is_none() {
83-
xml_module.borrow_mut().as_module_package_mut().xml_ids.insert(Sy!(id.clone()), vec![]);
84-
}
85-
xml_data.set_symbol(self.xml_symbol.clone());
86-
xml_module.borrow_mut().as_module_package_mut().xml_ids.get_mut(&Sy!(id)).unwrap().push(xml_data);
83+
xml_data.set_file_symbol(&self.xml_symbol);
84+
xml_module.borrow_mut().as_module_package_mut().xml_ids.entry(Sy!(id.clone())).or_insert(PtrWeakHashSet::new()).insert(self.xml_symbol.clone());
85+
self.xml_symbol.borrow_mut().as_xml_file_sym_mut().xml_ids.entry(Sy!(id.clone())).or_insert(vec![]).push(xml_data);
8786
}
8887
}
8988

89+
/**
90+
* search for an xml_id in the already registered xml files.
91+
* */
9092
pub fn get_xml_ids(&self, session: &mut SessionInfo, xml_id: &str, attr: &Attribute, diagnostics: &mut Vec<Diagnostic>) -> Vec<XmlData> {
91-
let mut res = vec![];
9293
if !self.is_in_main_ep {
93-
return res;
94+
return vec![];
9495
}
9596
let id_split = xml_id.split(".").collect::<Vec<&str>>();
9697
let mut module = None;
@@ -115,17 +116,15 @@ impl XmlArchBuilder {
115116
None,
116117
None
117118
));
118-
return res;
119+
return vec![];
119120
}
120121
if module.is_none() {
121122
warn!("Module not found for id: {}", xml_id);
122-
return res;
123+
return vec![];
123124
}
124125
let module = module.unwrap();
125-
if let Some(xml) = module.borrow().as_module_package().xml_ids.get(&oyarn!("{}", id_split.last().unwrap())) {
126-
res.extend(xml.iter().map(|x| x.clone()));
127-
}
128-
res
126+
let module = module.borrow();
127+
module.as_module_package().get_xml_id(&oyarn!("{}", id_split.last().unwrap()))
129128
}
130129

131130
pub fn get_group_ids(&self, session: &mut SessionInfo, xml_id: &str, attr: &Attribute, diagnostics: &mut Vec<Diagnostic>) -> Vec<XmlData> {
@@ -134,7 +133,7 @@ impl XmlArchBuilder {
134133
for data in xml_ids.iter() {
135134
match data {
136135
XmlData::RECORD(r) => {
137-
if r.model == "res.groups" {
136+
if r.model.0 == "res.groups" {
138137
res.push(data.clone());
139138
}
140139
},

server/src/core/xml_arch_builder_rng_validation.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ impl XmlArchBuilder {
175175
}
176176
}
177177
let data = XmlData::MENUITEM(XmlDataMenuItem {
178-
xml_symbol: self.xml_symbol.clone(),
178+
file_symbol: Rc::downgrade(&self.xml_symbol),
179179
xml_id: found_id.clone().map(|id| oyarn!("{}", id)),
180180
});
181181
self.on_operation_creation(session, found_id, node, data, diagnostics);
@@ -225,8 +225,8 @@ impl XmlArchBuilder {
225225
}
226226
}
227227
let data = XmlData::RECORD(XmlDataRecord {
228-
xml_symbol: self.xml_symbol.clone(),
229-
model: oyarn!("{}", node.attribute("model").unwrap()),
228+
file_symbol: Rc::downgrade(&self.xml_symbol),
229+
model: (oyarn!("{}", node.attribute("model").unwrap()), node.attribute_node("model").unwrap().range()),
230230
xml_id: found_id.clone().map(|id| oyarn!("{}", id)),
231231
});
232232
self.on_operation_creation(session, found_id, node, data, diagnostics);
@@ -444,7 +444,7 @@ impl XmlArchBuilder {
444444
//no interesting rule to check, as 'any' is valid
445445
let found_id = node.attribute("id").map(|s| s.to_string());
446446
let data = XmlData::TEMPLATE(XmlDataTemplate {
447-
xml_symbol: self.xml_symbol.clone(),
447+
file_symbol: Rc::downgrade(&self.xml_symbol),
448448
xml_id: found_id.clone().map(|id| oyarn!("{}", id)),
449449
});
450450
self.on_operation_creation(session, found_id, node, data, diagnostics);
@@ -480,7 +480,7 @@ impl XmlArchBuilder {
480480
}
481481
}
482482
let data = XmlData::DELETE(XmlDataDelete {
483-
xml_symbol: self.xml_symbol.clone(),
483+
file_symbol: Rc::downgrade(&self.xml_symbol),
484484
xml_id: found_id.clone().map(|id| oyarn!("{}", id)),
485485
model: Sy!(node.attribute("model").unwrap().to_string()),
486486
});
@@ -547,7 +547,7 @@ impl XmlArchBuilder {
547547
}
548548
}
549549
let data = XmlData::ACT_WINDOW(XmlDataActWindow {
550-
xml_symbol: self.xml_symbol.clone(),
550+
file_symbol: Rc::downgrade(&self.xml_symbol),
551551
xml_id: found_id.clone().map(|id| oyarn!("{}", id)),
552552
res_model: Sy!(node.attribute("res_model").unwrap().to_string()),
553553
name: Sy!(node.attribute("name").unwrap().to_string()),
@@ -593,7 +593,7 @@ impl XmlArchBuilder {
593593
}
594594
}
595595
let data = XmlData::REPORT(XmlDataReport {
596-
xml_symbol: self.xml_symbol.clone(),
596+
file_symbol: Rc::downgrade(&self.xml_symbol),
597597
xml_id: found_id.clone().map(|id| oyarn!("{}", id)),
598598
name: Sy!(node.attribute("name").unwrap().to_string()),
599599
model: Sy!(node.attribute("model").unwrap().to_string()),

0 commit comments

Comments
 (0)