Revert "Merge PlatformHeaderInfo into revised HeaderInfo"

This reverts commit 6115781b9d.
This commit is contained in:
Richard Feldman 2022-12-06 14:06:05 -05:00
parent 579feeeadd
commit 2b1deff379
No known key found for this signature in database
GPG key ID: F1F21AA5B1D9E43B
3 changed files with 98 additions and 90 deletions

View file

@ -15,7 +15,7 @@ use roc_module::ident::Ident;
use roc_module::ident::Lowercase; use roc_module::ident::Lowercase;
use roc_module::symbol::{IdentIds, IdentIdsByModule, ModuleId, ModuleIds, Symbol}; use roc_module::symbol::{IdentIds, IdentIdsByModule, ModuleId, ModuleIds, Symbol};
use roc_parse::ast::{Defs, TypeAnnotation}; use roc_parse::ast::{Defs, TypeAnnotation};
use roc_parse::header::HeaderType; use roc_parse::header::HeaderFor;
use roc_parse::pattern::PatternType; use roc_parse::pattern::PatternType;
use roc_problem::can::{Problem, RuntimeError}; use roc_problem::can::{Problem, RuntimeError};
use roc_region::all::{Loc, Region}; use roc_region::all::{Loc, Region};
@ -194,18 +194,16 @@ enum GeneratedInfo {
} }
impl GeneratedInfo { impl GeneratedInfo {
fn from_header_type<'a>( fn from_header_for<'a>(
env: &mut Env, env: &mut Env,
scope: &mut Scope, scope: &mut Scope,
var_store: &mut VarStore, var_store: &mut VarStore,
header_type: &HeaderType<'a>, header_for: &HeaderFor<'a>,
) -> Self { ) -> Self {
match header_type { match header_for {
HeaderType::Hosted { HeaderFor::Hosted {
generates, generates,
generates_with, generates_with,
exposes: _,
imports: _,
} => { } => {
let name: &str = generates.into(); let name: &str = generates.into();
let (generated_functions, unknown_generated) = let (generated_functions, unknown_generated) =
@ -238,14 +236,11 @@ impl GeneratedInfo {
generated_functions, generated_functions,
} }
} }
HeaderType::Builtin { generates_with } => { HeaderFor::Builtin { generates_with } => {
debug_assert!(generates_with.is_empty()); debug_assert!(generates_with.is_empty());
GeneratedInfo::Builtin GeneratedInfo::Builtin
} }
HeaderType::App { .. } _ => GeneratedInfo::NotSpecial,
| HeaderType::Platform { .. }
| HeaderType::Interface { .. }
| HeaderType::Package { .. } => GeneratedInfo::NotSpecial,
} }
} }
} }
@ -271,7 +266,7 @@ fn has_no_implementation(expr: &Expr) -> bool {
pub fn canonicalize_module_defs<'a>( pub fn canonicalize_module_defs<'a>(
arena: &'a Bump, arena: &'a Bump,
loc_defs: &'a mut Defs<'a>, loc_defs: &'a mut Defs<'a>,
header_for: &roc_parse::header::HeaderType, header_for: &roc_parse::header::HeaderFor,
home: ModuleId, home: ModuleId,
module_ids: &'a ModuleIds, module_ids: &'a ModuleIds,
exposed_ident_ids: IdentIds, exposed_ident_ids: IdentIds,
@ -299,7 +294,7 @@ pub fn canonicalize_module_defs<'a>(
} }
let generated_info = let generated_info =
GeneratedInfo::from_header_type(&mut env, &mut scope, var_store, header_for); GeneratedInfo::from_header_for(&mut env, &mut scope, var_store, header_for);
// Desugar operators (convert them to Apply calls, taking into account // Desugar operators (convert them to Apply calls, taking into account
// operator precedence and associativity rules), before doing other canonicalization. // operator precedence and associativity rules), before doing other canonicalization.

View file

