mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 16:44:33 +00:00
add OptionalField constructor
This commit is contained in:
parent
1b4f7ccfa5
commit
c4971675eb
6 changed files with 30 additions and 0 deletions
|
@ -117,6 +117,9 @@ fn can_assigned_field<'a>(
|
|||
let field_type = can_annotation_help(&annotation.value, var_store, rigids);
|
||||
field_types.insert(Lowercase::from(field_name.value), field_type);
|
||||
}
|
||||
OptionalField(_field_name, _, _annotation) => {
|
||||
panic!("TODO handle optional field");
|
||||
}
|
||||
LabelOnly(loc_field_name) => {
|
||||
// Interpret { a, b } as { a : a, b : b }
|
||||
let field_name = Lowercase::from(loc_field_name.value);
|
||||
|
|
|
@ -1190,6 +1190,8 @@ fn canonicalize_field<'a>(
|
|||
)
|
||||
}
|
||||
|
||||
OptionalField(_, _, _) => panic!("invalid in expressions"),
|
||||
|
||||
// A label with no value, e.g. `{ name }` (this is sugar for { name: name })
|
||||
LabelOnly(_) => {
|
||||
panic!("Somehow a LabelOnly record field was not desugared!");
|
||||
|
|
|
@ -295,6 +295,7 @@ fn desugar_field<'a>(
|
|||
spaces,
|
||||
desugar_expr(arena, loc_expr),
|
||||
),
|
||||
OptionalField(_, _, _) => panic!("invalid in expressions"),
|
||||
LabelOnly(loc_str) => {
|
||||
// Desugar { x } into { x: x }
|
||||
let loc_expr = Located {
|
||||
|
|
|
@ -202,6 +202,22 @@ pub fn fmt_field<'a>(
|
|||
buf.push(' ');
|
||||
fmt_expr(buf, &value.value, indent, apply_needs_parens, true);
|
||||
}
|
||||
OptionalField(name, spaces, value) => {
|
||||
if is_multiline {
|
||||
newline(buf, indent);
|
||||
}
|
||||
|
||||
buf.push_str(name.value);
|
||||
buf.push('?');
|
||||
|
||||
if !spaces.is_empty() {
|
||||
fmt_spaces(buf, spaces.iter(), indent);
|
||||
}
|
||||
|
||||
buf.push(':');
|
||||
buf.push(' ');
|
||||
fmt_expr(buf, &value.value, indent, apply_needs_parens, true);
|
||||
}
|
||||
LabelOnly(name) => {
|
||||
if is_multiline {
|
||||
newline(buf, indent);
|
||||
|
@ -346,6 +362,7 @@ pub fn is_multiline_field<'a, Val>(field: &'a AssignedField<'a, Val>) -> bool {
|
|||
|
||||
match field {
|
||||
LabeledValue(_, spaces, _) => !spaces.is_empty(),
|
||||
OptionalField(_, spaces, _) => !spaces.is_empty(),
|
||||
LabelOnly(_) => false,
|
||||
AssignedField::SpaceBefore(_, _) | AssignedField::SpaceAfter(_, _) => true,
|
||||
Malformed(text) => text.chars().any(|c| c == '\n'),
|
||||
|
|
|
@ -240,6 +240,9 @@ pub enum AssignedField<'a, Val> {
|
|||
// Both a label and a value, e.g. `{ name: "blah" }`
|
||||
LabeledValue(Loc<&'a str>, &'a [CommentOrNewline<'a>], &'a Loc<Val>),
|
||||
|
||||
// An optional field, e.g. `{ name? : String }`. Only for types
|
||||
OptionalField(Loc<&'a str>, &'a [CommentOrNewline<'a>], &'a Loc<Val>),
|
||||
|
||||
// A label with no value, e.g. `{ name }` (this is sugar for { name: name })
|
||||
LabelOnly(Loc<&'a str>),
|
||||
|
||||
|
|
|
@ -353,6 +353,7 @@ pub fn assigned_expr_field_to_pattern<'a>(
|
|||
)
|
||||
}
|
||||
}
|
||||
AssignedField::OptionalField(_, _, _) => panic!("invalid in literals"),
|
||||
AssignedField::LabelOnly(name) => Pattern::Identifier(name.value),
|
||||
AssignedField::SpaceBefore(nested, spaces) => Pattern::SpaceBefore(
|
||||
arena.alloc(assigned_expr_field_to_pattern(arena, nested)?),
|
||||
|
@ -393,6 +394,9 @@ pub fn assigned_pattern_field_to_pattern<'a>(
|
|||
)
|
||||
}
|
||||
}
|
||||
AssignedField::OptionalField(_, _, _) => {
|
||||
panic!("invalid as a pattern");
|
||||
}
|
||||
AssignedField::LabelOnly(name) => Located::at(name.region, Pattern::Identifier(name.value)),
|
||||
AssignedField::SpaceBefore(nested, spaces) => {
|
||||
let can_nested = assigned_pattern_field_to_pattern(arena, nested, backup_region)?;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue