finish impl

This commit is contained in:
WindSoilder 2024-06-18 17:54:57 +08:00
parent 3c43258bbd
commit 6862bf0e26
3 changed files with 70 additions and 12 deletions

View File

@ -1211,6 +1211,7 @@ pub fn parse_export_in_module(
working_set: &mut StateWorkingSet,
lite_command: &LiteCommand,
module_name: &[u8],
module: &mut Module,
) -> (Pipeline, Vec<Exportable>) {
let spans = &lite_command.parts[..];
@ -1416,7 +1417,7 @@ pub fn parse_export_in_module(
pipe: lite_command.pipe,
redirection: lite_command.redirection.clone(),
};
let (pipeline, exportables) = parse_use(working_set, &lite_command);
let (pipeline, exportables) = parse_use(working_set, &lite_command, Some(module));
let export_use_decl_id = if let Some(id) = working_set.find_decl(b"export use") {
id
@ -1774,7 +1775,7 @@ pub fn parse_module_block(
}
b"export" => {
let (pipe, exportables) =
parse_export_in_module(working_set, command, module_name);
parse_export_in_module(working_set, command, module_name, &mut module);
for exportable in exportables {
match exportable {
@ -1922,23 +1923,38 @@ fn parse_module_file(
// Check if we've parsed the module before.
if let Some(module_id) = working_set.find_module_by_span(new_span) {
return Some(module_id);
let module = working_set.get_module(module_id);
// check if it contains submodules with a file name.
let has_export_submodules = module
.submodules
.iter()
.any(|(_, m)| working_set.get_module(*m).file.is_some());
// check if it's using other modules with a file name.
let has_use_submodules = module
.imported_modules
.iter()
.any(|m| working_set.get_module(*m).file.is_some());
if !(has_export_submodules || has_use_submodules) {
return Some(module_id);
}
}
// Add the file to the stack of files being processed.
if let Err(e) = working_set.files.push(path.path_buf(), path_span) {
let path_buf = path.path_buf();
if let Err(e) = working_set.files.push(path_buf.clone(), path_span) {
working_set.error(e);
return None;
}
// Parse the module
let (block, module, module_comments) =
let (block, mut module, module_comments) =
parse_module_block(working_set, new_span, module_name.as_bytes());
// Remove the file from the stack of files being processed.
working_set.files.pop();
let _ = working_set.add_block(Arc::new(block));
module.file = Some(path_buf);
let module_id = working_set.add_module(&module_name, module, module_comments);
Some(module_id)
@ -2422,7 +2438,7 @@ pub fn parse_use(
import_pattern.constants = constants.iter().map(|(_, id)| *id).collect();
if let Some(m) = user_module {
m.add_usage_modules(
m.track_imported_modules(
definitions
.modules
.iter()

View File

@ -36,7 +36,7 @@ pub struct Module {
pub env_block: Option<BlockId>, // `export-env { ... }` block
pub main: Option<DeclId>, // `export def main`
pub span: Option<Span>,
pub use_modules: Vec<ModuleId>,
pub imported_modules: Vec<ModuleId>, // use other_module.nu
pub file: Option<PathBuf>,
}
@ -50,7 +50,7 @@ impl Module {
env_block: None,
main: None,
span: None,
use_modules: vec![],
imported_modules: vec![],
file: None,
}
}
@ -64,7 +64,7 @@ impl Module {
env_block: None,
main: None,
span: Some(span),
use_modules: vec![],
imported_modules: vec![],
file: None,
}
}
@ -89,9 +89,9 @@ impl Module {
self.env_block = Some(block_id);
}
pub fn add_usage_modules(&mut self, module_id: &[ModuleId]) {
pub fn track_imported_modules(&mut self, module_id: &[ModuleId]) {
for m in module_id {
self.use_modules.push(*m)
self.imported_modules.push(*m)
}
}

View File

@ -1,4 +1,4 @@
use nu_test_support::fs::Stub::FileWithContentToBeTrimmed;
use nu_test_support::fs::Stub::{FileWithContent, FileWithContentToBeTrimmed};
use nu_test_support::playground::Playground;
use nu_test_support::{nu, nu_repl_code};
use pretty_assertions::assert_eq;
@ -760,3 +760,45 @@ fn nested_list_export_works() {
let actual = nu!(&inp.join("; "));
assert_eq!(actual.out, "bacon");
}
#[test]
fn reload_submodules() {
Playground::setup("reload_submodule_changed_file", |dirs, sandbox| {
sandbox.with_files(&[
FileWithContent("voice.nu", r#"export module animals.nu"#),
FileWithContent("animals.nu", "export def cat [] { 'meow'}"),
]);
let inp = [
"use voice.nu",
r#""export def cat [] {'woem'}" | save -f animals.nu"#,
"use voice.nu",
"(voice animals cat) == 'woem'",
];
let actual = nu!(cwd: dirs.test(), nu_repl_code(&inp));
assert_eq!(actual.out, "true");
});
}
#[test]
fn use_submodules() {
Playground::setup("reload_submodule_changed_file", |dirs, sandbox| {
sandbox.with_files(&[
FileWithContent("voice.nu", r#"export use animals.nu"#),
FileWithContent("animals.nu", "export def cat [] { 'meow'}"),
]);
let inp = [
"use voice.nu",
r#""export def cat [] {'woem'}" | save -f animals.nu"#,
"use voice.nu",
"(voice animals cat) == 'woem'",
];
let actual = nu!(cwd: dirs.test(), nu_repl_code(&inp));
assert_eq!(actual.out, "true");
});
}