@ -41,7 +41,7 @@ use roc_packaging::cache::{self, RocCacheDir};
use roc_packaging::https::PackageMetadata; use roc_packaging::https::PackageMetadata;
use roc_parse::ast::{self, Defs, ExtractSpaces, Spaced, StrLiteral, TypeAnnotation}; use roc_parse::ast::{self, Defs, ExtractSpaces, Spaced, StrLiteral, TypeAnnotation};
use roc_parse::header::{ExposedName, ImportsEntry, PackageEntry, PlatformHeader, To, TypedIdent}; use roc_parse::header::{ExposedName, ImportsEntry, PackageEntry, PlatformHeader, To, TypedIdent};
use roc_parse::header::{HeaderType, ModuleNameEnum, PackageName}; use roc_parse::header::{HeaderFor, ModuleNameEnum, PackageName};
use roc_parse::ident::UppercaseIdent; use roc_parse::ident::UppercaseIdent;
use roc_parse::module::module_defs; use roc_parse::module::module_defs;
use roc_parse::parser::{FileError, Parser, SourceError, SyntaxError}; use roc_parse::parser::{FileError, Parser, SourceError, SyntaxError};
@ -633,7 +633,7 @@ struct ModuleHeader<'a> {
exposes: Vec<Symbol>, exposes: Vec<Symbol>,
exposed_imports: MutMap<Ident, (Symbol, Region)>, exposed_imports: MutMap<Ident, (Symbol, Region)>,
parse_state: roc_parse::state::State<'a>, parse_state: roc_parse::state::State<'a>,
header_type: HeaderType<'a>, header_for: HeaderFor<'a>,
symbols_from_requires: Vec<(Loc<Symbol>, Loc<TypeAnnotation<'a>>)>, symbols_from_requires: Vec<(Loc<Symbol>, Loc<TypeAnnotation<'a>>)>,
module_timing: ModuleTiming, module_timing: ModuleTiming,
} }
@ -773,7 +773,7 @@ struct ParsedModule<'a> {
parsed_defs: Defs<'a>, parsed_defs: Defs<'a>,
module_name: ModuleNameEnum<'a>, module_name: ModuleNameEnum<'a>,
symbols_from_requires: Vec<(Loc<Symbol>, Loc<TypeAnnotation<'a>>)>, symbols_from_requires: Vec<(Loc<Symbol>, Loc<TypeAnnotation<'a>>)>,
header_type: HeaderType<'a>, header_for: HeaderFor<'a>,
} }
type LocExpects = VecMap<Region, Vec<ExpectLookup>>; type LocExpects = VecMap<Region, Vec<ExpectLookup>>;
@ -2271,6 +2271,8 @@ fn update<'a>(
Ok(state) Ok(state)
} }
Header(header) => { Header(header) => {
use HeaderFor::*;
log!("loaded header for {:?}", header.module_id); log!("loaded header for {:?}", header.module_id);
let home = header.module_id; let home = header.module_id;
@ -2348,14 +2350,14 @@ fn update<'a>(
shorthands.insert(shorthand, shorthand_path); shorthands.insert(shorthand, shorthand_path);
} }
match header.header_type { match header.header_for {
HeaderType::App { to_platform } => { App { to_platform } => {
debug_assert!(matches!(state.platform_path, PlatformPath::NotSpecified)); debug_assert!(matches!(state.platform_path, PlatformPath::NotSpecified));
state.platform_path = PlatformPath::Valid(to_platform); state.platform_path = PlatformPath::Valid(to_platform);
} }
HeaderType::Platform { Platform {
main_for_host, main_for_host,
shorthand: config_shorthand, config_shorthand,
.. ..
} => { } => {
debug_assert!(matches!(state.platform_data, None)); debug_assert!(matches!(state.platform_data, None));
@ -2386,7 +2388,7 @@ fn update<'a>(
is_prebuilt, is_prebuilt,
}); });
} }
HeaderType::Builtin { .. } | HeaderType::Interface { .. } => { Builtin { .. } | Interface => {
if header.is_root_module { if header.is_root_module {
debug_assert!(matches!( debug_assert!(matches!(
state.platform_path, state.platform_path,
@ -2395,7 +2397,7 @@ fn update<'a>(
state.platform_path = PlatformPath::RootIsInterface; state.platform_path = PlatformPath::RootIsInterface;
} }
} }
HeaderType::Hosted { .. } => { Hosted { .. } => {
if header.is_root_module { if header.is_root_module {
debug_assert!(matches!( debug_assert!(matches!(
state.platform_path, state.platform_path,
@ -3371,7 +3373,7 @@ fn load_package_from_disk<'a>(
parser_state, parser_state,
)) => { )) => {
// make a `platform` module that ultimately exposes `main` to the host // make a `platform` module that ultimately exposes `main` to the host
Ok(fabricate_platform_module( let platform_module_msg = fabricate_platform_module(
arena, arena,
Some(shorthand), Some(shorthand),
Some(app_module_id), Some(app_module_id),
@ -3382,7 +3384,9 @@ fn load_package_from_disk<'a>(
&header, &header,
pkg_module_timing, pkg_module_timing,
) )
.1) .1;
Ok(platform_module_msg)
} }
Err(fail) => Err(LoadingProblem::ParsingFailed( Err(fail) => Err(LoadingProblem::ParsingFailed(
fail.map_problem(SyntaxError::Header) fail.map_problem(SyntaxError::Header)
@ -3430,7 +3434,7 @@ fn load_builtin_module_help<'a>(
packages: &[], packages: &[],
exposes: unspace(arena, header.exposes.item.items), exposes: unspace(arena, header.exposes.item.items),
imports: unspace(arena, header.imports.item.items), imports: unspace(arena, header.imports.item.items),
header_type: HeaderType::Builtin { extra: HeaderFor::Builtin {
generates_with: &[], generates_with: &[],
}, },
}; };
@ -3723,10 +3727,11 @@ fn parse_header<'a>(
}, },
filename, filename,
is_root_module, is_root_module,
header_type: HeaderType::Interface { opt_shorthand,
packages: &[],
exposes: unspace(arena, header.exposes.item.items), exposes: unspace(arena, header.exposes.item.items),
imports: unspace(arena, header.imports.item.items), imports: unspace(arena, header.imports.item.items),
}, extra: HeaderFor::Interface,
}; };
let (module_id, module_name, header) = build_header( let (module_id, module_name, header) = build_header(
@ -3771,11 +3776,13 @@ fn parse_header<'a>(
}, },
filename, filename,
is_root_module, is_root_module,
header_type: HeaderType::Hosted { opt_shorthand,
generates: header.generates.item, packages: &[],
generates_with: unspace(arena, header.generates_with.item.items),
exposes: unspace(arena, header.exposes.item.items), exposes: unspace(arena, header.exposes.item.items),
imports: unspace(arena, header.imports.item.items), imports: unspace(arena, header.imports.item.items),
extra: HeaderFor::Hosted {
generates: header.generates.item,
generates_with: unspace(arena, header.generates_with.item.items),
}, },
}; };
@ -3827,8 +3834,7 @@ fn parse_header<'a>(
}, },
filename, filename,
is_root_module, is_root_module,
header_type: HeaderType::App { opt_shorthand,
to_platform: header.provides.to.value,
packages, packages,
exposes, exposes,
imports: if let Some(imports) = header.imports { imports: if let Some(imports) = header.imports {
@ -3836,6 +3842,8 @@ fn parse_header<'a>(
} else { } else {
&[] &[]
}, },
extra: HeaderFor::App {
to_platform: header.provides.to.value,
}, },
}; };
@ -4069,6 +4077,18 @@ fn load_from_str<'a>(
) )
} }
#[derive(Debug)]
struct HeaderInfo<'a> {
loc_name: Loc<ModuleNameEnum<'a>>,
filename: PathBuf,
is_root_module: bool,
opt_shorthand: Option<&'a str>,
packages: &'a [Loc<PackageEntry<'a>>],
exposes: &'a [Loc<ExposedName<'a>>],
imports: &'a [Loc<ImportsEntry<'a>>],
extra: HeaderFor<'a>,
}
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
fn build_header<'a>( fn build_header<'a>(
info: HeaderInfo<'a>, info: HeaderInfo<'a>,
@ -4083,7 +4103,11 @@ fn build_header<'a>(
loc_name, loc_name,
filename, filename,
is_root_module, is_root_module,
header_type: extra, opt_shorthand,
packages,
exposes,
imports,
extra,
} = info; } = info;
let declared_name: ModuleName = match &loc_name.value { let declared_name: ModuleName = match &loc_name.value {
@ -4247,7 +4271,7 @@ fn build_header<'a>(
// and we just have a bunch of definitions with runtime errors in their bodies // and we just have a bunch of definitions with runtime errors in their bodies
let extra = { let extra = {
match extra { match extra {
HeaderType::Interface if home.is_builtin() => HeaderType::Builtin { HeaderFor::Interface if home.is_builtin() => HeaderFor::Builtin {
generates_with: &[], generates_with: &[],
}, },
_ => extra, _ => extra,
@ -4271,35 +4295,44 @@ fn build_header<'a>(
parse_state, parse_state,
exposed_imports: scope, exposed_imports: scope,
symbols_from_requires: Vec::new(), symbols_from_requires: Vec::new(),
header_type: extra, header_for: extra,
module_timing, module_timing,
}, },
) )
} }
#[derive(Debug)] #[derive(Debug)]
struct HeaderInfo<'a> { struct PlatformHeaderInfo<'a> {
loc_name: Loc<ModuleNameEnum<'a>>,
filename: PathBuf, filename: PathBuf,
is_root_module: bool, is_root_module: bool,
header_type: HeaderType<'a>, opt_shorthand: Option<&'a str>,
opt_app_module_id: Option<ModuleId>,
packages: &'a [Loc<PackageEntry<'a>>],
provides: &'a [Loc<ExposedName<'a>>],
requires: &'a [Loc<TypedIdent<'a>>],
requires_types: &'a [Loc<UppercaseIdent<'a>>],
imports: &'a [Loc<ImportsEntry<'a>>],
} }
// TODO refactor so more logic is shared with `send_header`
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
fn send_package_header<'a>( fn send_platform_header<'a>(
info: HeaderInfo<'a>, info: PlatformHeaderInfo<'a>,
parse_state: roc_parse::state::State<'a>, parse_state: roc_parse::state::State<'a>,
module_ids: &Arc<Mutex<PackageModuleIds<'a>>>, module_ids: &Arc<Mutex<PackageModuleIds<'a>>>,
ident_ids_by_module: &SharedIdentIdsByModule, ident_ids_by_module: &SharedIdentIdsByModule,
module_timing: ModuleTiming, module_timing: ModuleTiming,
) -> (ModuleId, Msg<'a>) { ) -> (ModuleId, Msg<'a>) {
let HeaderInfo { let PlatformHeaderInfo {
filename, filename,
opt_shorthand, opt_shorthand,
is_root_module, is_root_module,
opt_app_module_id, opt_app_module_id,
packages, packages,
package_type, provides,
requires,
requires_types,
imports,
} = info; } = info;
let declared_name: ModuleName = "".into(); let declared_name: ModuleName = "".into();
@ -4314,8 +4347,8 @@ fn send_package_header<'a>(
HashMap::with_capacity_and_hasher(num_exposes, default_hasher()); HashMap::with_capacity_and_hasher(num_exposes, default_hasher());
// Add standard imports, if there is an app module. // Add standard imports, if there is an app module.
// (There might not be, e.g. when running `roc check mypackage.roc` or // (There might not be, e.g. when running `roc check myplatform.roc` or
// when generating glue.) // when generating bindings.)
if let Some(app_module_id) = opt_app_module_id { if let Some(app_module_id) = opt_app_module_id {
imported_modules.insert(app_module_id, Region::zero()); imported_modules.insert(app_module_id, Region::zero());
deps_by_name.insert( deps_by_name.insert(
@ -4489,9 +4522,9 @@ fn send_package_header<'a>(
Symbol::new(home, ident_id) Symbol::new(home, ident_id)
}; };
let extra = HeaderType::Platform { let extra = HeaderFor::Platform {
// A config_shorthand of "" should be fine // A config_shorthand of "" should be fine
shorthand: opt_shorthand.unwrap_or_default(), config_shorthand: opt_shorthand.unwrap_or_default(),
platform_main_type: requires[0].value, platform_main_type: requires[0].value,
main_for_host, main_for_host,
}; };
@ -4527,7 +4560,7 @@ fn send_package_header<'a>(
exposed_imports: scope, exposed_imports: scope,
module_timing, module_timing,
symbols_from_requires, symbols_from_requires,
header_type: extra, header_for: extra,
}), }),
) )
} }
@ -4977,11 +5010,11 @@ fn fabricate_platform_module<'a>(
header: &PlatformHeader<'a>, header: &PlatformHeader<'a>,
module_timing: ModuleTiming, module_timing: ModuleTiming,
) -> (ModuleId, Msg<'a>) { ) -> (ModuleId, Msg<'a>) {
// If we have an app module, then that app module is the root module; // If we have an app module, then it's the root module;
// otherwise, we must be the root. // otherwise, we must be the root.
let is_root_module = opt_app_module_id.is_none(); let is_root_module = opt_app_module_id.is_none();
let info = PackageHeaderInfo { let info = PlatformHeaderInfo {
filename, filename,
is_root_module, is_root_module,
opt_shorthand, opt_shorthand,
@ -4996,7 +5029,7 @@ fn fabricate_platform_module<'a>(
imports: unspace(arena, header.imports.item.items), imports: unspace(arena, header.imports.item.items),
}; };
send_package_header( send_platform_header(
info, info,
parse_state, parse_state,
module_ids, module_ids,
@ -5022,7 +5055,7 @@ fn canonicalize_and_constrain<'a>(
let ParsedModule { let ParsedModule {
module_id, module_id,
module_name, module_name,
header_type: header_for, header_for,
exposed_ident_ids, exposed_ident_ids,
parsed_defs, parsed_defs,
exposed_imports, exposed_imports,
@ -5216,7 +5249,7 @@ fn parse<'a>(arena: &'a Bump, header: ModuleHeader<'a>) -> Result<Msg<'a>, Loadi
exposed_ident_ids, exposed_ident_ids,
exposed_imports, exposed_imports,
module_path, module_path,
header_type: header_for, header_for,
symbols_from_requires, symbols_from_requires,
.. ..
} = header; } = header;
@ -5233,7 +5266,7 @@ fn parse<'a>(arena: &'a Bump, header: ModuleHeader<'a>) -> Result<Msg<'a>, Loadi
exposed_imports, exposed_imports,
parsed_defs, parsed_defs,
symbols_from_requires, symbols_from_requires,
header_type: header_for, header_for,
}; };
Ok(Msg::Parsed(parsed)) Ok(Msg::Parsed(parsed))

View file

@ -8,50 +8,30 @@ use roc_module::symbol::Symbol;
use roc_region::all::Loc; use roc_region::all::Loc;
use std::fmt::Debug; use std::fmt::Debug;
/// Extra information in HeaderInfo that's specific to the type of module header we've parsed
#[derive(Debug)] #[derive(Debug)]
pub enum HeaderType<'a> { pub enum HeaderFor<'a> {
App { App {
packages: &'a [Loc<PackageEntry<'a>>],
exposes: &'a [Loc<ExposedName<'a>>],
imports: &'a [Loc<ImportsEntry<'a>>],
to_platform: To<'a>, to_platform: To<'a>,
}, },
Hosted { Hosted {
exposes: &'a [Loc<ExposedName<'a>>],
imports: &'a [Loc<ImportsEntry<'a>>],
generates: UppercaseIdent<'a>, generates: UppercaseIdent<'a>,
generates_with: &'a [Loc<ExposedName<'a>>], generates_with: &'a [Loc<ExposedName<'a>>],
}, },
/// Only created during canonicalization, never actually parsed from source /// Only created during canonicalization, never actually parsed from source
Builtin { generates_with: &'a [Symbol] }, Builtin {
generates_with: &'a [Symbol],
},
Platform { Platform {
/// usually `pf` - this is not actually something we parse out of the file. /// usually `pf`
shorthand: &'a str, config_shorthand: &'a str,
/// the type scheme of the main function (required by the platform) /// the type scheme of the main function (required by the platform)
/// (currently unused) /// (currently unused)
#[allow(dead_code)] #[allow(dead_code)]
platform_main_type: TypedIdent<'a>, platform_main_type: TypedIdent<'a>,
/// provided symbol to host (commonly `mainForHost`) /// provided symbol to host (commonly `mainForHost`)
main_for_host: Symbol, main_for_host: roc_module::symbol::Symbol,
packages: &'a [Loc<PackageEntry<'a>>],
provides: &'a [Loc<ExposedName<'a>>],
requires: &'a [Loc<TypedIdent<'a>>],
requires_types: &'a [Loc<UppercaseIdent<'a>>],
imports: &'a [Loc<ImportsEntry<'a>>],
},
Interface {
exposes: &'a [Loc<ExposedName<'a>>],
imports: &'a [Loc<ImportsEntry<'a>>],
},
Package {
/// usually not `pf` since that's what the platform typically uses
shorthand: &'a str,
packages: &'a [Loc<PackageEntry<'a>>],
/// The modules this package exposes
exposes: &'a [Loc<UppercaseIdent<'a>>],
}, },
Interface,
} }
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]