make Pkg-Config work as a module

This commit is contained in:
Folkert 2020-12-08 22:58:30 +01:00
parent 4b665639ff
commit 3969a73277
4 changed files with 62 additions and 50 deletions

View File

@ -690,6 +690,7 @@ enum Msg<'a> {
#[derive(Debug)]
struct State<'a> {
pub root_id: ModuleId,
pub platform_id: Option<ModuleId>,
pub goal_phase: Phase,
pub stdlib: StdLib,
pub exposed_types: SubsByModule,
@ -844,12 +845,6 @@ enum BuildTask<'a> {
ident_ids_by_module: Arc<Mutex<MutMap<ModuleId, IdentIds>>>,
mode: Mode,
},
LoadPkgConfig {
shorthand: &'a str,
module_ids: Arc<Mutex<PackageModuleIds<'a>>>,
ident_ids_by_module: Arc<Mutex<MutMap<ModuleId, IdentIds>>>,
mode: Mode,
},
Parse {
header: ModuleHeader<'a>,
},
@ -1272,6 +1267,7 @@ where
let mut state = State {
root_id,
platform_id: None,
goal_phase,
stdlib,
output_path: None,
@ -1426,6 +1422,10 @@ fn update<'a>(
}
}
if let ModuleNameEnum::PkgConfig(_shorthand) = header.module_name {
state.platform_id = Some(header.module_id);
}
state.platform_path = state.platform_path.or_else(|| header.to_platform.clone());
// store an ID to name mapping, so we know the file to read when fetching dependencies' headers
@ -1603,7 +1603,7 @@ fn update<'a>(
let work = state.dependencies.notify(module_id, Phase::SolveTypes);
if module_id == state.root_id {
if Some(module_id) == state.platform_id {
state
.exposed_to_host
.extend(solved_module.exposed_vars_by_symbol.iter().copied());
@ -1638,15 +1638,10 @@ fn update<'a>(
// the originally requested module, we're all done!
return Ok(state);
} else {
if module_id != state.root_id {
state.exposed_types.insert(
module_id,
ExposedModuleTypes::Valid(
solved_module.solved_types,
solved_module.aliases,
),
ExposedModuleTypes::Valid(solved_module.solved_types, solved_module.aliases),
);
}
if state.goal_phase > Phase::SolveTypes {
let layout_cache = state.layout_caches.pop().unwrap_or_default();
@ -1914,6 +1909,7 @@ fn load_pkg_config<'a>(
arena: &'a Bump,
src_dir: &Path,
shorthand: &'a str,
app_module_id: ModuleId,
module_ids: Arc<Mutex<PackageModuleIds<'a>>>,
ident_ids_by_module: Arc<Mutex<MutMap<ModuleId, IdentIds>>>,
mode: Mode,
@ -1961,6 +1957,7 @@ fn load_pkg_config<'a>(
let pkg_config_module_msg = fabricate_pkg_config_module(
arena,
shorthand,
app_module_id,
filename,
parser_state,
module_ids.clone(),
@ -2183,6 +2180,7 @@ fn parse_header<'a>(
arena,
&pkg_config_roc,
shorthand,
module_id,
module_ids,
ident_ids_by_module,
mode,
@ -2488,10 +2486,13 @@ fn send_header<'a>(
#[allow(clippy::too_many_arguments)]
fn send_header_two<'a>(
arena: &'a Bump,
filename: PathBuf,
shorthand: &'a str,
app_module_id: ModuleId,
packages: &'a [Located<PackageEntry<'a>>],
provides: &'a [Located<ExposesEntry<'a, &'a str>>],
requires: &'a [Located<TypedIdent<'a>>],
imports: &'a [Located<ImportsEntry<'a>>],
to_platform: Option<To<'a>>,
parse_state: parser::State<'a>,
@ -2501,15 +2502,23 @@ fn send_header_two<'a>(
) -> (ModuleId, Msg<'a>) {
use inlinable_string::InlinableString;
let declared_name: InlinableString = "Pkg-Config".into();
let declared_name: InlinableString = "".into();
let mut imported: Vec<(QualifiedModuleName, Vec<Ident>, Region)> =
Vec::with_capacity(imports.len());
let mut imported_modules: MutSet<ModuleId> = MutSet::default();
let num_exposes = provides.len();
let mut deps_by_name: MutMap<PQModuleName, ModuleId> =
HashMap::with_capacity_and_hasher(num_exposes, default_hasher());
// add standard imports
// imported_modules.insert(ModuleId::APP);
// imported_modules.insert(ModuleId::EFFECT);
// TODO add Effect by default
imported_modules.insert(app_module_id);
deps_by_name.insert(
PQModuleName::Unqualified(ModuleName::APP.into()),
app_module_id,
);
let mut scope_size = 0;
@ -2521,9 +2530,6 @@ fn send_header_two<'a>(
imported.push((qualified_module_name, exposed, loc_entry.region));
}
let num_exposes = provides.len();
let mut deps_by_name: MutMap<PQModuleName, ModuleId> =
HashMap::with_capacity_and_hasher(num_exposes, default_hasher());
let mut exposed: Vec<Symbol> = Vec::with_capacity(num_exposes);
// Make sure the module_ids has ModuleIds for all our deps,
@ -2582,6 +2588,23 @@ fn send_header_two<'a>(
}
}
{
let ident_ids = ident_ids_by_module
.entry(app_module_id)
.or_insert_with(IdentIds::default);
for (loc_ident, _) in unpack_exposes_entries(arena, requires) {
let ident: Ident = loc_ident.value.into();
let ident_id = ident_ids.get_or_insert(ident.as_inline_str());
let symbol = Symbol::new(app_module_id, ident_id);
// Since this value is exposed, add it to our module's default scope.
debug_assert!(!scope.contains_key(&ident.clone()));
scope.insert(ident, (symbol, loc_ident.region));
}
}
let ident_ids = ident_ids_by_module.get_mut(&home).unwrap();
// Generate IdentIds entries for all values this module exposes.
@ -2771,24 +2794,26 @@ fn run_solve<'a>(
fn fabricate_pkg_config_module<'a>(
arena: &'a Bump,
shorthand: &'a str,
app_module_id: ModuleId,
filename: PathBuf,
parse_state: parser::State<'a>,
module_ids: Arc<Mutex<PackageModuleIds<'a>>>,
ident_ids_by_module: Arc<Mutex<MutMap<ModuleId, IdentIds>>>,
mode: Mode,
_mode: Mode,
header: &PlatformHeader<'a>,
module_timing: ModuleTiming,
) -> Result<(ModuleId, Msg<'a>), LoadingProblem> {
let name = format!("{}.Pkg-Config", shorthand);
let provides: &'a [Located<ExposesEntry<'a, &'a str>>] =
header.provides.clone().into_bump_slice();
Ok(send_header_two(
arena,
filename,
shorthand,
app_module_id,
&[],
provides,
header.requires.clone().into_bump_slice(),
header.imports.clone().into_bump_slice(),
None,
parse_state,
@ -3545,19 +3570,6 @@ fn run_task<'a>(
mode,
)
.map(|(_, msg)| msg),
LoadPkgConfig {
shorthand,
module_ids,
ident_ids_by_module,
mode,
} => load_pkg_config(
arena,
src_dir,
shorthand,
module_ids,
ident_ids_by_module,
mode,
),
Parse { header } => parse(arena, header),
CanonicalizeAndConstrain {
parsed,

View File

@ -3,6 +3,6 @@ app "effect-example"
imports [ base.Task.{ Task, after } ]
provides [ main ] to base
main : Task.Task {} I64 as Fx
main : Task.Task {} I64
main =
Task.succeed {}

View File

@ -2,7 +2,7 @@ platform folkertdev/foo
requires { main : Effect {} }
exposes []
packages {}
imports [ Effect ]
imports [ Task ]
provides [ mainForHost ]
effects Effect
{
@ -10,5 +10,5 @@ platform folkertdev/foo
readAllUtf8 : Str -> Effect { errno : I64, bytes : Str }
}
mainForHost : Effect.Effect {} as Fx
mainForHost = UserApp.main
mainForHost : Task.Task {} I64 as Fx
mainForHost = main

View File

@ -2,15 +2,15 @@ const std = @import("std");
const str = @import("../../../compiler/builtins/bitcode/src/str.zig");
const testing = std.testing;
extern fn roc__main_1_exposed([*]u8) void;
extern fn roc__main_1_size() i64;
extern fn roc__main_1_Fx_caller(*const u8, [*]u8, [*]u8) void;
extern fn roc__main_1_Fx_size() i64;
extern fn roc__mainForHost_1_exposed([*]u8) void;
extern fn roc__mainForHost_1_size() i64;
extern fn roc__mainForHost_1_Fx_caller(*const u8, [*]u8, [*]u8) void;
extern fn roc__mainForHost_1_Fx_size() i64;
pub export fn main() u8 {
const stdout = std.io.getStdOut().writer();
const size = @intCast(usize, roc__main_1_size());
const size = @intCast(usize, roc__mainForHost_1_size());
const raw_output = std.heap.c_allocator.alloc(u8, size) catch unreachable;
var output = @ptrCast([*]u8, raw_output);
@ -18,7 +18,7 @@ pub export fn main() u8 {
std.heap.c_allocator.free(raw_output);
}
roc__main_1_exposed(output);
roc__mainForHost_1_exposed(output);
const elements = @ptrCast([*]u64, @alignCast(8, output));
@ -38,7 +38,7 @@ pub export fn main() u8 {
}
fn call_the_closure(function_pointer: *const u8, closure_data_pointer: [*]u8) void {
const size = roc__main_1_Fx_size();
const size = roc__mainForHost_1_Fx_size();
const raw_output = std.heap.c_allocator.alloc(u8, @intCast(usize, size)) catch unreachable;
var output = @ptrCast([*]u8, raw_output);
@ -46,7 +46,7 @@ fn call_the_closure(function_pointer: *const u8, closure_data_pointer: [*]u8) vo
std.heap.c_allocator.free(raw_output);
}
roc__main_1_Fx_caller(function_pointer, closure_data_pointer, output);
roc__mainForHost_1_Fx_caller(function_pointer, closure_data_pointer, output);
const elements = @ptrCast([*]u64, @alignCast(8, output));