Merge pull request #6840 from roc-lang/load-transitive-pkgs

Load packages of packages
This commit is contained in:
Luke Boswell 2024-06-26 11:38:44 +10:00 committed by GitHub
commit 6a074adcf2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 152 additions and 29 deletions

View file

@ -1436,6 +1436,54 @@ mod cli_run {
);
}
#[test]
#[serial(multi_dep_thunk)]
#[cfg_attr(windows, ignore)]
fn run_transitive_deps_app() {
check_output_with_stdin(
&fixture_file("transitive-deps", "direct-one.roc"),
&[],
&[],
&[],
&[],
"[One imports Two: From two]\n",
UseValgrind::Yes,
TestCliCommands::Run,
);
}
#[test]
#[serial(multi_dep_thunk)]
#[cfg_attr(windows, ignore)]
fn run_transitive_and_direct_dep_app() {
check_output_with_stdin(
&fixture_file("transitive-deps", "direct-one-and-two.roc"),
&[],
&[],
&[],
&[],
"[One imports Two: From two] | From two\n",
UseValgrind::Yes,
TestCliCommands::Run,
);
}
#[test]
#[serial(multi_dep_thunk)]
#[cfg_attr(windows, ignore)]
fn run_double_transitive_dep_app() {
check_output_with_stdin(
&fixture_file("transitive-deps", "direct-zero.roc"),
&[],
&[],
&[],
&[],
"[Zero imports One: [One imports Two: From two]]\n",
UseValgrind::Yes,
TestCliCommands::Run,
);
}
#[test]
fn known_type_error() {
check_compile_error(

View file

@ -0,0 +1,10 @@
app [main] {
pf: platform "../packages/platform/main.roc",
one: "one/main.roc",
two: "two/main.roc",
}
import one.One
import two.Two
main = "$(One.example) | $(Two.example)"

View file

@ -0,0 +1,8 @@
app [main] {
pf: platform "../packages/platform/main.roc",
one: "one/main.roc",
}
import one.One
main = One.example

View file

@ -0,0 +1,8 @@
app [main] {
pf: platform "../packages/platform/main.roc",
zero: "zero/main.roc",
}
import zero.Zero
main = Zero.example

View file

@ -0,0 +1,5 @@
module [example]
import two.Two
example = "[One imports Two: $(Two.example)]"

View file

@ -0,0 +1,3 @@
package [One] {
two: "../two/main.roc",
}

View file

@ -0,0 +1,3 @@
module [example]
example = "From two"

View file

@ -0,0 +1 @@
package [Two] {}

View file

@ -0,0 +1,5 @@
module [example]
import one.One
example = "[Zero imports One: $(One.example)]"

View file

@ -0,0 +1,3 @@
package [Zero] {
one: "../one/main.roc"
}

View file

@ -1560,15 +1560,7 @@ pub fn load_single_threaded<'a>(
// now we just manually interleave stepping the state "thread" and the worker "thread"
loop {
match state_thread_step(
arena,
state,
&src_dir,
worker_listeners,
&injector,
&msg_tx,
&msg_rx,
) {
match state_thread_step(arena, state, worker_listeners, &injector, &msg_tx, &msg_rx) {
Ok(ControlFlow::Break(done)) => return Ok(done),
Ok(ControlFlow::Continue(new_state)) => {
state = new_state;
@ -1595,7 +1587,6 @@ pub fn load_single_threaded<'a>(
fn state_thread_step<'a>(
arena: &'a Bump,
state: State<'a>,
src_dir: &Path,
worker_listeners: &'a [Sender<WorkerMsg>],
injector: &Injector<BuildTask<'a>>,
msg_tx: &crossbeam::channel::Sender<Msg<'a>>,
@ -1704,7 +1695,6 @@ fn state_thread_step<'a>(
let res_state = update(
state,
src_dir,
msg,
msg_tx.clone(),
injector,
@ -2050,15 +2040,8 @@ fn load_multi_threaded<'a>(
// The root module will have already queued up messages to process,
// and processing those messages will in turn queue up more messages.
loop {
match state_thread_step(
arena,
state,
&src_dir,
worker_listeners,
&injector,
&msg_tx,
&msg_rx,
) {
match state_thread_step(arena, state, worker_listeners, &injector, &msg_tx, &msg_rx)
{
Ok(ControlFlow::Break(load_result)) => {
shut_down_worker_threads!();
@ -2174,7 +2157,6 @@ fn extend_module_with_builtin_import(module: &mut ParsedModule, module_id: Modul
fn update<'a>(
mut state: State<'a>,
src_dir: &Path,
msg: Msg<'a>,
msg_tx: MsgSender<'a>,
injector: &Injector<BuildTask<'a>>,
@ -2203,11 +2185,14 @@ fn update<'a>(
if !header.packages.is_empty() {
let mut shorthands = state.arc_shorthands.lock();
let mut parent_dir = header.module_path.clone();
parent_dir.pop();
register_package_shorthands(
&mut shorthands,
&header.packages,
&header.module_path,
src_dir,
&parent_dir,
&state.cache_dir,
)?;
}
@ -3347,6 +3332,7 @@ fn load_package_from_disk<'a>(
arena: &'a Bump,
filename: &Path,
shorthand: &'a str,
roc_cache_dir: RocCacheDir,
app_module_id: Option<ModuleId>,
module_ids: Arc<Mutex<PackageModuleIds<'a>>>,
ident_ids_by_module: SharedIdentIdsByModule,
@ -3405,20 +3391,41 @@ fn load_package_from_disk<'a>(
},
parser_state,
)) => {
let (_, _, package_module_msg) = build_package_header(
let mut parent_dir = filename.to_path_buf();
parent_dir.pop();
let packages = unspace(arena, header.packages.value.items);
let (_, _, header) = build_package_header(
arena,
Some(shorthand),
false, // cannot be the root if loaded as a package
filename.to_path_buf(),
parser_state,
module_ids,
ident_ids_by_module,
module_ids.clone(),
ident_ids_by_module.clone(),
&header,
comments,
pkg_module_timing,
)?;
Ok(Msg::Header(package_module_msg))
let filename = header.module_path.clone();
let mut messages = Vec::with_capacity(packages.len() + 1);
messages.push(Msg::Header(header));
load_packages(
packages,
&mut messages,
roc_cache_dir,
parent_dir,
arena,
None,
module_ids,
ident_ids_by_module,
filename,
);
Ok(Msg::Many(messages))
}
Ok((
ast::Module {
@ -3427,6 +3434,11 @@ fn load_package_from_disk<'a>(
},
parser_state,
)) => {
let mut parent_dir = filename.to_path_buf();
parent_dir.pop();
let packages = unspace(arena, header.packages.item.items);
let exposes_ids = get_exposes_ids(
header.exposes.item.items,
arena,
@ -3435,21 +3447,37 @@ fn load_package_from_disk<'a>(
);
// make a `platform` module that ultimately exposes `main` to the host
let (_, _, platform_module_msg) = build_platform_header(
let (_, _, header) = build_platform_header(
arena,
Some(shorthand),
false, // cannot be the root if loaded as a package
app_module_id,
filename.to_path_buf(),
parser_state,
module_ids,
module_ids.clone(),
exposes_ids.into_bump_slice(),
&header,
comments,
pkg_module_timing,
)?;
Ok(Msg::Header(platform_module_msg))
let filename = header.module_path.clone();
let mut messages = Vec::with_capacity(packages.len() + 1);
messages.push(Msg::Header(header));
load_packages(
packages,
&mut messages,
roc_cache_dir,
parent_dir,
arena,
None,
module_ids,
ident_ids_by_module,
filename,
);
Ok(Msg::Many(messages))
}
Err(fail) => Err(LoadingProblem::ParsingFailed(
fail.map_problem(SyntaxError::Header)
@ -4091,6 +4119,7 @@ fn load_packages<'a>(
arena,
&root_module_path,
shorthand,
roc_cache_dir,
app_module_id,
module_ids.clone(),
ident_ids_by_module.clone(),