add OptionalField constructor

This commit is contained in:
Folkert 2019-12-29 22:16:19 +01:00
parent 1b4f7ccfa5
commit c4971675eb
6 changed files with 30 additions and 0 deletions

View file

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

View file

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

View file

@ -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 {

View file

@ -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'),

View file

@ -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>),

View file

@ -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)?;