mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 16:44:33 +00:00
Merge pull request #743 from rtfeldman/parse-pkg-imports
Parse package-qualified imports
This commit is contained in:
commit
59ca5282ed
5 changed files with 38 additions and 19 deletions
|
@ -175,7 +175,7 @@ fn fmt_imports_entry<'a>(buf: &mut String<'a>, entry: &'a ImportsEntry<'a>, inde
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Package(_name, _entries) => {
|
Package(_pkg, _name, _entries) => {
|
||||||
todo!("TODO Format imported package");
|
todo!("TODO Format imported package");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2796,7 +2796,7 @@ fn exposed_from_import(entry: &ImportsEntry<'_>) -> (ModuleName, Vec<Ident>) {
|
||||||
(module_name.as_str().into(), exposed)
|
(module_name.as_str().into(), exposed)
|
||||||
}
|
}
|
||||||
|
|
||||||
Package(_package_name, _exposes) => {
|
Package(_package_name, _module_name, _exposes) => {
|
||||||
todo!("TODO support exposing package-qualified module names.");
|
todo!("TODO support exposing package-qualified module names.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -177,7 +177,11 @@ pub enum ImportsEntry<'a> {
|
||||||
Module(ModuleName<'a>, Vec<'a, Loc<ExposesEntry<'a, &'a str>>>),
|
Module(ModuleName<'a>, Vec<'a, Loc<ExposesEntry<'a, &'a str>>>),
|
||||||
|
|
||||||
/// e.g. `base.Task` or `base.Task.{ after }` or `base.{ Task.{ Task, after } }`
|
/// e.g. `base.Task` or `base.Task.{ after }` or `base.{ Task.{ Task, after } }`
|
||||||
Package(&'a str, Vec<'a, Loc<&'a ImportsEntry<'a>>>),
|
Package(
|
||||||
|
&'a str,
|
||||||
|
ModuleName<'a>,
|
||||||
|
Vec<'a, Loc<ExposesEntry<'a, &'a str>>>,
|
||||||
|
),
|
||||||
|
|
||||||
// Spaces
|
// Spaces
|
||||||
SpaceBefore(&'a ImportsEntry<'a>, &'a [CommentOrNewline<'a>]),
|
SpaceBefore(&'a ImportsEntry<'a>, &'a [CommentOrNewline<'a>]),
|
||||||
|
|
|
@ -544,11 +544,16 @@ fn typed_ident<'a>() -> impl Parser<'a, TypedIdent<'a>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
#[allow(clippy::type_complexity)]
|
||||||
fn imports_entry<'a>() -> impl Parser<'a, ImportsEntry<'a>> {
|
fn imports_entry<'a>() -> impl Parser<'a, ImportsEntry<'a>> {
|
||||||
map_with_arena!(
|
map_with_arena!(
|
||||||
and!(
|
and!(
|
||||||
// e.g. `Task`
|
and!(
|
||||||
module_name(),
|
// e.g. `base.`
|
||||||
|
optional(skip_second!(lowercase_ident(), ascii_char(b'.'))),
|
||||||
|
// e.g. `Task`
|
||||||
|
module_name()
|
||||||
|
),
|
||||||
// e.g. `.{ Task, after}`
|
// e.g. `.{ Task, after}`
|
||||||
optional(skip_first!(
|
optional(skip_first!(
|
||||||
ascii_char(b'.'),
|
ascii_char(b'.'),
|
||||||
|
@ -562,13 +567,17 @@ fn imports_entry<'a>() -> impl Parser<'a, ImportsEntry<'a>> {
|
||||||
))
|
))
|
||||||
),
|
),
|
||||||
|arena,
|
|arena,
|
||||||
(module_name, opt_values): (
|
((opt_shortname, module_name), opt_values): (
|
||||||
ModuleName<'a>,
|
(Option<&'a str>, ModuleName<'a>),
|
||||||
Option<Vec<'a, Located<ExposesEntry<'a, &'a str>>>>
|
Option<Vec<'a, Located<ExposesEntry<'a, &'a str>>>>
|
||||||
)| {
|
)| {
|
||||||
let exposed_values = opt_values.unwrap_or_else(|| Vec::new_in(arena));
|
let exposed_values = opt_values.unwrap_or_else(|| Vec::new_in(arena));
|
||||||
|
|
||||||
ImportsEntry::Module(module_name, exposed_values)
|
match opt_shortname {
|
||||||
|
Some(shortname) => ImportsEntry::Package(shortname, module_name, exposed_values),
|
||||||
|
|
||||||
|
None => ImportsEntry::Module(module_name, exposed_values),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,8 +27,8 @@ mod test_parse {
|
||||||
self, Attempting, Def, EscapedChar, Spaceable, TypeAnnotation, WhenBranch,
|
self, Attempting, Def, EscapedChar, Spaceable, TypeAnnotation, WhenBranch,
|
||||||
};
|
};
|
||||||
use roc_parse::header::{
|
use roc_parse::header::{
|
||||||
AppHeader, Effects, ExposesEntry, InterfaceHeader, ModuleName, PackageEntry, PackageName,
|
AppHeader, Effects, ExposesEntry, ImportsEntry, InterfaceHeader, ModuleName, PackageEntry,
|
||||||
PackageOrPath, PlatformHeader, To,
|
PackageName, PackageOrPath, PlatformHeader, To,
|
||||||
};
|
};
|
||||||
use roc_parse::module::{app_header, interface_header, module_defs, platform_header};
|
use roc_parse::module::{app_header, interface_header, module_defs, platform_header};
|
||||||
use roc_parse::parser::{Fail, FailReason, Parser, State};
|
use roc_parse::parser::{Fail, FailReason, Parser, State};
|
||||||
|
@ -2358,16 +2358,19 @@ mod test_parse {
|
||||||
use ExposesEntry::Exposed;
|
use ExposesEntry::Exposed;
|
||||||
use PackageOrPath::Path;
|
use PackageOrPath::Path;
|
||||||
|
|
||||||
|
let newlines = &[Newline];
|
||||||
let pkg_entry = PackageEntry::Entry {
|
let pkg_entry = PackageEntry::Entry {
|
||||||
shorthand: "base",
|
shorthand: "base",
|
||||||
spaces_after_shorthand: &[],
|
spaces_after_shorthand: &[],
|
||||||
package_or_path: Located::new(0, 0, 33, 45, Path(PlainLine("./platform"))),
|
package_or_path: Located::new(1, 1, 21, 33, Path(PlainLine("./platform"))),
|
||||||
};
|
};
|
||||||
let loc_pkg_entry = Located::new(0, 0, 27, 45, pkg_entry);
|
let loc_pkg_entry = Located::new(1, 1, 15, 33, pkg_entry);
|
||||||
let arena = Bump::new();
|
let arena = Bump::new();
|
||||||
let packages = bumpalo::vec![in &arena; loc_pkg_entry];
|
let packages = bumpalo::vec![in &arena; loc_pkg_entry];
|
||||||
let imports = Vec::new_in(&arena);
|
let import = ImportsEntry::Package("foo", ModuleName::new("Bar.Baz"), Vec::new_in(&arena));
|
||||||
let provide_entry = Located::new(0, 0, 59, 68, Exposed("quicksort"));
|
let loc_import = Located::new(2, 2, 14, 25, import);
|
||||||
|
let imports = bumpalo::vec![in &arena; loc_import];
|
||||||
|
let provide_entry = Located::new(3, 3, 15, 24, Exposed("quicksort"));
|
||||||
let provides = bumpalo::vec![in &arena; provide_entry];
|
let provides = bumpalo::vec![in &arena; provide_entry];
|
||||||
let module_name = StrLiteral::PlainLine("quicksort");
|
let module_name = StrLiteral::PlainLine("quicksort");
|
||||||
let expected = AppHeader {
|
let expected = AppHeader {
|
||||||
|
@ -2375,13 +2378,13 @@ mod test_parse {
|
||||||
packages,
|
packages,
|
||||||
imports,
|
imports,
|
||||||
provides,
|
provides,
|
||||||
to: Located::new(0, 0, 74, 78, To::ExistingPackage("base")),
|
to: Located::new(3, 3, 30, 34, To::ExistingPackage("base")),
|
||||||
after_app_keyword: &[],
|
after_app_keyword: &[],
|
||||||
before_packages: &[],
|
before_packages: newlines,
|
||||||
after_packages: &[],
|
after_packages: &[],
|
||||||
before_imports: &[],
|
before_imports: newlines,
|
||||||
after_imports: &[],
|
after_imports: &[],
|
||||||
before_provides: &[],
|
before_provides: newlines,
|
||||||
after_provides: &[],
|
after_provides: &[],
|
||||||
before_to: &[],
|
before_to: &[],
|
||||||
after_to: &[],
|
after_to: &[],
|
||||||
|
@ -2389,7 +2392,10 @@ mod test_parse {
|
||||||
|
|
||||||
let src = indoc!(
|
let src = indoc!(
|
||||||
r#"
|
r#"
|
||||||
app "quicksort" packages { base: "./platform" } provides [ quicksort ] to base
|
app "quicksort"
|
||||||
|
packages { base: "./platform" }
|
||||||
|
imports [ foo.Bar.Baz ]
|
||||||
|
provides [ quicksort ] to base
|
||||||
"#
|
"#
|
||||||
);
|
);
|
||||||
let actual = app_header()
|
let actual = app_header()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue