mirror of
https://github.com/roc-lang/roc.git
synced 2025-12-15 21:23:57 +00:00
Handle root type when loading from str
This commit is contained in:
parent
0283bd1d24
commit
4e5fdfbf52
12 changed files with 127 additions and 101 deletions
|
|
@ -1303,6 +1303,7 @@ pub fn build_str_test<'a>(
|
|||
PathBuf::from("valgrind_test.roc"),
|
||||
app_module_source,
|
||||
app_module_path.to_path_buf(),
|
||||
None,
|
||||
roc_cache_dir,
|
||||
load_config,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ fn write_types_for_module_real(module_id: ModuleId, filename: &str, output_path:
|
|||
PathBuf::from(filename),
|
||||
source,
|
||||
cwd,
|
||||
None,
|
||||
Default::default(),
|
||||
target,
|
||||
function_kind,
|
||||
|
|
|
|||
|
|
@ -104,12 +104,14 @@ pub fn load_and_monomorphize_from_str<'a>(
|
|||
filename: PathBuf,
|
||||
src: &'a str,
|
||||
src_dir: PathBuf,
|
||||
opt_main_path: Option<PathBuf>,
|
||||
roc_cache_dir: RocCacheDir<'_>,
|
||||
load_config: LoadConfig,
|
||||
) -> Result<MonomorphizedModule<'a>, LoadMonomorphizedError<'a>> {
|
||||
use LoadResult::*;
|
||||
|
||||
let load_start = LoadStart::from_str(arena, filename, src, roc_cache_dir, src_dir)?;
|
||||
let load_start =
|
||||
LoadStart::from_str(arena, filename, opt_main_path, src, roc_cache_dir, src_dir)?;
|
||||
let exposed_types = ExposedByModule::default();
|
||||
|
||||
match load(arena, load_start, exposed_types, roc_cache_dir, load_config)? {
|
||||
|
|
@ -176,6 +178,7 @@ pub fn load_and_typecheck_str<'a>(
|
|||
filename: PathBuf,
|
||||
source: &'a str,
|
||||
src_dir: PathBuf,
|
||||
opt_main_path: Option<PathBuf>,
|
||||
target: Target,
|
||||
function_kind: FunctionKind,
|
||||
render: RenderTarget,
|
||||
|
|
@ -184,7 +187,14 @@ pub fn load_and_typecheck_str<'a>(
|
|||
) -> Result<LoadedModule, LoadingProblem<'a>> {
|
||||
use LoadResult::*;
|
||||
|
||||
let load_start = LoadStart::from_str(arena, filename, source, roc_cache_dir, src_dir)?;
|
||||
let load_start = LoadStart::from_str(
|
||||
arena,
|
||||
filename,
|
||||
opt_main_path,
|
||||
source,
|
||||
roc_cache_dir,
|
||||
src_dir,
|
||||
)?;
|
||||
|
||||
// NOTE: this function is meant for tests, and so we use single-threaded
|
||||
// solving so we don't use too many threads per-test. That gives higher
|
||||
|
|
|
|||
|
|
@ -1081,6 +1081,7 @@ pub fn load_and_typecheck_str<'a>(
|
|||
filename: PathBuf,
|
||||
source: &'a str,
|
||||
src_dir: PathBuf,
|
||||
opt_main_path: Option<PathBuf>,
|
||||
exposed_types: ExposedByModule,
|
||||
target: Target,
|
||||
function_kind: FunctionKind,
|
||||
|
|
@ -1091,7 +1092,14 @@ pub fn load_and_typecheck_str<'a>(
|
|||
) -> Result<LoadedModule, LoadingProblem<'a>> {
|
||||
use LoadResult::*;
|
||||
|
||||
let load_start = LoadStart::from_str(arena, filename, source, roc_cache_dir, src_dir)?;
|
||||
let load_start = LoadStart::from_str(
|
||||
arena,
|
||||
filename,
|
||||
opt_main_path,
|
||||
source,
|
||||
roc_cache_dir,
|
||||
src_dir,
|
||||
)?;
|
||||
|
||||
// this function is used specifically in the case
|
||||
// where we want to regenerate the cached data
|
||||
|
|
@ -1161,7 +1169,7 @@ impl<'a> LoadStart<'a> {
|
|||
// Load the root module synchronously; we can't proceed until we have its id.
|
||||
let root_start_time = Instant::now();
|
||||
|
||||
let res_loaded = load_filename(
|
||||
let load_result = load_filename(
|
||||
arena,
|
||||
filename.clone(),
|
||||
true,
|
||||
|
|
@ -1173,57 +1181,22 @@ impl<'a> LoadStart<'a> {
|
|||
root_start_time,
|
||||
);
|
||||
|
||||
let (header_output, root_type) = match res_loaded {
|
||||
Ok(mut header_output) => {
|
||||
if let Msg::Header(ModuleHeader {
|
||||
module_id: header_id,
|
||||
header_type,
|
||||
..
|
||||
}) = &header_output.msg
|
||||
{
|
||||
debug_assert_eq!(*header_id, header_output.module_id);
|
||||
let load_result = match load_result {
|
||||
Ok(header_output) => handle_root_type(
|
||||
arena,
|
||||
Arc::clone(&arc_shorthands),
|
||||
Arc::clone(&arc_modules),
|
||||
Arc::clone(&ident_ids_by_module),
|
||||
roc_cache_dir,
|
||||
header_output,
|
||||
opt_main_path,
|
||||
&mut src_dir,
|
||||
),
|
||||
Err(problem) => Err(problem),
|
||||
};
|
||||
|
||||
use HeaderType::*;
|
||||
|
||||
match header_type {
|
||||
Module { .. } | Builtin { .. } | Hosted { .. } => {
|
||||
let main_path =
|
||||
opt_main_path.or_else(|| find_main_roc_recursively(&mut src_dir));
|
||||
|
||||
let cache_dir = roc_cache_dir.as_persistent_path();
|
||||
|
||||
if let (Some(main_path), Some(cache_dir)) =
|
||||
(main_path.clone(), cache_dir)
|
||||
{
|
||||
let mut messages = Vec::with_capacity(4);
|
||||
messages.push(header_output.msg);
|
||||
|
||||
load_packages_from_main(
|
||||
arena,
|
||||
src_dir.clone(),
|
||||
main_path,
|
||||
&mut messages,
|
||||
Arc::clone(&arc_modules),
|
||||
Arc::clone(&ident_ids_by_module),
|
||||
Arc::clone(&arc_shorthands),
|
||||
cache_dir,
|
||||
)?;
|
||||
|
||||
header_output.msg = Msg::Many(messages);
|
||||
}
|
||||
|
||||
let header_output = adjust_header_paths(header_output, &mut src_dir);
|
||||
|
||||
(header_output, RootType::Module { main_path })
|
||||
}
|
||||
App { .. } | Package { .. } | Platform { .. } => {
|
||||
(header_output, RootType::Main)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
(header_output, RootType::Main)
|
||||
}
|
||||
}
|
||||
let (header_output, root_type) = match load_result {
|
||||
Ok(header_output) => header_output,
|
||||
|
||||
Err(problem) => {
|
||||
let module_ids = Arc::try_unwrap(arc_modules)
|
||||
|
|
@ -1257,6 +1230,7 @@ impl<'a> LoadStart<'a> {
|
|||
pub fn from_str(
|
||||
arena: &'a Bump,
|
||||
filename: PathBuf,
|
||||
opt_main_path: Option<PathBuf>,
|
||||
src: &'a str,
|
||||
roc_cache_dir: RocCacheDir<'_>,
|
||||
mut src_dir: PathBuf,
|
||||
|
|
@ -1267,25 +1241,34 @@ impl<'a> LoadStart<'a> {
|
|||
let ident_ids_by_module = Arc::new(Mutex::new(root_exposed_ident_ids));
|
||||
|
||||
// Load the root module synchronously; we can't proceed until we have its id.
|
||||
let root_start_time = Instant::now();
|
||||
|
||||
let header_output = load_from_str(
|
||||
arena,
|
||||
filename.clone(),
|
||||
src,
|
||||
Arc::clone(&arc_modules),
|
||||
Arc::clone(&ident_ids_by_module),
|
||||
roc_cache_dir,
|
||||
root_start_time,
|
||||
)?;
|
||||
|
||||
let (header_output, root_type) = handle_root_type(
|
||||
arena,
|
||||
Arc::clone(&arc_shorthands),
|
||||
Arc::clone(&arc_modules),
|
||||
Arc::clone(&ident_ids_by_module),
|
||||
roc_cache_dir,
|
||||
header_output,
|
||||
opt_main_path,
|
||||
&mut src_dir,
|
||||
)?;
|
||||
|
||||
let HeaderOutput {
|
||||
module_id: root_id,
|
||||
msg: root_msg,
|
||||
opt_platform_shorthand: opt_platform_id,
|
||||
} = {
|
||||
let root_start_time = Instant::now();
|
||||
|
||||
let header_output = load_from_str(
|
||||
arena,
|
||||
filename.clone(),
|
||||
src,
|
||||
Arc::clone(&arc_modules),
|
||||
Arc::clone(&ident_ids_by_module),
|
||||
roc_cache_dir,
|
||||
root_start_time,
|
||||
)?;
|
||||
|
||||
adjust_header_paths(header_output, &mut src_dir)
|
||||
};
|
||||
} = header_output;
|
||||
|
||||
Ok(LoadStart {
|
||||
arc_modules,
|
||||
|
|
@ -1295,13 +1278,65 @@ impl<'a> LoadStart<'a> {
|
|||
root_id,
|
||||
root_path: filename,
|
||||
root_msg,
|
||||
// todo(agus): could be module
|
||||
root_type: RootType::Main,
|
||||
root_type,
|
||||
opt_platform_shorthand: opt_platform_id,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_root_type<'a>(
|
||||
arena: &'a Bump,
|
||||
arc_shorthands: Arc<Mutex<MutMap<&'a str, ShorthandPath>>>,
|
||||
arc_modules: Arc<Mutex<PackageModuleIds<'a>>>,
|
||||
ident_ids_by_module: SharedIdentIdsByModule,
|
||||
roc_cache_dir: RocCacheDir<'_>,
|
||||
mut header_output: HeaderOutput<'a>,
|
||||
opt_main_path: Option<PathBuf>,
|
||||
src_dir: &mut PathBuf,
|
||||
) -> Result<(HeaderOutput<'a>, RootType), LoadingProblem<'a>> {
|
||||
if let Msg::Header(ModuleHeader {
|
||||
module_id: header_id,
|
||||
header_type,
|
||||
..
|
||||
}) = &header_output.msg
|
||||
{
|
||||
debug_assert_eq!(*header_id, header_output.module_id);
|
||||
|
||||
use HeaderType::*;
|
||||
|
||||
match header_type {
|
||||
Module { .. } | Builtin { .. } | Hosted { .. } => {
|
||||
let main_path = opt_main_path.or_else(|| find_main_roc_recursively(src_dir));
|
||||
|
||||
let cache_dir = roc_cache_dir.as_persistent_path();
|
||||
|
||||
if let (Some(main_path), Some(cache_dir)) = (main_path.clone(), cache_dir) {
|
||||
let mut messages = Vec::with_capacity(4);
|
||||
messages.push(header_output.msg);
|
||||
|
||||
load_packages_from_main(
|
||||
arena,
|
||||
src_dir.clone(),
|
||||
main_path,
|
||||
&mut messages,
|
||||
Arc::clone(&arc_modules),
|
||||
Arc::clone(&ident_ids_by_module),
|
||||
Arc::clone(&arc_shorthands),
|
||||
cache_dir,
|
||||
)?;
|
||||
|
||||
header_output.msg = Msg::Many(messages);
|
||||
}
|
||||
|
||||
Ok((header_output, RootType::Module { main_path }))
|
||||
}
|
||||
App { .. } | Package { .. } | Platform { .. } => Ok((header_output, RootType::Main)),
|
||||
}
|
||||
} else {
|
||||
Ok((header_output, RootType::Main))
|
||||
}
|
||||
}
|
||||
|
||||
fn find_main_roc_recursively(src_dir: &mut PathBuf) -> Option<PathBuf> {
|
||||
let original_src_dir = src_dir.clone();
|
||||
|
||||
|
|
@ -1351,7 +1386,7 @@ fn load_packages_from_main<'a>(
|
|||
unspace(arena, packages.value.items)
|
||||
}
|
||||
Platform(PlatformHeader { packages, .. }) => unspace(arena, packages.item.items),
|
||||
Module(_) | Hosted(_) => todo!("agus: report bad main"),
|
||||
Module(_) | Hosted(_) => todo!("expected {} to be an app or package", filename.display()),
|
||||
};
|
||||
|
||||
load_packages(
|
||||
|
|
@ -1382,35 +1417,6 @@ fn load_packages_from_main<'a>(
|
|||
)
|
||||
}
|
||||
|
||||
fn adjust_header_paths<'a>(
|
||||
header_output: HeaderOutput<'a>,
|
||||
src_dir: &mut PathBuf,
|
||||
) -> HeaderOutput<'a> {
|
||||
if let Msg::Header(ModuleHeader {
|
||||
module_id: header_id,
|
||||
header_type,
|
||||
..
|
||||
}) = &header_output.msg
|
||||
{
|
||||
debug_assert_eq!(*header_id, header_output.module_id);
|
||||
|
||||
if let HeaderType::Module { name, .. } = header_type {
|
||||
// [modules-revamp] TODO: Privacy changes
|
||||
// Modules can have names like Foo.Bar.Baz,
|
||||
// in which case we need to adjust the src_dir to
|
||||
// remove the "Bar/Baz" directories in order to correctly
|
||||
// resolve this interface module's imports!
|
||||
let dirs_to_pop = name.as_str().matches('.').count();
|
||||
|
||||
for _ in 0..dirs_to_pop {
|
||||
src_dir.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
header_output
|
||||
}
|
||||
|
||||
pub enum LoadResult<'a> {
|
||||
TypeChecked(LoadedModule),
|
||||
Monomorphized(MonomorphizedModule<'a>),
|
||||
|
|
|
|||
|
|
@ -530,6 +530,7 @@ where
|
|||
path.file_name().unwrap().into(),
|
||||
source,
|
||||
path.parent().unwrap().to_path_buf(),
|
||||
None,
|
||||
Default::default(),
|
||||
target,
|
||||
FunctionKind::LambdaSet,
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ fn create_llvm_module<'a>(
|
|||
filename,
|
||||
module_src,
|
||||
src_dir,
|
||||
None,
|
||||
RocCacheDir::Disallowed,
|
||||
load_config,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -117,6 +117,7 @@ fn compiles_to_ir(test_name: &str, src: &str, mode: &str, allow_type_errors: boo
|
|||
filename,
|
||||
module_src,
|
||||
src_dir,
|
||||
None,
|
||||
RocCacheDir::Disallowed,
|
||||
load_config,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ pub fn run_load_and_infer<'a>(
|
|||
file_path,
|
||||
module_src,
|
||||
dir.path().to_path_buf(),
|
||||
None,
|
||||
roc_target::Target::LinuxX64,
|
||||
function_kind,
|
||||
roc_reporting::report::RenderTarget::Generic,
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ pub(crate) fn write_compiled_ir<'a>(
|
|||
file_path,
|
||||
test_module,
|
||||
dir.path().to_path_buf(),
|
||||
None,
|
||||
RocCacheDir::Disallowed,
|
||||
load_config,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ pub(crate) fn global_analysis(doc_info: DocInfo) -> Vec<AnalyzedDocument> {
|
|||
fi,
|
||||
&doc_info.source,
|
||||
src_dir,
|
||||
None,
|
||||
roc_target::Target::LinuxX64,
|
||||
roc_load::FunctionKind::LambdaSet,
|
||||
roc_reporting::report::RenderTarget::LanguageServer,
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ pub fn compile_to_mono<'a, 'i, I: Iterator<Item = &'i str>>(
|
|||
filename,
|
||||
module_src,
|
||||
src_dir,
|
||||
None,
|
||||
RocCacheDir::Persistent(cache::roc_cache_dir().as_path()),
|
||||
LoadConfig {
|
||||
target,
|
||||
|
|
|
|||
|
|
@ -130,6 +130,7 @@ mod test {
|
|||
filename,
|
||||
source,
|
||||
src_dir.path().to_path_buf(),
|
||||
None,
|
||||
RocCacheDir::Disallowed,
|
||||
load_config,
|
||||
) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue