mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 13:29:12 +00:00
PNC for Patterns, stabilize formatting
This commit is contained in:
parent
bac165fd99
commit
3b0db07fa1
78 changed files with 789 additions and 332 deletions
|
@ -13,14 +13,14 @@ use crate::pattern::{pattern_lift_spaces, pattern_lift_spaces_before};
|
|||
use crate::spaces::{
|
||||
fmt_comments_only, fmt_default_newline, fmt_default_spaces, fmt_spaces, NewlineAt, INDENT,
|
||||
};
|
||||
use crate::Buf;
|
||||
use crate::{Buf, MigrationFlags};
|
||||
use bumpalo::Bump;
|
||||
use roc_error_macros::internal_error;
|
||||
use roc_parse::ast::{
|
||||
AbilityMember, Defs, Expr, ExtractSpaces, ImportAlias, ImportAsKeyword, ImportExposingKeyword,
|
||||
ImportedModuleName, IngestedFileAnnotation, IngestedFileImport, ModuleImport,
|
||||
ModuleImportParams, Pattern, Spaceable, Spaces, SpacesAfter, SpacesBefore, StrLiteral,
|
||||
TypeAnnotation, TypeDef, TypeHeader, ValueDef,
|
||||
ModuleImportParams, Pattern, PatternApplyStyle, Spaceable, Spaces, SpacesAfter, SpacesBefore,
|
||||
StrLiteral, TypeAnnotation, TypeDef, TypeHeader, ValueDef,
|
||||
};
|
||||
use roc_parse::expr::merge_spaces;
|
||||
use roc_parse::header::Keyword;
|
||||
|
@ -564,6 +564,11 @@ impl<'a> Formattable for TypeHeader<'a> {
|
|||
_newlines: Newlines,
|
||||
indent: u16,
|
||||
) {
|
||||
let old_flags = buf.flags;
|
||||
buf.flags = MigrationFlags {
|
||||
parens_and_commas: false,
|
||||
..old_flags
|
||||
};
|
||||
pattern_fmt_apply(
|
||||
buf,
|
||||
Pattern::Tag(self.name.value),
|
||||
|
@ -571,7 +576,9 @@ impl<'a> Formattable for TypeHeader<'a> {
|
|||
Parens::NotNeeded,
|
||||
indent,
|
||||
self.vars.iter().any(|v| v.is_multiline()),
|
||||
PatternApplyStyle::Whitespace,
|
||||
);
|
||||
buf.flags = old_flags;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -582,6 +589,7 @@ fn type_head_lift_spaces<'a, 'b: 'a>(
|
|||
let pat = Pattern::Apply(
|
||||
arena.alloc(Loc::at(head.name.region, Pattern::Tag(head.name.value))),
|
||||
head.vars,
|
||||
PatternApplyStyle::Whitespace,
|
||||
);
|
||||
|
||||
pattern_lift_spaces(arena, &pat)
|
||||
|
@ -903,7 +911,9 @@ impl<'a> Formattable for ValueDef<'a> {
|
|||
fn ann_pattern_needs_parens(value: &Pattern<'_>) -> bool {
|
||||
match value.extract_spaces().item {
|
||||
Pattern::Tag(_) => true,
|
||||
Pattern::Apply(func, _args) if matches!(func.extract_spaces().item, Pattern::Tag(..)) => {
|
||||
Pattern::Apply(func, _args, _style)
|
||||
if matches!(func.extract_spaces().item, Pattern::Tag(..)) =>
|
||||
{
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
|
|
|
@ -11,7 +11,7 @@ use crate::spaces::{
|
|||
use crate::Buf;
|
||||
use bumpalo::collections::Vec;
|
||||
use bumpalo::Bump;
|
||||
use roc_module::called_via::{self, BinOp, UnaryOp};
|
||||
use roc_module::called_via::{self, BinOp, CalledVia, UnaryOp};
|
||||
use roc_parse::ast::{
|
||||
AssignedField, Base, Collection, CommentOrNewline, Expr, ExtractSpaces, Pattern, Spaceable,
|
||||
Spaces, SpacesAfter, SpacesBefore, TryTarget, WhenBranch,
|
||||
|
@ -96,8 +96,9 @@ fn format_expr_only(
|
|||
}
|
||||
Expr::Apply(loc_expr, loc_args, _) => {
|
||||
let apply_needs_parens = parens == Parens::InApply || parens == Parens::InApplyLastArg;
|
||||
|
||||
if apply_needs_parens && !loc_args.is_empty() {
|
||||
if buf.flags().parens_and_commas {
|
||||
fmt_apply(loc_expr, loc_args, indent, buf, false);
|
||||
} else if apply_needs_parens && !loc_args.is_empty() {
|
||||
fmt_parens(item, buf, indent);
|
||||
} else {
|
||||
fmt_apply(loc_expr, loc_args, indent, buf, false);
|
||||
|
@ -716,7 +717,9 @@ fn fmt_apply(
|
|||
let is_first_arg = i == 0;
|
||||
|
||||
let arg = expr_lift_spaces(
|
||||
if is_last_arg {
|
||||
if use_commas_and_parens {
|
||||
Parens::NotNeeded
|
||||
} else if is_last_arg {
|
||||
Parens::InApplyLastArg
|
||||
} else {
|
||||
Parens::InApply
|
||||
|
@ -1038,7 +1041,7 @@ pub fn expr_lift_spaces<'a, 'b: 'a>(
|
|||
) -> Spaces<'a, Expr<'a>> {
|
||||
match expr {
|
||||
Expr::Apply(func, args, called_via) => {
|
||||
if args.is_empty() {
|
||||
if args.is_empty() && !matches!(called_via, CalledVia::ParensAndCommas) {
|
||||
return expr_lift_spaces(Parens::NotNeeded, arena, &func.value);
|
||||
}
|
||||
|
||||
|
@ -1082,7 +1085,9 @@ pub fn expr_lift_spaces<'a, 'b: 'a>(
|
|||
}
|
||||
};
|
||||
|
||||
if parens == Parens::InApply || parens == Parens::InApplyLastArg {
|
||||
if (parens == Parens::InApply || parens == Parens::InApplyLastArg)
|
||||
&& !matches!(called_via, CalledVia::ParensAndCommas)
|
||||
{
|
||||
res = Spaces {
|
||||
before: &[],
|
||||
item: Expr::ParensAround(arena.alloc(lower(arena, res))),
|
||||
|
|
|
@ -7,7 +7,8 @@ use crate::spaces::{fmt_comments_only, fmt_spaces, NewlineAt, INDENT};
|
|||
use crate::Buf;
|
||||
use bumpalo::Bump;
|
||||
use roc_parse::ast::{
|
||||
Base, CommentOrNewline, Pattern, PatternAs, Spaceable, Spaces, SpacesAfter, SpacesBefore,
|
||||
Base, CommentOrNewline, Pattern, PatternApplyStyle, PatternAs, Spaceable, Spaces, SpacesAfter,
|
||||
SpacesBefore,
|
||||
};
|
||||
use roc_parse::expr::merge_spaces;
|
||||
use roc_region::all::Loc;
|
||||
|
@ -72,7 +73,7 @@ impl<'a> Formattable for Pattern<'a> {
|
|||
}
|
||||
},
|
||||
Pattern::StrLiteral(literal) => is_str_multiline(literal),
|
||||
Pattern::Apply(pat, args) => {
|
||||
Pattern::Apply(pat, args, _) => {
|
||||
pat.is_multiline() || args.iter().any(|a| a.is_multiline())
|
||||
}
|
||||
|
||||
|
@ -162,7 +163,22 @@ fn fmt_pattern_only(
|
|||
buf.indent(indent);
|
||||
buf.push_str(name);
|
||||
}
|
||||
Pattern::Apply(loc_pattern, loc_arg_patterns) => {
|
||||
Pattern::Apply(
|
||||
loc_pattern,
|
||||
loc_arg_patterns,
|
||||
style @ PatternApplyStyle::ParensAndCommas,
|
||||
) => {
|
||||
pattern_fmt_apply(
|
||||
buf,
|
||||
loc_pattern.value,
|
||||
loc_arg_patterns,
|
||||
Parens::NotNeeded,
|
||||
indent,
|
||||
is_multiline,
|
||||
*style,
|
||||
);
|
||||
}
|
||||
Pattern::Apply(loc_pattern, loc_arg_patterns, style) => {
|
||||
pattern_fmt_apply(
|
||||
buf,
|
||||
loc_pattern.value,
|
||||
|
@ -170,6 +186,7 @@ fn fmt_pattern_only(
|
|||
parens,
|
||||
indent,
|
||||
is_multiline,
|
||||
*style,
|
||||
);
|
||||
}
|
||||
Pattern::RecordDestructure(loc_patterns) => {
|
||||
|
@ -445,11 +462,14 @@ pub fn pattern_fmt_apply(
|
|||
parens: Parens,
|
||||
indent: u16,
|
||||
is_multiline: bool,
|
||||
style: PatternApplyStyle,
|
||||
) {
|
||||
let use_commas_and_parens =
|
||||
matches!(style, PatternApplyStyle::ParensAndCommas) || buf.flags().parens_and_commas;
|
||||
buf.indent(indent);
|
||||
// Sometimes, an Apply pattern needs parens around it.
|
||||
// In particular when an Apply's argument is itself an Apply (> 0) arguments
|
||||
let parens = !args.is_empty() && parens == Parens::InApply;
|
||||
let parens = !args.is_empty() && parens == Parens::InApply && !use_commas_and_parens;
|
||||
|
||||
let indent_more = if is_multiline {
|
||||
indent + INDENT
|
||||
|
@ -473,14 +493,27 @@ pub fn pattern_fmt_apply(
|
|||
|
||||
fmt_pattern_only(&func.item, buf, Parens::InApply, indent, is_multiline);
|
||||
|
||||
if use_commas_and_parens {
|
||||
buf.push('(');
|
||||
}
|
||||
|
||||
let mut last_after = func.after;
|
||||
|
||||
let mut add_newlines = is_multiline;
|
||||
|
||||
for loc_arg in args.iter() {
|
||||
buf.spaces(1);
|
||||
for (i, loc_arg) in args.iter().enumerate() {
|
||||
let is_last_arg = i == args.len() - 1;
|
||||
let is_first_arg = i == 0;
|
||||
|
||||
let parens = Parens::InApply;
|
||||
if !(is_first_arg && use_commas_and_parens) {
|
||||
buf.spaces(1);
|
||||
}
|
||||
|
||||
let parens = if use_commas_and_parens {
|
||||
Parens::NotNeeded
|
||||
} else {
|
||||
Parens::InApply
|
||||
};
|
||||
let arg = pattern_lift_spaces(buf.text.bump(), &loc_arg.value);
|
||||
|
||||
let mut was_multiline = arg.item.is_multiline();
|
||||
|
@ -527,6 +560,9 @@ pub fn pattern_fmt_apply(
|
|||
buf.push_str("(implements)");
|
||||
} else {
|
||||
fmt_pattern_only(&arg.item, buf, parens, indent_more, arg.item.is_multiline());
|
||||
if use_commas_and_parens && (!is_last_arg || add_newlines) {
|
||||
buf.push(',');
|
||||
}
|
||||
}
|
||||
|
||||
last_after = arg.after;
|
||||
|
@ -542,7 +578,7 @@ pub fn pattern_fmt_apply(
|
|||
}
|
||||
}
|
||||
|
||||
if parens {
|
||||
if parens || use_commas_and_parens {
|
||||
buf.push(')');
|
||||
}
|
||||
}
|
||||
|
@ -597,7 +633,7 @@ fn pattern_prec(pat: Pattern<'_>) -> Prec {
|
|||
| Pattern::Tuple(..)
|
||||
| Pattern::List(..)
|
||||
| Pattern::ListRest(_) => Prec::Term,
|
||||
Pattern::Apply(_, _) | Pattern::As(_, _) => Prec::Apply,
|
||||
Pattern::Apply(_, _, _) | Pattern::As(_, _) => Prec::Apply,
|
||||
Pattern::SpaceBefore(inner, _) | Pattern::SpaceAfter(inner, _) => pattern_prec(*inner),
|
||||
Pattern::Malformed(_) | Pattern::MalformedIdent(..) => Prec::Term,
|
||||
}
|
||||
|
@ -617,7 +653,7 @@ pub fn pattern_lift_spaces<'a, 'b: 'a>(
|
|||
pat: &Pattern<'b>,
|
||||
) -> Spaces<'a, Pattern<'a>> {
|
||||
match pat {
|
||||
Pattern::Apply(func, args) => {
|
||||
Pattern::Apply(func, args, style) => {
|
||||
let func_lifted = pattern_lift_spaces(arena, &func.value);
|
||||
|
||||
let args = arena.alloc_slice_copy(args);
|
||||
|
@ -652,7 +688,7 @@ pub fn pattern_lift_spaces<'a, 'b: 'a>(
|
|||
};
|
||||
Spaces {
|
||||
before,
|
||||
item: Pattern::Apply(arena.alloc(func), args),
|
||||
item: Pattern::Apply(arena.alloc(func), args, *style),
|
||||
after,
|
||||
}
|
||||
}
|
||||
|
@ -712,7 +748,7 @@ fn handle_multiline_str_spaces<'a>(pat: &Pattern<'_>, before: &mut &'a [CommentO
|
|||
|
||||
fn starts_with_block_str(item: &Pattern<'_>) -> bool {
|
||||
match item {
|
||||
Pattern::As(inner, _) | Pattern::Apply(inner, _) => starts_with_block_str(&inner.value),
|
||||
Pattern::As(inner, _) | Pattern::Apply(inner, _, _) => starts_with_block_str(&inner.value),
|
||||
Pattern::SpaceBefore(inner, _) | Pattern::SpaceAfter(inner, _) => {
|
||||
starts_with_block_str(inner)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue