Merge pull request #743 from rtfeldman/parse-pkg-imports

Parse package-qualified imports
This commit is contained in:
Richard Feldman 2020-11-26 22:09:17 -05:00 committed by GitHub
commit 59ca5282ed
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 38 additions and 19 deletions

View file

@ -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");
}

View file

@ -2796,7 +2796,7 @@ fn exposed_from_import(entry: &ImportsEntry<'_>) -> (ModuleName, Vec<Ident>) {
(module_name.as_str().into(), exposed)
}
Package(_package_name, _exposes) => {
Package(_package_name, _module_name, _exposes) => {
todo!("TODO support exposing package-qualified module names.");
}

View file

@ -177,7 +177,11 @@ pub enum ImportsEntry<'a> {
Module(ModuleName<'a>, Vec<'a, Loc<ExposesEntry<'a, &'a str>>>),
/// 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
SpaceBefore(&'a ImportsEntry<'a>, &'a [CommentOrNewline<'a>]),

View file

@ -544,11 +544,16 @@ fn typed_ident<'a>() -> impl Parser<'a, TypedIdent<'a>> {
}
#[inline(always)]
#[allow(clippy::type_complexity)]
fn imports_entry<'a>() -> impl Parser<'a, ImportsEntry<'a>> {
map_with_arena!(
and!(
// e.g. `Task`
module_name(),
and!(
// e.g. `base.`
optional(skip_second!(lowercase_ident(), ascii_char(b'.'))),
// e.g. `Task`
module_name()
),
// e.g. `.{ Task, after}`
optional(skip_first!(
ascii_char(b'.'),
@ -562,13 +567,17 @@ fn imports_entry<'a>() -> impl Parser<'a, ImportsEntry<'a>> {
))
),
|arena,
(module_name, opt_values): (
ModuleName<'a>,
((opt_shortname, module_name), opt_values): (
(Option<&'a str>, ModuleName<'a>),
Option<Vec<'a, Located<ExposesEntry<'a, &'a str>>>>
)| {
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),
}
}
)
}

View file

@ -27,8 +27,8 @@ mod test_parse {
self, Attempting, Def, EscapedChar, Spaceable, TypeAnnotation, WhenBranch,
};
use roc_parse::header::{
AppHeader, Effects, ExposesEntry, InterfaceHeader, ModuleName, PackageEntry, PackageName,
PackageOrPath, PlatformHeader, To,
AppHeader, Effects, ExposesEntry, ImportsEntry, InterfaceHeader, ModuleName, PackageEntry,
PackageName, PackageOrPath, PlatformHeader, To,
};
use roc_parse::module::{app_header, interface_header, module_defs, platform_header};
use roc_parse::parser::{Fail, FailReason, Parser, State};
@ -2358,16 +2358,19 @@ mod test_parse {
use ExposesEntry::Exposed;
use PackageOrPath::Path;
let newlines = &[Newline];
let pkg_entry = PackageEntry::Entry {
shorthand: "base",
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 packages = bumpalo::vec![in &arena; loc_pkg_entry];
let imports = Vec::new_in(&arena);
let provide_entry = Located::new(0, 0, 59, 68, Exposed("quicksort"));
let import = ImportsEntry::Package("foo", ModuleName::new("Bar.Baz"), Vec::new_in(&arena));
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 module_name = StrLiteral::PlainLine("quicksort");
let expected = AppHeader {
@ -2375,13 +2378,13 @@ mod test_parse {
packages,
imports,
provides,
to: Located::new(0, 0, 74, 78, To::ExistingPackage("base")),
to: Located::new(3, 3, 30, 34, To::ExistingPackage("base")),
after_app_keyword: &[],
before_packages: &[],
before_packages: newlines,
after_packages: &[],
before_imports: &[],
before_imports: newlines,
after_imports: &[],
before_provides: &[],
before_provides: newlines,
after_provides: &[],
before_to: &[],
after_to: &[],
@ -2389,7 +2392,10 @@ mod test_parse {
let src = indoc!(
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()