mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 06:44:46 +00:00
Refactor: introduce trait SpaceProblem to remove a bunch of redundant args in ::Space errors
This commit is contained in:
parent
999287e958
commit
f440d53e7b
7 changed files with 117 additions and 170 deletions
|
@ -1,5 +1,6 @@
|
|||
use crate::ast::CommentOrNewline;
|
||||
use crate::ast::Spaceable;
|
||||
use crate::parser::SpaceProblem;
|
||||
use crate::parser::{self, and, backtrackable, BadInputError, Parser, Progress::*};
|
||||
use crate::state::State;
|
||||
use bumpalo::collections::vec::Vec;
|
||||
|
@ -10,7 +11,6 @@ use roc_region::all::Position;
|
|||
pub fn space0_around_ee<'a, P, S, E>(
|
||||
parser: P,
|
||||
min_indent: u32,
|
||||
space_problem: fn(BadInputError, Position) -> E,
|
||||
indent_before_problem: fn(Position) -> E,
|
||||
indent_after_problem: fn(Position) -> E,
|
||||
) -> impl Parser<'a, Loc<S>, E>
|
||||
|
@ -19,15 +19,12 @@ where
|
|||
S: 'a,
|
||||
P: Parser<'a, Loc<S>, E>,
|
||||
P: 'a,
|
||||
E: 'a,
|
||||
E: 'a + SpaceProblem,
|
||||
{
|
||||
parser::map_with_arena(
|
||||
and(
|
||||
space0_e(min_indent, space_problem, indent_before_problem),
|
||||
and(
|
||||
parser,
|
||||
space0_e(min_indent, space_problem, indent_after_problem),
|
||||
),
|
||||
space0_e(min_indent, indent_before_problem),
|
||||
and(parser, space0_e(min_indent, indent_after_problem)),
|
||||
),
|
||||
spaces_around_help,
|
||||
)
|
||||
|
@ -36,7 +33,6 @@ where
|
|||
pub fn space0_before_optional_after<'a, P, S, E>(
|
||||
parser: P,
|
||||
min_indent: u32,
|
||||
space_problem: fn(BadInputError, Position) -> E,
|
||||
indent_before_problem: fn(Position) -> E,
|
||||
indent_after_problem: fn(Position) -> E,
|
||||
) -> impl Parser<'a, Loc<S>, E>
|
||||
|
@ -45,15 +41,15 @@ where
|
|||
S: 'a,
|
||||
P: Parser<'a, Loc<S>, E>,
|
||||
P: 'a,
|
||||
E: 'a,
|
||||
E: 'a + SpaceProblem,
|
||||
{
|
||||
parser::map_with_arena(
|
||||
and(
|
||||
space0_e(min_indent, space_problem, indent_before_problem),
|
||||
space0_e(min_indent, indent_before_problem),
|
||||
and(
|
||||
parser,
|
||||
one_of![
|
||||
backtrackable(space0_e(min_indent, space_problem, indent_after_problem)),
|
||||
backtrackable(space0_e(min_indent, indent_after_problem)),
|
||||
succeed!(&[] as &[_]),
|
||||
],
|
||||
),
|
||||
|
@ -101,7 +97,6 @@ where
|
|||
pub fn space0_before_e<'a, P, S, E>(
|
||||
parser: P,
|
||||
min_indent: u32,
|
||||
space_problem: fn(BadInputError, Position) -> E,
|
||||
indent_problem: fn(Position) -> E,
|
||||
) -> impl Parser<'a, Loc<S>, E>
|
||||
where
|
||||
|
@ -109,10 +104,10 @@ where
|
|||
S: 'a,
|
||||
P: Parser<'a, Loc<S>, E>,
|
||||
P: 'a,
|
||||
E: 'a,
|
||||
E: 'a + SpaceProblem,
|
||||
{
|
||||
parser::map_with_arena(
|
||||
and!(space0_e(min_indent, space_problem, indent_problem), parser),
|
||||
and!(space0_e(min_indent, indent_problem), parser),
|
||||
|arena: &'a Bump, (space_list, loc_expr): (&'a [CommentOrNewline<'a>], Loc<S>)| {
|
||||
if space_list.is_empty() {
|
||||
loc_expr
|
||||
|
@ -128,7 +123,6 @@ where
|
|||
pub fn space0_after_e<'a, P, S, E>(
|
||||
parser: P,
|
||||
min_indent: u32,
|
||||
space_problem: fn(BadInputError, Position) -> E,
|
||||
indent_problem: fn(Position) -> E,
|
||||
) -> impl Parser<'a, Loc<S>, E>
|
||||
where
|
||||
|
@ -136,10 +130,10 @@ where
|
|||
S: 'a,
|
||||
P: Parser<'a, Loc<S>, E>,
|
||||
P: 'a,
|
||||
E: 'a,
|
||||
E: 'a + SpaceProblem,
|
||||
{
|
||||
parser::map_with_arena(
|
||||
and!(parser, space0_e(min_indent, space_problem, indent_problem)),
|
||||
and!(parser, space0_e(min_indent, indent_problem)),
|
||||
|arena: &'a Bump, (loc_expr, space_list): (Loc<S>, &'a [CommentOrNewline<'a>])| {
|
||||
if space_list.is_empty() {
|
||||
loc_expr
|
||||
|
@ -170,23 +164,21 @@ where
|
|||
|
||||
pub fn space0_e<'a, E>(
|
||||
min_indent: u32,
|
||||
space_problem: fn(BadInputError, Position) -> E,
|
||||
indent_problem: fn(Position) -> E,
|
||||
) -> impl Parser<'a, &'a [CommentOrNewline<'a>], E>
|
||||
where
|
||||
E: 'a,
|
||||
E: 'a + SpaceProblem,
|
||||
{
|
||||
spaces_help_help(min_indent, space_problem, indent_problem)
|
||||
spaces_help_help(min_indent, indent_problem)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn spaces_help_help<'a, E>(
|
||||
min_indent: u32,
|
||||
space_problem: fn(BadInputError, Position) -> E,
|
||||
indent_problem: fn(Position) -> E,
|
||||
) -> impl Parser<'a, &'a [CommentOrNewline<'a>], E>
|
||||
where
|
||||
E: 'a,
|
||||
E: 'a + SpaceProblem,
|
||||
{
|
||||
use SpaceState::*;
|
||||
|
||||
|
@ -195,7 +187,7 @@ where
|
|||
match eat_spaces(state.clone(), false, comments_and_newlines) {
|
||||
HasTab(state) => Err((
|
||||
MadeProgress,
|
||||
space_problem(BadInputError::HasTab, state.pos()),
|
||||
E::space_problem(BadInputError::HasTab, state.pos()),
|
||||
state,
|
||||
)),
|
||||
Good {
|
||||
|
|
|
@ -39,7 +39,6 @@ pub fn test_parse_expr<'a>(
|
|||
space0_before_e(
|
||||
move |a, s| parse_loc_expr(min_indent, a, s),
|
||||
min_indent,
|
||||
EExpr::Space,
|
||||
EExpr::IndentStart,
|
||||
),
|
||||
expr_end()
|
||||
|
@ -106,7 +105,6 @@ fn loc_expr_in_parens_help_help<'a>(
|
|||
min_indent, arena, state
|
||||
)),
|
||||
min_indent,
|
||||
EInParens::Space,
|
||||
EInParens::IndentOpen,
|
||||
EInParens::IndentEnd,
|
||||
),
|
||||
|
@ -340,7 +338,7 @@ fn parse_expr_operator_chain<'a>(
|
|||
let initial = state.clone();
|
||||
let end = state.pos();
|
||||
|
||||
match space0_e(min_indent, EExpr::Space, EExpr::IndentEnd).parse(arena, state) {
|
||||
match space0_e(min_indent, EExpr::IndentEnd).parse(arena, state) {
|
||||
Err((_, _, state)) => Ok((MadeProgress, expr.value, state)),
|
||||
Ok((_, spaces_before_op, state)) => {
|
||||
let expr_state = ExprState {
|
||||
|
@ -781,7 +779,7 @@ fn parse_defs_end<'a>(
|
|||
let min_indent = start_column;
|
||||
let initial = state.clone();
|
||||
|
||||
let state = match space0_e(min_indent, EExpr::Space, EExpr::IndentStart).parse(arena, state) {
|
||||
let state = match space0_e(min_indent, EExpr::IndentStart).parse(arena, state) {
|
||||
Err((MadeProgress, _, s)) => {
|
||||
return Err((MadeProgress, EExpr::DefMissingFinalExpr(s.pos()), s));
|
||||
}
|
||||
|
@ -798,7 +796,6 @@ fn parse_defs_end<'a>(
|
|||
match space0_after_e(
|
||||
crate::pattern::loc_pattern_help(min_indent),
|
||||
min_indent,
|
||||
EPattern::Space,
|
||||
EPattern::IndentEnd,
|
||||
)
|
||||
.parse(arena, state.clone())
|
||||
|
@ -815,7 +812,6 @@ fn parse_defs_end<'a>(
|
|||
let parse_def_expr = space0_before_e(
|
||||
move |a, s| parse_loc_expr(min_indent + 1, a, s),
|
||||
min_indent,
|
||||
EExpr::Space,
|
||||
EExpr::IndentEnd,
|
||||
);
|
||||
|
||||
|
@ -842,7 +838,6 @@ fn parse_defs_end<'a>(
|
|||
let parse_def_expr = space0_before_e(
|
||||
move |a, s| parse_loc_expr(min_indent + 1, a, s),
|
||||
min_indent,
|
||||
EExpr::Space,
|
||||
EExpr::IndentEnd,
|
||||
);
|
||||
|
||||
|
@ -864,7 +859,6 @@ fn parse_defs_end<'a>(
|
|||
space0_before_e(
|
||||
type_annotation::located_help(min_indent + 1, false),
|
||||
min_indent + 1,
|
||||
EType::TSpace,
|
||||
EType::TIndentStart,
|
||||
),
|
||||
)
|
||||
|
@ -902,7 +896,6 @@ fn parse_defs_expr<'a>(
|
|||
let parse_final_expr = space0_before_e(
|
||||
move |a, s| parse_loc_expr(min_indent, a, s),
|
||||
min_indent,
|
||||
EExpr::Space,
|
||||
EExpr::IndentEnd,
|
||||
);
|
||||
|
||||
|
@ -936,7 +929,7 @@ fn parse_expr_operator<'a>(
|
|||
state: State<'a>,
|
||||
) -> ParseResult<'a, Expr<'a>, EExpr<'a>> {
|
||||
let (_, spaces_after_operator, state) =
|
||||
space0_e(min_indent, EExpr::Space, EExpr::IndentEnd).parse(arena, state)?;
|
||||
space0_e(min_indent, EExpr::IndentEnd).parse(arena, state)?;
|
||||
|
||||
// a `-` is unary if it is preceded by a space and not followed by a space
|
||||
|
||||
|
@ -961,11 +954,10 @@ fn parse_expr_operator<'a>(
|
|||
|
||||
expr_state.initial = state.clone();
|
||||
|
||||
let (spaces, state) =
|
||||
match space0_e(min_indent, EExpr::Space, EExpr::IndentEnd).parse(arena, state) {
|
||||
Err((_, _, state)) => (&[] as &[_], state),
|
||||
Ok((_, spaces, state)) => (spaces, state),
|
||||
};
|
||||
let (spaces, state) = match space0_e(min_indent, EExpr::IndentEnd).parse(arena, state) {
|
||||
Err((_, _, state)) => (&[] as &[_], state),
|
||||
Ok((_, spaces, state)) => (spaces, state),
|
||||
};
|
||||
|
||||
expr_state.arguments.push(arena.alloc(arg));
|
||||
expr_state.spaces_after = spaces;
|
||||
|
@ -1054,7 +1046,6 @@ fn parse_expr_operator<'a>(
|
|||
let parse_cont = space0_before_e(
|
||||
move |a, s| parse_loc_expr(min_indent, a, s),
|
||||
min_indent,
|
||||
EExpr::Space,
|
||||
EExpr::IndentEnd,
|
||||
);
|
||||
|
||||
|
@ -1094,7 +1085,6 @@ fn parse_expr_operator<'a>(
|
|||
space0_before_e(
|
||||
type_annotation::located_help(indented_more, true),
|
||||
min_indent,
|
||||
EType::TSpace,
|
||||
EType::TIndentStart,
|
||||
),
|
||||
)
|
||||
|
@ -1123,7 +1113,6 @@ fn parse_expr_operator<'a>(
|
|||
space0_before_e(
|
||||
type_annotation::located_help(indented_more, false),
|
||||
min_indent,
|
||||
EType::TSpace,
|
||||
EType::TIndentStart,
|
||||
),
|
||||
);
|
||||
|
@ -1180,7 +1169,7 @@ fn parse_expr_operator<'a>(
|
|||
.with_spaces_before(spaces_after_operator, new_expr.region);
|
||||
}
|
||||
|
||||
match space0_e(min_indent, EExpr::Space, EExpr::IndentEnd).parse(arena, state) {
|
||||
match space0_e(min_indent, EExpr::IndentEnd).parse(arena, state) {
|
||||
Err((_, _, state)) => {
|
||||
let args = std::mem::replace(&mut expr_state.arguments, Vec::new_in(arena));
|
||||
|
||||
|
@ -1243,7 +1232,7 @@ fn parse_expr_end<'a>(
|
|||
}
|
||||
expr_state.initial = state.clone();
|
||||
|
||||
match space0_e(min_indent, EExpr::Space, EExpr::IndentEnd).parse(arena, state) {
|
||||
match space0_e(min_indent, EExpr::IndentEnd).parse(arena, state) {
|
||||
Err((_, _, state)) => {
|
||||
expr_state.arguments.push(arena.alloc(arg));
|
||||
expr_state.end = new_end;
|
||||
|
@ -1290,7 +1279,6 @@ fn parse_expr_end<'a>(
|
|||
space0_around_ee(
|
||||
crate::pattern::loc_pattern_help(min_indent),
|
||||
min_indent,
|
||||
EPattern::Space,
|
||||
EPattern::Start,
|
||||
EPattern::IndentEnd,
|
||||
),
|
||||
|
@ -1316,7 +1304,6 @@ fn parse_expr_end<'a>(
|
|||
let parse_body = space0_before_e(
|
||||
move |a, s| parse_loc_expr(min_indent + 1, a, s),
|
||||
min_indent,
|
||||
EExpr::Space,
|
||||
EExpr::IndentEnd,
|
||||
);
|
||||
|
||||
|
@ -1325,7 +1312,6 @@ fn parse_expr_end<'a>(
|
|||
let parse_cont = space0_before_e(
|
||||
move |a, s| parse_loc_expr(min_indent, a, s),
|
||||
min_indent,
|
||||
EExpr::Space,
|
||||
EExpr::IndentEnd,
|
||||
);
|
||||
|
||||
|
@ -1538,7 +1524,7 @@ pub fn defs<'a>(min_indent: u32) -> impl Parser<'a, Vec<'a, Loc<Def<'a>>>, EExpr
|
|||
};
|
||||
|
||||
let (_, initial_space, state) =
|
||||
space0_e(min_indent, EExpr::Space, EExpr::IndentEnd).parse(arena, state)?;
|
||||
space0_e(min_indent, EExpr::IndentEnd).parse(arena, state)?;
|
||||
|
||||
let start_column = state.column();
|
||||
|
||||
|
@ -1550,7 +1536,7 @@ pub fn defs<'a>(min_indent: u32) -> impl Parser<'a, Vec<'a, Loc<Def<'a>>>, EExpr
|
|||
let (_, def_state, state) = parse_defs_end(options, start_column, def_state, arena, state)?;
|
||||
|
||||
let (_, final_space, state) =
|
||||
space0_e(start_column, EExpr::Space, EExpr::IndentEnd).parse(arena, state)?;
|
||||
space0_e(start_column, EExpr::IndentEnd).parse(arena, state)?;
|
||||
|
||||
let mut output = Vec::with_capacity_in(def_state.defs.len(), arena);
|
||||
|
||||
|
@ -1601,7 +1587,6 @@ fn closure_help<'a>(
|
|||
space0_around_ee(
|
||||
specialize(ELambda::Pattern, loc_closure_param(min_indent)),
|
||||
min_indent,
|
||||
ELambda::Space,
|
||||
ELambda::IndentArg,
|
||||
ELambda::IndentArrow
|
||||
),
|
||||
|
@ -1616,7 +1601,6 @@ fn closure_help<'a>(
|
|||
parse_loc_expr_with_options(min_indent, options, arena, state)
|
||||
}),
|
||||
min_indent,
|
||||
ELambda::Space,
|
||||
ELambda::IndentBody
|
||||
)
|
||||
)
|
||||
|
@ -1649,7 +1633,6 @@ mod when {
|
|||
parse_loc_expr_with_options(min_indent, options, arena, state)
|
||||
}),
|
||||
min_indent,
|
||||
EWhen::Space,
|
||||
EWhen::IndentCondition,
|
||||
EWhen::IndentIs,
|
||||
),
|
||||
|
@ -1797,7 +1780,6 @@ mod when {
|
|||
parse_loc_expr_with_options(min_indent + 1, options, arena, state)
|
||||
}),
|
||||
min_indent,
|
||||
EWhen::Space,
|
||||
EWhen::IndentIfGuard,
|
||||
EWhen::IndentArrow,
|
||||
)
|
||||
|
@ -1814,13 +1796,11 @@ mod when {
|
|||
) -> impl Parser<'a, Loc<Pattern<'a>>, EWhen<'a>> {
|
||||
move |arena, state| {
|
||||
let (_, spaces, state) =
|
||||
backtrackable(space0_e(min_indent, EWhen::Space, EWhen::IndentPattern))
|
||||
.parse(arena, state)?;
|
||||
backtrackable(space0_e(min_indent, EWhen::IndentPattern)).parse(arena, state)?;
|
||||
|
||||
let (_, loc_pattern, state) = space0_after_e(
|
||||
specialize(EWhen::Pattern, crate::pattern::loc_pattern_help(min_indent)),
|
||||
min_indent,
|
||||
EWhen::Space,
|
||||
EWhen::IndentPattern,
|
||||
)
|
||||
.parse(arena, state)?;
|
||||
|
@ -1847,7 +1827,7 @@ mod when {
|
|||
let initial = state.clone();
|
||||
|
||||
// put no restrictions on the indent after the spaces; we'll check it manually
|
||||
match space0_e(0, EWhen::Space, EWhen::IndentPattern).parse(arena, state) {
|
||||
match space0_e(0, EWhen::IndentPattern).parse(arena, state) {
|
||||
Err((MadeProgress, fail, _)) => Err((NoProgress, fail, initial)),
|
||||
Err((NoProgress, fail, _)) => Err((NoProgress, fail, initial)),
|
||||
Ok((_progress, spaces, state)) => {
|
||||
|
@ -1914,7 +1894,6 @@ mod when {
|
|||
indent, arena, state
|
||||
)),
|
||||
indent,
|
||||
EWhen::Space,
|
||||
EWhen::IndentBranch,
|
||||
)
|
||||
)
|
||||
|
@ -1929,7 +1908,6 @@ fn if_branch<'a>(min_indent: u32) -> impl Parser<'a, (Loc<Expr<'a>>, Loc<Expr<'a
|
|||
parse_loc_expr(min_indent, arena, state)
|
||||
}),
|
||||
min_indent,
|
||||
EIf::Space,
|
||||
EIf::IndentCondition,
|
||||
EIf::IndentThenToken,
|
||||
)
|
||||
|
@ -1945,7 +1923,6 @@ fn if_branch<'a>(min_indent: u32) -> impl Parser<'a, (Loc<Expr<'a>>, Loc<Expr<'a
|
|||
parse_loc_expr(min_indent, arena, state)
|
||||
}),
|
||||
min_indent,
|
||||
EIf::Space,
|
||||
EIf::IndentThenBranch,
|
||||
EIf::IndentElseToken,
|
||||
)
|
||||
|
@ -1975,7 +1952,6 @@ fn expect_help<'a>(
|
|||
parse_loc_expr_with_options(start_column + 1, options, arena, state)
|
||||
}),
|
||||
start_column + 1,
|
||||
EExpect::Space,
|
||||
EExpect::IndentCondition,
|
||||
)
|
||||
.parse(arena, state)
|
||||
|
@ -1986,7 +1962,6 @@ fn expect_help<'a>(
|
|||
space0_before_e(
|
||||
move |a, s| parse_loc_expr(min_indent, a, s),
|
||||
min_indent,
|
||||
EExpr::Space,
|
||||
EExpr::IndentEnd,
|
||||
),
|
||||
);
|
||||
|
@ -2018,7 +1993,7 @@ fn if_expr_help<'a>(
|
|||
// try to parse another `if`
|
||||
// NOTE this drops spaces between the `else` and the `if`
|
||||
let optional_if = and!(
|
||||
backtrackable(space0_e(min_indent, EIf::Space, EIf::IndentIf)),
|
||||
backtrackable(space0_e(min_indent, EIf::IndentIf)),
|
||||
parser::keyword_e(keyword::IF, EIf::If)
|
||||
);
|
||||
|
||||
|
@ -2036,7 +2011,6 @@ fn if_expr_help<'a>(
|
|||
parse_loc_expr_with_options(min_indent, options, arena, state)
|
||||
}),
|
||||
min_indent,
|
||||
EIf::Space,
|
||||
EIf::IndentElseBranch,
|
||||
)
|
||||
.parse(arena, state_final_else)
|
||||
|
@ -2133,7 +2107,6 @@ fn list_literal_help<'a>(min_indent: u32) -> impl Parser<'a, Expr<'a>, EList<'a>
|
|||
word1(b']', EList::End),
|
||||
min_indent,
|
||||
EList::Open,
|
||||
EList::Space,
|
||||
EList::IndentEnd,
|
||||
Expr::SpaceBefore
|
||||
)
|
||||
|
@ -2158,8 +2131,7 @@ fn record_field_help<'a>(
|
|||
.parse(arena, state)?;
|
||||
debug_assert_eq!(progress, MadeProgress);
|
||||
|
||||
let (_, spaces, state) =
|
||||
space0_e(min_indent, ERecord::Space, ERecord::IndentColon).parse(arena, state)?;
|
||||
let (_, spaces, state) = space0_e(min_indent, ERecord::IndentColon).parse(arena, state)?;
|
||||
|
||||
// Having a value is optional; both `{ email }` and `{ email: blah }` work.
|
||||
// (This is true in both literals and types.)
|
||||
|
@ -2173,7 +2145,6 @@ fn record_field_help<'a>(
|
|||
parse_loc_expr_no_multi_backpassing(min_indent, a, s)
|
||||
}),
|
||||
min_indent,
|
||||
ERecord::Space,
|
||||
ERecord::IndentEnd,
|
||||
)
|
||||
))
|
||||
|
@ -2236,7 +2207,6 @@ fn record_help<'a>(
|
|||
// (and not e.g. an `Expr::Access`) and extract its string.
|
||||
loc!(record_updateable_identifier()),
|
||||
min_indent,
|
||||
ERecord::Space,
|
||||
ERecord::IndentEnd,
|
||||
ERecord::IndentAmpersand,
|
||||
),
|
||||
|
@ -2254,12 +2224,11 @@ fn record_help<'a>(
|
|||
space0_around_ee(
|
||||
loc!(record_field_help(min_indent)),
|
||||
min_indent,
|
||||
ERecord::Space,
|
||||
ERecord::IndentEnd,
|
||||
ERecord::IndentEnd
|
||||
),
|
||||
),
|
||||
space0_e(min_indent, ERecord::Space, ERecord::IndentEnd)
|
||||
space0_e(min_indent, ERecord::IndentEnd)
|
||||
),
|
||||
word1(b'}', ERecord::End)
|
||||
)
|
||||
|
|
|
@ -255,11 +255,7 @@ pub fn package_entry<'a>() -> impl Parser<'a, Spaced<'a, PackageEntry<'a>>, EPac
|
|||
specialize(|_, pos| EPackageEntry::Shorthand(pos), lowercase_ident()),
|
||||
word1(b':', EPackageEntry::Colon)
|
||||
),
|
||||
space0_e(
|
||||
min_indent,
|
||||
EPackageEntry::Space,
|
||||
EPackageEntry::IndentPackage
|
||||
)
|
||||
space0_e(min_indent, EPackageEntry::IndentPackage)
|
||||
))
|
||||
.parse(arena, state)?;
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ use crate::parser::Progress::{self, *};
|
|||
use crate::parser::{
|
||||
backtrackable, optional, specialize, specialize_region, word1, EExposes, EGenerates,
|
||||
EGeneratesWith, EHeader, EImports, EPackages, EProvides, ERequires, ETypedIdent, Parser,
|
||||
SourceError, SyntaxError,
|
||||
SourceError, SpaceProblem, SyntaxError,
|
||||
};
|
||||
use crate::state::State;
|
||||
use crate::string_literal;
|
||||
|
@ -57,7 +57,7 @@ fn header<'a>() -> impl Parser<'a, Module<'a>, EHeader<'a>> {
|
|||
|
||||
map!(
|
||||
and!(
|
||||
space0_e(0, EHeader::Space, EHeader::IndentStart),
|
||||
space0_e(0, EHeader::IndentStart),
|
||||
one_of![
|
||||
map!(
|
||||
skip_first!(keyword_e("interface", EHeader::Start), interface_header()),
|
||||
|
@ -107,7 +107,7 @@ fn interface_header<'a>() -> impl Parser<'a, InterfaceHeader<'a>, EHeader<'a>> {
|
|||
let min_indent = 1;
|
||||
|
||||
let (_, after_interface_keyword, state) =
|
||||
space0_e(min_indent, EHeader::Space, EHeader::IndentStart).parse(arena, state)?;
|
||||
space0_e(min_indent, EHeader::IndentStart).parse(arena, state)?;
|
||||
let (_, name, state) = loc!(module_name_help(EHeader::ModuleName)).parse(arena, state)?;
|
||||
|
||||
let (_, ((before_exposes, after_exposes), exposes), state) =
|
||||
|
@ -137,7 +137,7 @@ fn hosted_header<'a>() -> impl Parser<'a, HostedHeader<'a>, EHeader<'a>> {
|
|||
let min_indent = 1;
|
||||
|
||||
let (_, after_hosted_keyword, state) =
|
||||
space0_e(min_indent, EHeader::Space, EHeader::IndentStart).parse(arena, state)?;
|
||||
space0_e(min_indent, EHeader::IndentStart).parse(arena, state)?;
|
||||
let (_, name, state) = loc!(module_name_help(EHeader::ModuleName)).parse(arena, state)?;
|
||||
|
||||
let (_, ((before_exposes, after_exposes), exposes), state) =
|
||||
|
@ -236,7 +236,7 @@ fn app_header<'a>() -> impl Parser<'a, AppHeader<'a>, EHeader<'a>> {
|
|||
let min_indent = 1;
|
||||
|
||||
let (_, after_app_keyword, state) =
|
||||
space0_e(min_indent, EHeader::Space, EHeader::IndentStart).parse(arena, state)?;
|
||||
space0_e(min_indent, EHeader::IndentStart).parse(arena, state)?;
|
||||
let (_, name, state) = loc!(crate::parser::specialize(
|
||||
EHeader::AppName,
|
||||
string_literal::parse()
|
||||
|
@ -303,7 +303,7 @@ fn platform_header<'a>() -> impl Parser<'a, PlatformHeader<'a>, EHeader<'a>> {
|
|||
let min_indent = 1;
|
||||
|
||||
let (_, after_platform_keyword, state) =
|
||||
space0_e(min_indent, EHeader::Space, EHeader::IndentStart).parse(arena, state)?;
|
||||
space0_e(min_indent, EHeader::IndentStart).parse(arena, state)?;
|
||||
let (_, name, state) =
|
||||
loc!(specialize(EHeader::PlatformName, package_name())).parse(arena, state)?;
|
||||
|
||||
|
@ -380,7 +380,6 @@ fn provides_to<'a>() -> impl Parser<'a, ProvidesTo<'a>, EProvides<'a>> {
|
|||
min_indent,
|
||||
"to",
|
||||
EProvides::To,
|
||||
EProvides::Space,
|
||||
EProvides::IndentTo,
|
||||
EProvides::IndentListStart
|
||||
),
|
||||
|
@ -422,7 +421,6 @@ fn provides_without_to<'a>() -> impl Parser<
|
|||
min_indent,
|
||||
"provides",
|
||||
EProvides::Provides,
|
||||
EProvides::Space,
|
||||
EProvides::IndentProvides,
|
||||
EProvides::IndentListStart
|
||||
),
|
||||
|
@ -434,7 +432,6 @@ fn provides_without_to<'a>() -> impl Parser<
|
|||
word1(b']', EProvides::ListEnd),
|
||||
min_indent,
|
||||
EProvides::Open,
|
||||
EProvides::Space,
|
||||
EProvides::IndentListEnd,
|
||||
Spaced::SpaceBefore
|
||||
),
|
||||
|
@ -468,7 +465,6 @@ fn provides_types<'a>(
|
|||
word1(b'}', EProvides::ListEnd),
|
||||
min_indent,
|
||||
EProvides::Open,
|
||||
EProvides::Space,
|
||||
EProvides::IndentListEnd,
|
||||
Spaced::SpaceBefore
|
||||
)
|
||||
|
@ -518,7 +514,6 @@ fn requires<'a>() -> impl Parser<
|
|||
min_indent,
|
||||
"requires",
|
||||
ERequires::Requires,
|
||||
ERequires::Space,
|
||||
ERequires::IndentRequires,
|
||||
ERequires::IndentListStart
|
||||
),
|
||||
|
@ -530,10 +525,7 @@ fn requires<'a>() -> impl Parser<
|
|||
fn platform_requires<'a>() -> impl Parser<'a, PlatformRequires<'a>, ERequires<'a>> {
|
||||
map!(
|
||||
and!(
|
||||
skip_second!(
|
||||
requires_rigids(0),
|
||||
space0_e(0, ERequires::Space, ERequires::ListStart)
|
||||
),
|
||||
skip_second!(requires_rigids(0), space0_e(0, ERequires::ListStart)),
|
||||
requires_typed_ident()
|
||||
),
|
||||
|(rigids, signature)| { PlatformRequires { rigids, signature } }
|
||||
|
@ -554,7 +546,6 @@ fn requires_rigids<'a>(
|
|||
word1(b'}', ERequires::ListEnd),
|
||||
min_indent,
|
||||
ERequires::Open,
|
||||
ERequires::Space,
|
||||
ERequires::IndentListEnd,
|
||||
Spaced::SpaceBefore
|
||||
)
|
||||
|
@ -568,7 +559,6 @@ fn requires_typed_ident<'a>() -> impl Parser<'a, Loc<Spaced<'a, TypedIdent<'a>>>
|
|||
space0_around_ee(
|
||||
specialize(ERequires::TypedIdent, loc!(typed_ident()),),
|
||||
0,
|
||||
ERequires::Space,
|
||||
ERequires::ListStart,
|
||||
ERequires::ListEnd
|
||||
),
|
||||
|
@ -593,7 +583,6 @@ fn exposes_values<'a>() -> impl Parser<
|
|||
min_indent,
|
||||
"exposes",
|
||||
EExposes::Exposes,
|
||||
EExposes::Space,
|
||||
EExposes::IndentExposes,
|
||||
EExposes::IndentListStart
|
||||
),
|
||||
|
@ -604,7 +593,6 @@ fn exposes_values<'a>() -> impl Parser<
|
|||
word1(b']', EExposes::ListEnd),
|
||||
min_indent,
|
||||
EExposes::Open,
|
||||
EExposes::Space,
|
||||
EExposes::IndentListEnd,
|
||||
Spaced::SpaceBefore
|
||||
)
|
||||
|
@ -615,19 +603,18 @@ fn spaces_around_keyword<'a, E>(
|
|||
min_indent: u32,
|
||||
keyword: &'static str,
|
||||
expectation: fn(Position) -> E,
|
||||
space_problem: fn(crate::parser::BadInputError, Position) -> E,
|
||||
indent_problem1: fn(Position) -> E,
|
||||
indent_problem2: fn(Position) -> E,
|
||||
) -> impl Parser<'a, (&'a [CommentOrNewline<'a>], &'a [CommentOrNewline<'a>]), E>
|
||||
where
|
||||
E: 'a,
|
||||
E: 'a + SpaceProblem,
|
||||
{
|
||||
and!(
|
||||
skip_second!(
|
||||
backtrackable(space0_e(min_indent, space_problem, indent_problem1)),
|
||||
backtrackable(space0_e(min_indent, indent_problem1)),
|
||||
crate::parser::keyword_e(keyword, expectation)
|
||||
),
|
||||
space0_e(min_indent, space_problem, indent_problem2)
|
||||
space0_e(min_indent, indent_problem2)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -647,7 +634,6 @@ fn exposes_modules<'a>() -> impl Parser<
|
|||
min_indent,
|
||||
"exposes",
|
||||
EExposes::Exposes,
|
||||
EExposes::Space,
|
||||
EExposes::IndentExposes,
|
||||
EExposes::IndentListStart
|
||||
),
|
||||
|
@ -658,7 +644,6 @@ fn exposes_modules<'a>() -> impl Parser<
|
|||
word1(b']', EExposes::ListEnd),
|
||||
min_indent,
|
||||
EExposes::Open,
|
||||
EExposes::Space,
|
||||
EExposes::IndentListEnd,
|
||||
Spaced::SpaceBefore
|
||||
)
|
||||
|
@ -696,7 +681,6 @@ fn packages<'a>() -> impl Parser<'a, Packages<'a>, EPackages<'a>> {
|
|||
min_indent,
|
||||
"packages",
|
||||
EPackages::Packages,
|
||||
EPackages::Space,
|
||||
EPackages::IndentPackages,
|
||||
EPackages::IndentListStart
|
||||
),
|
||||
|
@ -707,7 +691,6 @@ fn packages<'a>() -> impl Parser<'a, Packages<'a>, EPackages<'a>> {
|
|||
word1(b'}', EPackages::ListEnd),
|
||||
min_indent,
|
||||
EPackages::Open,
|
||||
EPackages::Space,
|
||||
EPackages::IndentListEnd,
|
||||
Spaced::SpaceBefore
|
||||
)
|
||||
|
@ -741,7 +724,6 @@ fn generates<'a>() -> impl Parser<
|
|||
min_indent,
|
||||
"generates",
|
||||
EGenerates::Generates,
|
||||
EGenerates::Space,
|
||||
EGenerates::IndentGenerates,
|
||||
EGenerates::IndentTypeStart
|
||||
),
|
||||
|
@ -765,7 +747,6 @@ fn generates_with<'a>() -> impl Parser<
|
|||
min_indent,
|
||||
"with",
|
||||
EGeneratesWith::With,
|
||||
EGeneratesWith::Space,
|
||||
EGeneratesWith::IndentWith,
|
||||
EGeneratesWith::IndentListStart
|
||||
),
|
||||
|
@ -776,7 +757,6 @@ fn generates_with<'a>() -> impl Parser<
|
|||
word1(b']', EGeneratesWith::ListEnd),
|
||||
min_indent,
|
||||
EGeneratesWith::Open,
|
||||
EGeneratesWith::Space,
|
||||
EGeneratesWith::IndentListEnd,
|
||||
Spaced::SpaceBefore
|
||||
)
|
||||
|
@ -799,7 +779,6 @@ fn imports<'a>() -> impl Parser<
|
|||
min_indent,
|
||||
"imports",
|
||||
EImports::Imports,
|
||||
EImports::Space,
|
||||
EImports::IndentImports,
|
||||
EImports::IndentListStart
|
||||
),
|
||||
|
@ -810,7 +789,6 @@ fn imports<'a>() -> impl Parser<
|
|||
word1(b']', EImports::ListEnd),
|
||||
min_indent,
|
||||
EImports::Open,
|
||||
EImports::Space,
|
||||
EImports::IndentListEnd,
|
||||
Spaced::SpaceBefore
|
||||
)
|
||||
|
@ -831,7 +809,7 @@ fn typed_ident<'a>() -> impl Parser<'a, Spaced<'a, TypedIdent<'a>>, ETypedIdent<
|
|||
|_, pos| ETypedIdent::Identifier(pos),
|
||||
lowercase_ident()
|
||||
)),
|
||||
space0_e(min_indent, ETypedIdent::Space, ETypedIdent::IndentHasType)
|
||||
space0_e(min_indent, ETypedIdent::IndentHasType)
|
||||
),
|
||||
skip_first!(
|
||||
word1(b':', ETypedIdent::HasType),
|
||||
|
@ -841,7 +819,6 @@ fn typed_ident<'a>() -> impl Parser<'a, Spaced<'a, TypedIdent<'a>>, ETypedIdent<
|
|||
type_annotation::located_help(min_indent, true)
|
||||
),
|
||||
min_indent,
|
||||
ETypedIdent::Space,
|
||||
ETypedIdent::IndentType,
|
||||
)
|
||||
)
|
||||
|
@ -899,7 +876,6 @@ fn imports_entry<'a>() -> impl Parser<'a, Spaced<'a, ImportsEntry<'a>>, EImports
|
|||
word1(b'}', EImports::SetEnd),
|
||||
min_indent,
|
||||
EImports::Open,
|
||||
EImports::Space,
|
||||
EImports::IndentSetEnd,
|
||||
Spaced::SpaceBefore
|
||||
)
|
||||
|
|
|
@ -63,6 +63,50 @@ pub enum SyntaxError<'a> {
|
|||
Space(BadInputError),
|
||||
NotEndOfFile(Position),
|
||||
}
|
||||
pub trait SpaceProblem {
|
||||
fn space_problem(e: BadInputError, pos: Position) -> Self;
|
||||
}
|
||||
|
||||
macro_rules! impl_space_problem {
|
||||
($($name:ident $(< $lt:tt >)?),*) => {
|
||||
$(
|
||||
impl $(< $lt >)? SpaceProblem for $name $(< $lt >)? {
|
||||
fn space_problem(e: BadInputError, pos: Position) -> Self {
|
||||
Self::Space(e, pos)
|
||||
}
|
||||
}
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
impl_space_problem! {
|
||||
EExpect<'a>,
|
||||
EExposes,
|
||||
EExpr<'a>,
|
||||
EGenerates,
|
||||
EGeneratesWith,
|
||||
EHeader<'a>,
|
||||
EIf<'a>,
|
||||
EImports,
|
||||
EInParens<'a>,
|
||||
ELambda<'a>,
|
||||
EList<'a>,
|
||||
EPackageEntry<'a>,
|
||||
EPackages<'a>,
|
||||
EPattern<'a>,
|
||||
EProvides<'a>,
|
||||
ERecord<'a>,
|
||||
ERequires<'a>,
|
||||
EString<'a>,
|
||||
EType<'a>,
|
||||
ETypeInParens<'a>,
|
||||
ETypeRecord<'a>,
|
||||
ETypeTagUnion<'a>,
|
||||
ETypedIdent<'a>,
|
||||
EWhen<'a>,
|
||||
PInParens<'a>,
|
||||
PRecord<'a>
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum EHeader<'a> {
|
||||
|
@ -505,6 +549,8 @@ pub enum PInParens<'a> {
|
|||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum EType<'a> {
|
||||
Space(BadInputError, Position),
|
||||
|
||||
TRecord(ETypeRecord<'a>, Position),
|
||||
TTagUnion(ETypeTagUnion<'a>, Position),
|
||||
TInParens(ETypeInParens<'a>, Position),
|
||||
|
@ -516,7 +562,6 @@ pub enum EType<'a> {
|
|||
///
|
||||
TStart(Position),
|
||||
TEnd(Position),
|
||||
TSpace(BadInputError, Position),
|
||||
TFunctionArgument(Position),
|
||||
///
|
||||
TIndentStart(Position),
|
||||
|
@ -1153,11 +1198,11 @@ macro_rules! collection {
|
|||
|
||||
#[macro_export]
|
||||
macro_rules! collection_trailing_sep_e {
|
||||
($opening_brace:expr, $elem:expr, $delimiter:expr, $closing_brace:expr, $min_indent:expr, $open_problem:expr, $space_problem:expr, $indent_problem:expr, $space_before:expr) => {
|
||||
($opening_brace:expr, $elem:expr, $delimiter:expr, $closing_brace:expr, $min_indent:expr, $open_problem:expr, $indent_problem:expr, $space_before:expr) => {
|
||||
skip_first!(
|
||||
$opening_brace,
|
||||
|arena, state| {
|
||||
let (_, spaces, state) = space0_e($min_indent, $space_problem, $indent_problem)
|
||||
let (_, spaces, state) = space0_e($min_indent, $indent_problem)
|
||||
.parse(arena, state)?;
|
||||
|
||||
let (_, (mut parsed_elems, mut final_comments), state) =
|
||||
|
@ -1167,12 +1212,11 @@ macro_rules! collection_trailing_sep_e {
|
|||
$crate::blankspace::space0_before_optional_after(
|
||||
$elem,
|
||||
$min_indent,
|
||||
$space_problem,
|
||||
$indent_problem,
|
||||
$indent_problem
|
||||
)
|
||||
),
|
||||
$crate::blankspace::space0_e($min_indent, $space_problem, $indent_problem)
|
||||
$crate::blankspace::space0_e($min_indent, $indent_problem)
|
||||
).parse(arena, state)?;
|
||||
|
||||
let (_,_, state) =
|
||||
|
|
|
@ -75,8 +75,7 @@ fn loc_tag_pattern_arg<'a>(min_indent: u32) -> impl Parser<'a, Loc<Pattern<'a>>,
|
|||
// If we encounter one, we're done parsing function args!
|
||||
move |arena, state| {
|
||||
let (_, spaces, state) =
|
||||
backtrackable(space0_e(min_indent, EPattern::Space, EPattern::IndentStart))
|
||||
.parse(arena, state)?;
|
||||
backtrackable(space0_e(min_indent, EPattern::IndentStart)).parse(arena, state)?;
|
||||
|
||||
let (_, loc_pat, state) = loc_parse_tag_pattern_arg(min_indent, arena, state)?;
|
||||
|
||||
|
@ -123,7 +122,6 @@ fn loc_pattern_in_parens_help<'a>(
|
|||
move |arena, state| specialize_ref(PInParens::Pattern, loc_pattern_help(min_indent))
|
||||
.parse(arena, state),
|
||||
min_indent,
|
||||
PInParens::Space,
|
||||
PInParens::IndentOpen,
|
||||
PInParens::IndentEnd,
|
||||
),
|
||||
|
@ -321,7 +319,6 @@ fn record_pattern_help<'a>(min_indent: u32) -> impl Parser<'a, Pattern<'a>, PRec
|
|||
word1(b'}', PRecord::End),
|
||||
min_indent,
|
||||
PRecord::Open,
|
||||
PRecord::Space,
|
||||
PRecord::IndentEnd,
|
||||
Pattern::SpaceBefore
|
||||
)
|
||||
|
@ -347,8 +344,7 @@ fn record_pattern_field<'a>(min_indent: u32) -> impl Parser<'a, Loc<Pattern<'a>>
|
|||
.parse(arena, state)?;
|
||||
debug_assert_eq!(progress, MadeProgress);
|
||||
|
||||
let (_, spaces, state) =
|
||||
space0_e(min_indent, PRecord::Space, PRecord::IndentEnd).parse(arena, state)?;
|
||||
let (_, spaces, state) = space0_e(min_indent, PRecord::IndentEnd).parse(arena, state)?;
|
||||
|
||||
// Having a value is optional; both `{ email }` and `{ email: blah }` work.
|
||||
// (This is true in both literals and types.)
|
||||
|
@ -362,7 +358,7 @@ fn record_pattern_field<'a>(min_indent: u32) -> impl Parser<'a, Loc<Pattern<'a>>
|
|||
Some(First(_)) => {
|
||||
let val_parser = specialize_ref(PRecord::Pattern, loc_pattern_help(min_indent));
|
||||
let (_, loc_val, state) =
|
||||
space0_before_e(val_parser, min_indent, PRecord::Space, PRecord::IndentColon)
|
||||
space0_before_e(val_parser, min_indent, PRecord::IndentColon)
|
||||
.parse(arena, state)?;
|
||||
|
||||
let Loc {
|
||||
|
@ -392,7 +388,7 @@ fn record_pattern_field<'a>(min_indent: u32) -> impl Parser<'a, Loc<Pattern<'a>>
|
|||
});
|
||||
|
||||
let (_, loc_val, state) =
|
||||
space0_before_e(val_parser, min_indent, PRecord::Space, PRecord::IndentColon)
|
||||
space0_before_e(val_parser, min_indent, PRecord::IndentColon)
|
||||
.parse(arena, state)?;
|
||||
|
||||
let Loc {
|
||||
|
|
|
@ -28,7 +28,6 @@ fn tag_union_type<'a>(min_indent: u32) -> impl Parser<'a, TypeAnnotation<'a>, ET
|
|||
word1(b']', ETypeTagUnion::End),
|
||||
min_indent,
|
||||
ETypeTagUnion::Open,
|
||||
ETypeTagUnion::Space,
|
||||
ETypeTagUnion::IndentEnd,
|
||||
Tag::SpaceBefore
|
||||
)
|
||||
|
@ -87,16 +86,11 @@ fn check_type_alias(
|
|||
|
||||
fn parse_type_alias_after_as<'a>(min_indent: u32) -> impl Parser<'a, AliasHeader<'a>, EType<'a>> {
|
||||
move |arena, state| {
|
||||
space0_before_e(
|
||||
term(min_indent),
|
||||
min_indent,
|
||||
EType::TSpace,
|
||||
EType::TAsIndentStart,
|
||||
)
|
||||
.parse(arena, state)
|
||||
.and_then(|(p, annot, state)| {
|
||||
specialize(EType::TInlineAlias, check_type_alias(p, annot)).parse(arena, state)
|
||||
})
|
||||
space0_before_e(term(min_indent), min_indent, EType::TAsIndentStart)
|
||||
.parse(arena, state)
|
||||
.and_then(|(p, annot, state)| {
|
||||
specialize(EType::TInlineAlias, check_type_alias(p, annot)).parse(arena, state)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -122,7 +116,7 @@ fn term<'a>(min_indent: u32) -> impl Parser<'a, Loc<TypeAnnotation<'a>>, EType<'
|
|||
map!(
|
||||
and!(
|
||||
skip_second!(
|
||||
backtrackable(space0_e(min_indent, EType::TSpace, EType::TIndentEnd)),
|
||||
backtrackable(space0_e(min_indent, EType::TIndentEnd)),
|
||||
crate::parser::keyword_e(keyword::AS, EType::TEnd)
|
||||
),
|
||||
parse_type_alias_after_as(min_indent)
|
||||
|
@ -170,7 +164,7 @@ fn loc_applied_arg<'a>(min_indent: u32) -> impl Parser<'a, Loc<TypeAnnotation<'a
|
|||
|
||||
map_with_arena!(
|
||||
and!(
|
||||
backtrackable(space0_e(min_indent, EType::TSpace, EType::TIndentStart)),
|
||||
backtrackable(space0_e(min_indent, EType::TIndentStart)),
|
||||
one_of!(
|
||||
loc_wildcard(),
|
||||
loc_inferred(),
|
||||
|
@ -201,7 +195,6 @@ fn loc_type_in_parens<'a>(
|
|||
move |arena, state| specialize_ref(ETypeInParens::Type, expression(min_indent, true))
|
||||
.parse(arena, state),
|
||||
min_indent,
|
||||
ETypeInParens::Space,
|
||||
ETypeInParens::IndentOpen,
|
||||
ETypeInParens::IndentEnd,
|
||||
),
|
||||
|
@ -263,7 +256,7 @@ fn record_type_field<'a>(
|
|||
debug_assert_eq!(progress, MadeProgress);
|
||||
|
||||
let (_, spaces, state) =
|
||||
space0_e(min_indent, ETypeRecord::Space, ETypeRecord::IndentEnd).parse(arena, state)?;
|
||||
space0_e(min_indent, ETypeRecord::IndentEnd).parse(arena, state)?;
|
||||
|
||||
// Having a value is optional; both `{ email }` and `{ email: blah }` work.
|
||||
// (This is true in both literals and types.)
|
||||
|
@ -277,13 +270,9 @@ fn record_type_field<'a>(
|
|||
|
||||
match opt_loc_val {
|
||||
Some(First(_)) => {
|
||||
let (_, loc_val, state) = space0_before_e(
|
||||
val_parser,
|
||||
min_indent,
|
||||
ETypeRecord::Space,
|
||||
ETypeRecord::IndentColon,
|
||||
)
|
||||
.parse(arena, state)?;
|
||||
let (_, loc_val, state) =
|
||||
space0_before_e(val_parser, min_indent, ETypeRecord::IndentColon)
|
||||
.parse(arena, state)?;
|
||||
|
||||
Ok((
|
||||
MadeProgress,
|
||||
|
@ -292,13 +281,9 @@ fn record_type_field<'a>(
|
|||
))
|
||||
}
|
||||
Some(Second(_)) => {
|
||||
let (_, loc_val, state) = space0_before_e(
|
||||
val_parser,
|
||||
min_indent,
|
||||
ETypeRecord::Space,
|
||||
ETypeRecord::IndentOptional,
|
||||
)
|
||||
.parse(arena, state)?;
|
||||
let (_, loc_val, state) =
|
||||
space0_before_e(val_parser, min_indent, ETypeRecord::IndentOptional)
|
||||
.parse(arena, state)?;
|
||||
|
||||
Ok((
|
||||
MadeProgress,
|
||||
|
@ -336,7 +321,6 @@ fn record_type<'a>(min_indent: u32) -> impl Parser<'a, TypeAnnotation<'a>, EType
|
|||
word1(b'}', ETypeRecord::End),
|
||||
min_indent,
|
||||
ETypeRecord::Open,
|
||||
ETypeRecord::Space,
|
||||
ETypeRecord::IndentEnd,
|
||||
AssignedField::SpaceBefore
|
||||
)
|
||||
|
@ -389,13 +373,8 @@ fn expression<'a>(
|
|||
is_trailing_comma_valid: bool,
|
||||
) -> impl Parser<'a, Loc<TypeAnnotation<'a>>, EType<'a>> {
|
||||
(move |arena, state: State<'a>| {
|
||||
let (p1, first, state) = space0_before_e(
|
||||
term(min_indent),
|
||||
min_indent,
|
||||
EType::TSpace,
|
||||
EType::TIndentStart,
|
||||
)
|
||||
.parse(arena, state)?;
|
||||
let (p1, first, state) = space0_before_e(term(min_indent), min_indent, EType::TIndentStart)
|
||||
.parse(arena, state)?;
|
||||
|
||||
let result = and![
|
||||
zero_or_more!(skip_first!(
|
||||
|
@ -404,7 +383,6 @@ fn expression<'a>(
|
|||
space0_around_ee(
|
||||
term(min_indent),
|
||||
min_indent,
|
||||
EType::TSpace,
|
||||
EType::TIndentStart,
|
||||
EType::TIndentEnd
|
||||
),
|
||||
|
@ -419,7 +397,7 @@ fn expression<'a>(
|
|||
// TODO this space0 is dropped, so newlines just before the function arrow when there
|
||||
// is only one argument are not seen by the formatter. Can we do better?
|
||||
skip_second!(
|
||||
space0_e(min_indent, EType::TSpace, EType::TIndentStart),
|
||||
space0_e(min_indent, EType::TIndentStart),
|
||||
word2(b'-', b'>', EType::TStart)
|
||||
)
|
||||
.trace("type_annotation:expression:arrow")
|
||||
|
@ -428,13 +406,9 @@ fn expression<'a>(
|
|||
|
||||
match result {
|
||||
Ok((p2, (rest, _dropped_spaces), state)) => {
|
||||
let (p3, return_type, state) = space0_before_e(
|
||||
term(min_indent),
|
||||
min_indent,
|
||||
EType::TSpace,
|
||||
EType::TIndentStart,
|
||||
)
|
||||
.parse(arena, state)?;
|
||||
let (p3, return_type, state) =
|
||||
space0_before_e(term(min_indent), min_indent, EType::TIndentStart)
|
||||
.parse(arena, state)?;
|
||||
|
||||
// prepare arguments
|
||||
let mut arguments = Vec::with_capacity_in(rest.len() + 1, arena);
|
||||
|
@ -452,7 +426,7 @@ fn expression<'a>(
|
|||
Err(err) => {
|
||||
if !is_trailing_comma_valid {
|
||||
let (_, comma, _) = optional(skip_first!(
|
||||
space0_e(min_indent, EType::TSpace, EType::TIndentStart),
|
||||
space0_e(min_indent, EType::TIndentStart),
|
||||
word1(b',', EType::TStart)
|
||||
))
|
||||
.trace("check trailing comma")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue