mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 14:54:47 +00:00
Parse app header provided types
This commit is contained in:
parent
c1c0ffb25f
commit
01942fd98e
6 changed files with 61 additions and 15 deletions
|
@ -7,8 +7,8 @@ use crate::header::{
|
|||
use crate::ident::{self, lowercase_ident, unqualified_ident, uppercase_ident, UppercaseIdent};
|
||||
use crate::parser::Progress::{self, *};
|
||||
use crate::parser::{
|
||||
backtrackable, specialize, specialize_region, word1, EEffects, EExposes, EHeader, EImports,
|
||||
EPackages, EProvides, ERequires, ETypedIdent, Parser, SourceError, SyntaxError,
|
||||
backtrackable, optional, specialize, specialize_region, word1, EEffects, EExposes, EHeader,
|
||||
EImports, EPackages, EProvides, ERequires, ETypedIdent, Parser, SourceError, SyntaxError,
|
||||
};
|
||||
use crate::state::State;
|
||||
use crate::string_literal;
|
||||
|
@ -227,6 +227,7 @@ fn app_header<'a>() -> impl Parser<'a, AppHeader<'a>, EHeader<'a>> {
|
|||
packages,
|
||||
imports,
|
||||
provides: provides.entries,
|
||||
provides_types: provides.types,
|
||||
to: provides.to,
|
||||
before_header: &[] as &[_],
|
||||
after_app_keyword,
|
||||
|
@ -265,7 +266,7 @@ fn platform_header<'a>() -> impl Parser<'a, PlatformHeader<'a>, EHeader<'a>> {
|
|||
let (_, ((before_imports, after_imports), imports), state) =
|
||||
specialize(EHeader::Imports, imports()).parse(arena, state)?;
|
||||
|
||||
let (_, ((before_provides, after_provides), provides), state) =
|
||||
let (_, ((before_provides, after_provides), (provides, _provides_type)), state) =
|
||||
specialize(EHeader::Provides, provides_without_to()).parse(arena, state)?;
|
||||
|
||||
let (_, effects, state) = specialize(EHeader::Effects, effects()).parse(arena, state)?;
|
||||
|
@ -299,6 +300,7 @@ fn platform_header<'a>() -> impl Parser<'a, PlatformHeader<'a>, EHeader<'a>> {
|
|||
#[derive(Debug)]
|
||||
struct ProvidesTo<'a> {
|
||||
entries: Collection<'a, Loc<Spaced<'a, ExposedName<'a>>>>,
|
||||
types: Option<Collection<'a, Loc<Spaced<'a, UppercaseIdent<'a>>>>>,
|
||||
to: Loc<To<'a>>,
|
||||
|
||||
before_provides_keyword: &'a [CommentOrNewline<'a>],
|
||||
|
@ -337,11 +339,12 @@ fn provides_to<'a>() -> impl Parser<'a, ProvidesTo<'a>, EProvides<'a>> {
|
|||
)
|
||||
),
|
||||
|(
|
||||
((before_provides_keyword, after_provides_keyword), entries),
|
||||
((before_provides_keyword, after_provides_keyword), (entries, provides_types)),
|
||||
((before_to_keyword, after_to_keyword), to),
|
||||
)| {
|
||||
ProvidesTo {
|
||||
entries,
|
||||
types: provides_types,
|
||||
to,
|
||||
before_provides_keyword,
|
||||
after_provides_keyword,
|
||||
|
@ -357,7 +360,10 @@ fn provides_without_to<'a>() -> impl Parser<
|
|||
'a,
|
||||
(
|
||||
(&'a [CommentOrNewline<'a>], &'a [CommentOrNewline<'a>]),
|
||||
Collection<'a, Loc<Spaced<'a, ExposedName<'a>>>>,
|
||||
(
|
||||
Collection<'a, Loc<Spaced<'a, ExposedName<'a>>>>,
|
||||
Option<Collection<'a, Loc<Spaced<'a, UppercaseIdent<'a>>>>>,
|
||||
),
|
||||
),
|
||||
EProvides<'a>,
|
||||
> {
|
||||
|
@ -371,20 +377,55 @@ fn provides_without_to<'a>() -> impl Parser<
|
|||
EProvides::IndentProvides,
|
||||
EProvides::IndentListStart
|
||||
),
|
||||
collection_trailing_sep_e!(
|
||||
word1(b'[', EProvides::ListStart),
|
||||
exposes_entry(EProvides::Identifier),
|
||||
word1(b',', EProvides::ListEnd),
|
||||
word1(b']', EProvides::ListEnd),
|
||||
min_indent,
|
||||
EProvides::Open,
|
||||
EProvides::Space,
|
||||
EProvides::IndentListEnd,
|
||||
Spaced::SpaceBefore
|
||||
and!(
|
||||
collection_trailing_sep_e!(
|
||||
word1(b'[', EProvides::ListStart),
|
||||
exposes_entry(EProvides::Identifier),
|
||||
word1(b',', EProvides::ListEnd),
|
||||
word1(b']', EProvides::ListEnd),
|
||||
min_indent,
|
||||
EProvides::Open,
|
||||
EProvides::Space,
|
||||
EProvides::IndentListEnd,
|
||||
Spaced::SpaceBefore
|
||||
),
|
||||
// Optionally
|
||||
optional(provides_types())
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn provides_types<'a>(
|
||||
) -> impl Parser<'a, Collection<'a, Loc<Spaced<'a, UppercaseIdent<'a>>>>, EProvides<'a>> {
|
||||
let min_indent = 1;
|
||||
collection_trailing_sep_e!(
|
||||
word1(b'{', EProvides::ListStart),
|
||||
provides_type_entry(EProvides::Identifier),
|
||||
word1(b',', EProvides::ListEnd),
|
||||
word1(b'}', EProvides::ListEnd),
|
||||
min_indent,
|
||||
EProvides::Open,
|
||||
EProvides::Space,
|
||||
EProvides::IndentListEnd,
|
||||
Spaced::SpaceBefore
|
||||
)
|
||||
}
|
||||
|
||||
fn provides_type_entry<'a, F, E>(
|
||||
to_expectation: F,
|
||||
) -> impl Parser<'a, Loc<Spaced<'a, UppercaseIdent<'a>>>, E>
|
||||
where
|
||||
F: Fn(Position) -> E,
|
||||
F: Copy,
|
||||
E: 'a,
|
||||
{
|
||||
loc!(map!(
|
||||
specialize(|_, pos| to_expectation(pos), ident::uppercase()),
|
||||
Spaced::Item
|
||||
))
|
||||
}
|
||||
|
||||
fn exposes_entry<'a, F, E>(
|
||||
to_expectation: F,
|
||||
) -> impl Parser<'a, Loc<Spaced<'a, ExposedName<'a>>>, E>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue