mirror of
https://github.com/nushell/nushell
synced 2024-11-10 15:14:14 +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 file_id = working_set.add_file(path.to_string_lossy().to_string(), &contents);
|
||||||
let new_span = working_set.get_span_for_file(file_id);
|
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
|
// Change the currently parsed directory
|
||||||
let prev_currently_parsed_cwd = if let Some(parent) = path.parent() {
|
let prev_currently_parsed_cwd = if let Some(parent) = path.parent() {
|
||||||
let prev = working_set.currently_parsed_cwd.clone();
|
let prev = working_set.currently_parsed_cwd.clone();
|
||||||
|
@ -1834,13 +1838,25 @@ pub fn parse_module_file_or_dir(
|
||||||
path_span,
|
path_span,
|
||||||
name_override.or(Some(module_name)),
|
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 {
|
for (submodule_name, submodule_id) in submodules {
|
||||||
module.add_submodule(submodule_name, submodule_id);
|
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 {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
|
@ -1322,6 +1322,13 @@ impl<'a> StateWorkingSet<'a> {
|
||||||
module_id
|
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 {
|
pub fn next_span_start(&self) -> usize {
|
||||||
let permanent_span_start = self.permanent_state.next_span_start();
|
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 {
|
pub fn get_block_mut(&mut self, block_id: BlockId) -> &mut Block {
|
||||||
let num_permanent_blocks = self.permanent_state.num_blocks();
|
let num_permanent_blocks = self.permanent_state.num_blocks();
|
||||||
if block_id < num_permanent_blocks {
|
if block_id < num_permanent_blocks {
|
||||||
|
@ -1997,6 +1992,22 @@ impl<'a> StateWorkingSet<'a> {
|
||||||
|
|
||||||
None
|
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 {
|
impl Default for EngineState {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use nu_test_support::fs::Stub::FileWithContentToBeTrimmed;
|
use nu_test_support::fs::Stub::FileWithContentToBeTrimmed;
|
||||||
use nu_test_support::playground::Playground;
|
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;
|
use pretty_assertions::assert_eq;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -641,6 +641,14 @@ fn module_dir() {
|
||||||
assert_eq!(actual.out, "spambaz");
|
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]
|
#[test]
|
||||||
fn not_allowed_submodule_file() {
|
fn not_allowed_submodule_file() {
|
||||||
let inp = &["use samples/not_allowed"];
|
let inp = &["use samples/not_allowed"];
|
||||||
|
|
Loading…
Reference in a new issue