mirror of
https://github.com/roc-lang/roc.git
synced 2024-09-22 08:17:40 +03:00
Support parsing multiple abilities in a clause
This commit is contained in:
parent
bdc565762b
commit
548a235c25
@ -450,7 +450,8 @@ pub fn find_type_def_symbols(
|
||||
stack.push(&annotation.value);
|
||||
|
||||
for has_clause in clauses.iter() {
|
||||
stack.push(&has_clause.value.ability.value);
|
||||
// TODO(abilities)
|
||||
stack.push(&has_clause.value.abilities[0].value);
|
||||
}
|
||||
}
|
||||
Inferred | Wildcard | Malformed(_) => {}
|
||||
@ -920,7 +921,7 @@ fn canonicalize_has_clause(
|
||||
) -> Result<(), Type> {
|
||||
let Loc {
|
||||
region,
|
||||
value: roc_parse::ast::HasClause { var, ability },
|
||||
value: roc_parse::ast::HasClause { var, abilities },
|
||||
} = clause;
|
||||
let region = *region;
|
||||
|
||||
@ -931,6 +932,8 @@ fn canonicalize_has_clause(
|
||||
);
|
||||
let var_name = Lowercase::from(var_name);
|
||||
|
||||
// TODO(abilities)
|
||||
let ability = abilities[0];
|
||||
let ability = match ability.value {
|
||||
TypeAnnotation::Apply(module_name, ident, _type_arguments) => {
|
||||
let symbol = make_apply_symbol(env, ability.region, scope, module_name, ident)?;
|
||||
|
@ -546,7 +546,8 @@ impl<'a> Formattable for Tag<'a> {
|
||||
|
||||
impl<'a> Formattable for HasClause<'a> {
|
||||
fn is_multiline(&self) -> bool {
|
||||
self.ability.is_multiline()
|
||||
// TODO(abilities)
|
||||
self.abilities[0].is_multiline()
|
||||
}
|
||||
|
||||
fn format_with_options<'buf>(
|
||||
@ -560,8 +561,8 @@ impl<'a> Formattable for HasClause<'a> {
|
||||
buf.spaces(1);
|
||||
buf.push_str("has");
|
||||
buf.spaces(1);
|
||||
self.ability
|
||||
.format_with_options(buf, parens, newlines, indent);
|
||||
// TODO(abilities)
|
||||
self.abilities[0].format_with_options(buf, parens, newlines, indent);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -795,7 +795,7 @@ impl<'a> RemoveSpaces<'a> for HasClause<'a> {
|
||||
fn remove_spaces(&self, arena: &'a Bump) -> Self {
|
||||
HasClause {
|
||||
var: self.var.remove_spaces(arena),
|
||||
ability: self.ability.remove_spaces(arena),
|
||||
abilities: self.abilities.remove_spaces(arena),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -394,10 +394,11 @@ fn ability_member_type_to_docs(
|
||||
let has_clauses = has_clauses
|
||||
.iter()
|
||||
.map(|hc| {
|
||||
let ast::HasClause { var, ability } = hc.value;
|
||||
let ast::HasClause { var, abilities } = hc.value;
|
||||
(
|
||||
var.value.extract_spaces().item.to_string(),
|
||||
type_to_docs(false, ability.value),
|
||||
// TODO(abilities)
|
||||
type_to_docs(false, abilities[0].value),
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
|
@ -439,7 +439,7 @@ pub type AbilityName<'a> = Loc<TypeAnnotation<'a>>;
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct HasClause<'a> {
|
||||
pub var: Loc<Spaced<'a, &'a str>>,
|
||||
pub ability: AbilityName<'a>,
|
||||
pub abilities: &'a [AbilityName<'a>],
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
|
@ -2,7 +2,9 @@ use crate::ast::{
|
||||
AssignedField, CommentOrNewline, HasAbilities, HasAbility, HasClause, HasImpls, Pattern,
|
||||
Spaced, Tag, TypeAnnotation, TypeHeader,
|
||||
};
|
||||
use crate::blankspace::{space0_around_ee, space0_before_e, space0_e};
|
||||
use crate::blankspace::{
|
||||
space0_around_ee, space0_before_e, space0_before_optional_after, space0_e,
|
||||
};
|
||||
use crate::expr::record_value_field;
|
||||
use crate::ident::lowercase_ident;
|
||||
use crate::keyword;
|
||||
@ -410,6 +412,37 @@ fn loc_applied_args_e<'a>(
|
||||
zero_or_more!(loc_applied_arg(min_indent, stop_at_surface_has))
|
||||
}
|
||||
|
||||
// Hash & Eq & ...
|
||||
fn ability_chain<'a>(
|
||||
min_indent: u32,
|
||||
) -> impl Parser<'a, Vec<'a, Loc<TypeAnnotation<'a>>>, EType<'a>> {
|
||||
map!(
|
||||
and!(
|
||||
space0_before_optional_after(
|
||||
specialize(EType::TApply, loc!(parse_concrete_type)),
|
||||
min_indent,
|
||||
EType::TIndentStart,
|
||||
EType::TIndentEnd,
|
||||
),
|
||||
zero_or_more!(skip_first!(
|
||||
word1(b'&', EType::THasClause),
|
||||
space0_before_e(
|
||||
specialize(EType::TApply, loc!(parse_concrete_type)),
|
||||
min_indent,
|
||||
EType::TIndentStart,
|
||||
)
|
||||
))
|
||||
),
|
||||
|(first_ability, mut other_abilities): (
|
||||
Loc<TypeAnnotation<'a>>,
|
||||
Vec<'a, Loc<TypeAnnotation<'a>>>
|
||||
)| {
|
||||
other_abilities.push(first_ability);
|
||||
other_abilities
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
fn has_clause<'a>(min_indent: u32) -> impl Parser<'a, Loc<HasClause<'a>>, EType<'a>> {
|
||||
map!(
|
||||
// Suppose we are trying to parse "a has Hash"
|
||||
@ -427,20 +460,22 @@ fn has_clause<'a>(min_indent: u32) -> impl Parser<'a, Loc<HasClause<'a>>, EType<
|
||||
then(
|
||||
// Parse "has"; we don't care about this keyword
|
||||
word3(b'h', b'a', b's', EType::THasClause),
|
||||
// Parse "Hash"; this may be qualified from another module like "Hash.Hash"
|
||||
// Parse "Hash & ..."; this may be qualified from another module like "Hash.Hash"
|
||||
|arena, state, _progress, _output| {
|
||||
space0_before_e(
|
||||
specialize(EType::TApply, loc!(parse_concrete_type)),
|
||||
state.column() + 1,
|
||||
EType::TIndentStart,
|
||||
)
|
||||
.parse(arena, state)
|
||||
ability_chain(state.column() + 1).parse(arena, state)
|
||||
}
|
||||
)
|
||||
),
|
||||
|(var, ability): (Loc<Spaced<'a, &'a str>>, Loc<TypeAnnotation<'a>>)| {
|
||||
let region = Region::span_across(&var.region, &ability.region);
|
||||
let has_clause = HasClause { var, ability };
|
||||
|(var, abilities): (Loc<Spaced<'a, &'a str>>, Vec<'a, Loc<TypeAnnotation<'a>>>)| {
|
||||
let abilities_region = Region::span_across(
|
||||
&abilities.first().unwrap().region,
|
||||
&abilities.last().unwrap().region,
|
||||
);
|
||||
let region = Region::span_across(&var.region, &abilities_region);
|
||||
let has_clause = HasClause {
|
||||
var,
|
||||
abilities: abilities.into_bump_slice(),
|
||||
};
|
||||
Loc::at(region, has_clause)
|
||||
}
|
||||
)
|
||||
|
@ -39,11 +39,13 @@ Defs(
|
||||
[
|
||||
@27-37 HasClause {
|
||||
var: @27-28 "a",
|
||||
ability: @33-37 Apply(
|
||||
"",
|
||||
"Hash",
|
||||
[],
|
||||
),
|
||||
abilities: [
|
||||
@33-37 Apply(
|
||||
"",
|
||||
"Hash",
|
||||
[],
|
||||
),
|
||||
],
|
||||
},
|
||||
],
|
||||
),
|
||||
|
@ -45,11 +45,13 @@ Defs(
|
||||
[
|
||||
@24-33 HasClause {
|
||||
var: @24-25 "a",
|
||||
ability: @30-33 Apply(
|
||||
"",
|
||||
"Ab1",
|
||||
[],
|
||||
),
|
||||
abilities: [
|
||||
@30-33 Apply(
|
||||
"",
|
||||
"Ab1",
|
||||
[],
|
||||
),
|
||||
],
|
||||
},
|
||||
],
|
||||
),
|
||||
@ -80,11 +82,13 @@ Defs(
|
||||
[
|
||||
@59-68 HasClause {
|
||||
var: @59-60 "a",
|
||||
ability: @65-68 Apply(
|
||||
"",
|
||||
"Ab2",
|
||||
[],
|
||||
),
|
||||
abilities: [
|
||||
@65-68 Apply(
|
||||
"",
|
||||
"Ab2",
|
||||
[],
|
||||
),
|
||||
],
|
||||
},
|
||||
],
|
||||
),
|
||||
|
@ -114,11 +114,13 @@ Defs(
|
||||
[
|
||||
@33-44 HasClause {
|
||||
var: @33-34 "a",
|
||||
ability: @39-44 Apply(
|
||||
"",
|
||||
"Other",
|
||||
[],
|
||||
),
|
||||
abilities: [
|
||||
@39-44 Apply(
|
||||
"",
|
||||
"Other",
|
||||
[],
|
||||
),
|
||||
],
|
||||
},
|
||||
],
|
||||
),
|
||||
@ -157,11 +159,13 @@ Defs(
|
||||
[
|
||||
@70-81 HasClause {
|
||||
var: @70-71 "a",
|
||||
ability: @76-81 Apply(
|
||||
"",
|
||||
"Other",
|
||||
[],
|
||||
),
|
||||
abilities: [
|
||||
@76-81 Apply(
|
||||
"",
|
||||
"Other",
|
||||
[],
|
||||
),
|
||||
],
|
||||
},
|
||||
],
|
||||
),
|
||||
@ -394,11 +398,13 @@ Defs(
|
||||
[
|
||||
@260-271 HasClause {
|
||||
var: @260-261 "a",
|
||||
ability: @266-271 Apply(
|
||||
"",
|
||||
"Other",
|
||||
[],
|
||||
),
|
||||
abilities: [
|
||||
@266-271 Apply(
|
||||
"",
|
||||
"Other",
|
||||
[],
|
||||
),
|
||||
],
|
||||
},
|
||||
],
|
||||
),
|
||||
|
@ -40,11 +40,13 @@ Defs(
|
||||
[
|
||||
@20-27 HasClause {
|
||||
var: @20-21 "a",
|
||||
ability: @26-27 Apply(
|
||||
"",
|
||||
"A",
|
||||
[],
|
||||
),
|
||||
abilities: [
|
||||
@26-27 Apply(
|
||||
"",
|
||||
"A",
|
||||
[],
|
||||
),
|
||||
],
|
||||
},
|
||||
],
|
||||
),
|
||||
|
@ -40,27 +40,33 @@ Defs(
|
||||
[
|
||||
@20-27 HasClause {
|
||||
var: @20-21 "a",
|
||||
ability: @26-27 Apply(
|
||||
"",
|
||||
"A",
|
||||
[],
|
||||
),
|
||||
abilities: [
|
||||
@26-27 Apply(
|
||||
"",
|
||||
"A",
|
||||
[],
|
||||
),
|
||||
],
|
||||
},
|
||||
@29-37 HasClause {
|
||||
var: @29-30 "b",
|
||||
ability: @35-37 Apply(
|
||||
"",
|
||||
"Eq",
|
||||
[],
|
||||
),
|
||||
abilities: [
|
||||
@35-37 Apply(
|
||||
"",
|
||||
"Eq",
|
||||
[],
|
||||
),
|
||||
],
|
||||
},
|
||||
@39-48 HasClause {
|
||||
var: @39-40 "c",
|
||||
ability: @45-48 Apply(
|
||||
"",
|
||||
"Ord",
|
||||
[],
|
||||
),
|
||||
abilities: [
|
||||
@45-48 Apply(
|
||||
"",
|
||||
"Ord",
|
||||
[],
|
||||
),
|
||||
],
|
||||
},
|
||||
],
|
||||
),
|
||||
|
@ -45,11 +45,13 @@ Defs(
|
||||
[
|
||||
@24-34 HasClause {
|
||||
var: @24-25 "a",
|
||||
ability: @30-34 Apply(
|
||||
"",
|
||||
"Hash",
|
||||
[],
|
||||
),
|
||||
abilities: [
|
||||
@30-34 Apply(
|
||||
"",
|
||||
"Hash",
|
||||
[],
|
||||
),
|
||||
],
|
||||
},
|
||||
@42-50 HasClause {
|
||||
var: @42-43 SpaceBefore(
|
||||
@ -58,11 +60,13 @@ Defs(
|
||||
Newline,
|
||||
],
|
||||
),
|
||||
ability: @48-50 Apply(
|
||||
"",
|
||||
"Eq",
|
||||
[],
|
||||
),
|
||||
abilities: [
|
||||
@48-50 Apply(
|
||||
"",
|
||||
"Eq",
|
||||
[],
|
||||
),
|
||||
],
|
||||
},
|
||||
@58-67 HasClause {
|
||||
var: @58-59 SpaceBefore(
|
||||
@ -71,11 +75,13 @@ Defs(
|
||||
Newline,
|
||||
],
|
||||
),
|
||||
ability: @64-67 Apply(
|
||||
"",
|
||||
"Ord",
|
||||
[],
|
||||
),
|
||||
abilities: [
|
||||
@64-67 Apply(
|
||||
"",
|
||||
"Ord",
|
||||
[],
|
||||
),
|
||||
],
|
||||
},
|
||||
],
|
||||
),
|
||||
|
@ -26,11 +26,13 @@ Defs(
|
||||
[
|
||||
@8-15 HasClause {
|
||||
var: @8-9 "a",
|
||||
ability: @14-15 Apply(
|
||||
"",
|
||||
"A",
|
||||
[],
|
||||
),
|
||||
abilities: [
|
||||
@14-15 Apply(
|
||||
"",
|
||||
"A",
|
||||
[],
|
||||
),
|
||||
],
|
||||
},
|
||||
],
|
||||
),
|
||||
|
@ -40,11 +40,13 @@ Defs(
|
||||
[
|
||||
@19-29 HasClause {
|
||||
var: @19-20 "a",
|
||||
ability: @25-29 Apply(
|
||||
"",
|
||||
"Hash",
|
||||
[],
|
||||
),
|
||||
abilities: [
|
||||
@25-29 Apply(
|
||||
"",
|
||||
"Hash",
|
||||
[],
|
||||
),
|
||||
],
|
||||
},
|
||||
],
|
||||
),
|
||||
|
Loading…
Reference in New Issue
Block a user