Skip to content

Commit 1d7e54d

Browse files
committed
[IMP] server: xml - menuitem - check that parent is valid
1 parent e542584 commit 1d7e54d

File tree

5 files changed

+78
-7
lines changed

5 files changed

+78
-7
lines changed

server/error_code.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
# OdooLS Error codes
2-
OdooLS errors are now defined in their own modules, with the codes being available in [the diagnostics codes list file](src\core\diagnostic_codes_list.rs)
2+
OdooLS errors are now defined in their own modules, with the codes being available in [the diagnostics codes list file](src\core\diagnostic_codes_list.rs)

server/src/core/diagnostic_codes_list.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,4 +400,8 @@ OLS05050, DiagnosticSetting::Error, "Data file {0} is not a valid XML or CSV fil
400400
* An XML_ID should be in the format 'xml_id' or 'module.xml_id', but can't contains more dots
401401
*/
402402
OLS05051, DiagnosticSetting::Error, "Invalid XML ID '{0}'. It should not contain more than one dot.",
403+
/**
404+
* The given parent_id does not exists in the dependents modules, or is not a menuitem
405+
*/
406+
OLS05052, DiagnosticSetting::Error, "Parent menuitem with id '{0}' does not exist",
403407
}

server/src/core/symbols/module_symbol.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,4 +513,17 @@ impl ModuleSymbol {
513513
result
514514
}
515515

516+
pub fn this_and_dependencies(&self, session: &mut SessionInfo) -> PtrWeakHashSet<Weak<RefCell<Symbol>>> {
517+
let mut result = PtrWeakHashSet::new();
518+
result.insert(self.weak_self.as_ref().unwrap().upgrade().unwrap());
519+
for dep in self.depends.iter() {
520+
if let Some(module) = session.sync_odoo.modules.get(&dep.0) {
521+
if let Some(module) = module.upgrade() {
522+
result.insert(module);
523+
}
524+
}
525+
}
526+
result
527+
}
528+
516529
}

server/src/core/xml_arch_builder.rs

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
use std::{cell::RefCell, rc::Rc};
1+
use std::{cell::RefCell, collections::HashMap, fmt, fs, path::PathBuf, rc::{Rc, Weak}};
22

3-
use lsp_types::{Diagnostic};
4-
use roxmltree::Node;
5-
use tracing::{warn};
3+
use lsp_types::{Diagnostic, DiagnosticSeverity, Position, Range};
4+
use regex::Regex;
5+
use roxmltree::{Attribute, Node};
6+
use tracing::{error, warn};
67
use weak_table::PtrWeakHashSet;
78

89
use crate::{constants::{BuildStatus, BuildSteps, OYarn}, core::{diagnostics::{create_diagnostic, DiagnosticCode}, entry_point::EntryPointType}, threads::SessionInfo, Sy};
@@ -97,4 +98,47 @@ impl XmlArchBuilder {
9798
xml_module.borrow_mut().as_module_package_mut().xml_ids.get_mut(&Sy!(id)).unwrap().insert(self.xml_symbol.clone());
9899
}
99100
}
101+
102+
pub fn get_xml_ids(&self, session: &mut SessionInfo, xml_id: &str, attr: &Attribute, diagnostics: &mut Vec<Diagnostic>) -> Vec<Rc<RefCell<Symbol>>> {
103+
let mut res = vec![];
104+
if !self.is_in_main_ep {
105+
return res;
106+
}
107+
let id_split = xml_id.split(".").collect::<Vec<&str>>();
108+
let mut module = None;
109+
if id_split.len() == 1 {
110+
// If no module name, we are in the current module
111+
module = self.xml_symbol.borrow().find_module();
112+
} else if id_split.len() == 2 {
113+
// Try to find the module by name
114+
if let Some(m) = session.sync_odoo.modules.get(&Sy!(id_split.first().unwrap().to_string())) {
115+
module = m.upgrade();
116+
}
117+
} else if id_split.len() > 2 {
118+
diagnostics.push(Diagnostic::new(
119+
Range {
120+
start: Position::new(attr.range().start as u32, 0),
121+
end: Position::new(attr.range().end as u32, 0),
122+
},
123+
Some(DiagnosticSeverity::ERROR),
124+
Some(lsp_types::NumberOrString::String(S!("OLS30446"))),
125+
Some(EXTENSION_NAME.to_string()),
126+
format!("Invalid XML ID '{}'. It should not contain more than one dot", xml_id),
127+
None,
128+
None
129+
));
130+
return res;
131+
}
132+
if module.is_none() {
133+
warn!("Module not found for id: {}", xml_id);
134+
return res;
135+
}
136+
let module = module.unwrap();
137+
for module in module.borrow().as_module_package().this_and_dependencies(session).iter() {
138+
if let Some(xml) = module.borrow().as_module_package().xml_ids.get(&oyarn!("{}", id_split.last().unwrap())) {
139+
res.extend(xml.iter());
140+
}
141+
}
142+
res
143+
}
100144
}

server/src/core/xml_arch_builder_rng_validation.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ impl XmlArchBuilder {
8989
}
9090
}
9191
}
92-
}
92+
},
9393
"parent" => {
9494
if is_submenu {
9595
if let Some(diagnostic) = create_diagnostic(session, DiagnosticCode::OLS05012, &[]) {
@@ -98,8 +98,18 @@ impl XmlArchBuilder {
9898
..diagnostic.clone()
9999
});
100100
}
101+
} else {
102+
//check that parent exists
103+
if self.get_xml_ids(session, attr.value(), &attr, diagnostics).is_empty() {
104+
if let Some(diagnostic) = create_diagnostic(session, DiagnosticCode::OLS05052, &[]) {
105+
diagnostics.push(Diagnostic {
106+
range: Range { start: Position::new(attr.range().start as u32, 0), end: Position::new(attr.range().end as u32, 0) },
107+
..diagnostic.clone()
108+
});
109+
}
110+
}
101111
}
102-
}
112+
},
103113
"web_icon" => {
104114
if has_parent || is_submenu {
105115
if let Some(diagnostic) = create_diagnostic(session, DiagnosticCode::OLS05010, &[]) {

0 commit comments

Comments
 (0)