mirror of
https://github.com/nushell/nushell
synced 2024-12-25 20:43:09 +00:00
Reuse parsed modules (#9125)
This commit is contained in:
parent
0ea973b78b
commit
250071939b
3 changed files with 50 additions and 15 deletions
|
@ -1727,6 +1727,10 @@ fn parse_module_file(
|
|||
let file_id = working_set.add_file(path.to_string_lossy().to_string(), &contents);
|
||||
let new_span = working_set.get_span_for_file(file_id);
|
||||
|
||||
if let Some(module_id) = working_set.find_module_by_span(new_span) {
|
||||
return Some(module_id);
|
||||
}
|
||||
|
||||
// Change the currently parsed directory
|
||||
let prev_currently_parsed_cwd = if let Some(parent) = path.parent() {
|
||||
let prev = working_set.currently_parsed_cwd.clone();
|
||||
|
@ -1834,13 +1838,25 @@ pub fn parse_module_file_or_dir(
|
|||
path_span,
|
||||
name_override.or(Some(module_name)),
|
||||
) {
|
||||
let module = working_set.get_module_mut(module_id);
|
||||
let mut module = working_set.get_module(module_id).clone();
|
||||
|
||||
for (submodule_name, submodule_id) in submodules {
|
||||
module.add_submodule(submodule_name, submodule_id);
|
||||
}
|
||||
|
||||
Some(module_id)
|
||||
let module_name = String::from_utf8_lossy(&module.name).to_string();
|
||||
|
||||
let module_comments =
|
||||
if let Some(comments) = working_set.get_module_comments(module_id) {
|
||||
comments.to_vec()
|
||||
} else {
|
||||
vec![]
|
||||
};
|
||||
|
||||
let new_module_id =
|
||||
working_set.add_module(&module_name, module, module_comments);
|
||||
|
||||
Some(new_module_id)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
|
|
@ -1322,6 +1322,13 @@ impl<'a> StateWorkingSet<'a> {
|
|||
module_id
|
||||
}
|
||||
|
||||
pub fn get_module_comments(&self, module_id: ModuleId) -> Option<&[Span]> {
|
||||
self.delta
|
||||
.usage
|
||||
.get_module_comments(module_id)
|
||||
.or_else(|| self.permanent_state.get_module_comments(module_id))
|
||||
}
|
||||
|
||||
pub fn next_span_start(&self) -> usize {
|
||||
let permanent_span_start = self.permanent_state.next_span_start();
|
||||
|
||||
|
@ -1779,18 +1786,6 @@ impl<'a> StateWorkingSet<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_module_mut(&mut self, module_id: ModuleId) -> &mut Module {
|
||||
let num_permanent_modules = self.permanent_state.num_modules();
|
||||
if module_id < num_permanent_modules {
|
||||
panic!("Attempt to mutate a module that is in the permanent (immutable) state")
|
||||
} else {
|
||||
self.delta
|
||||
.modules
|
||||
.get_mut(module_id - num_permanent_modules)
|
||||
.expect("internal error: missing module")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_block_mut(&mut self, block_id: BlockId) -> &mut Block {
|
||||
let num_permanent_blocks = self.permanent_state.num_blocks();
|
||||
if block_id < num_permanent_blocks {
|
||||
|
@ -1997,6 +1992,22 @@ impl<'a> StateWorkingSet<'a> {
|
|||
|
||||
None
|
||||
}
|
||||
|
||||
pub fn find_module_by_span(&self, span: Span) -> Option<ModuleId> {
|
||||
for (id, module) in self.delta.modules.iter().enumerate() {
|
||||
if Some(span) == module.span {
|
||||
return Some(self.permanent_state.num_modules() + id);
|
||||
}
|
||||
}
|
||||
|
||||
for (module_id, module) in self.permanent_state.modules.iter().enumerate() {
|
||||
if Some(span) == module.span {
|
||||
return Some(module_id);
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for EngineState {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use nu_test_support::fs::Stub::FileWithContentToBeTrimmed;
|
||||
use nu_test_support::playground::Playground;
|
||||
use nu_test_support::{nu, pipeline};
|
||||
use nu_test_support::{nu, nu_repl_code, pipeline};
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
#[test]
|
||||
|
@ -641,6 +641,14 @@ fn module_dir() {
|
|||
assert_eq!(actual.out, "spambaz");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn module_dir_import_twice_no_panic() {
|
||||
let import = "use samples/spam";
|
||||
let inp = &[import, import, "spam"];
|
||||
let actual_repl = nu!(cwd: "tests/modules", nu_repl_code(inp));
|
||||
assert_eq!(actual_repl.out, "spam");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn not_allowed_submodule_file() {
|
||||
let inp = &["use samples/not_allowed"];
|
||||
|
|
Loading…
Reference in a new issue