mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 14:54:47 +00:00
parse defs with the new approach
This commit is contained in:
parent
d174cb72ae
commit
fa9ac912a0
3 changed files with 76 additions and 49 deletions
|
@ -7,9 +7,8 @@ extern crate roc_fmt;
|
|||
mod test_fmt {
|
||||
use bumpalo::Bump;
|
||||
use roc_fmt::annotation::{Formattable, Newlines, Parens};
|
||||
use roc_fmt::def::{fmt_type_def, fmt_value_def};
|
||||
use roc_fmt::def::fmt_toplevel_defs;
|
||||
use roc_fmt::module::fmt_module;
|
||||
use roc_fmt::spaces::fmt_spaces;
|
||||
use roc_fmt::Buf;
|
||||
use roc_parse::ast::Module;
|
||||
use roc_parse::module::{self, module_defs};
|
||||
|
@ -89,7 +88,7 @@ mod test_fmt {
|
|||
|
||||
match module_defs().parse(arena, state) {
|
||||
Ok((_, loc_defs, _)) => {
|
||||
fmt_toplevel_defs(buf, loc_defs, 0);
|
||||
fmt_toplevel_defs(buf, &loc_defs, 0);
|
||||
}
|
||||
Err(error) => panic!(
|
||||
r"Unexpected parse failure when parsing this for defs formatting:\n\n{:?}\n\nParse error was:\n\n{:?}\n\n",
|
||||
|
|
|
@ -346,7 +346,7 @@ pub struct Defs<'a> {
|
|||
}
|
||||
|
||||
impl<'a> Defs<'a> {
|
||||
pub fn defs<I>(&self) -> impl Iterator<Item = Result<&TypeDef<'a>, &ValueDef<'a>>> {
|
||||
pub fn defs(&self) -> impl Iterator<Item = Result<&TypeDef<'a>, &ValueDef<'a>>> {
|
||||
self.tags.iter().map(|tag| match tag.split() {
|
||||
Ok(type_index) => Ok(&self.type_defs[type_index.index()]),
|
||||
Err(value_index) => Err(&self.value_defs[value_index.index()]),
|
||||
|
|
|
@ -17,6 +17,7 @@ use crate::state::State;
|
|||
use crate::type_annotation;
|
||||
use bumpalo::collections::Vec;
|
||||
use bumpalo::Bump;
|
||||
use roc_collections::soa::Slice;
|
||||
use roc_module::called_via::{BinOp, CalledVia, UnaryOp};
|
||||
use roc_region::all::{Loc, Position, Region};
|
||||
|
||||
|
@ -924,78 +925,94 @@ fn parse_toplevel_defs_end<'a>(
|
|||
let region = Region::span_across(&loc_pattern.region, &loc_def_expr.region);
|
||||
|
||||
if spaces_before_current.len() <= 1 {
|
||||
let comment = match spaces_before_current.get(0) {
|
||||
Some(CommentOrNewline::LineComment(s)) => Some(*s),
|
||||
Some(CommentOrNewline::DocComment(s)) => Some(*s),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
match defs.last() {
|
||||
Some((
|
||||
before_ann_spaces,
|
||||
Def::Value(ValueDef::Annotation(ann_pattern, ann_type)),
|
||||
)) => {
|
||||
return append_body_definition_help(
|
||||
arena,
|
||||
defs,
|
||||
Some(Err(ValueDef::Annotation(ann_pattern, ann_type))) => {
|
||||
// join this body with the preceding annotation
|
||||
|
||||
let value_def = ValueDef::AnnotatedBody {
|
||||
ann_pattern: arena.alloc(*ann_pattern),
|
||||
ann_type: arena.alloc(*ann_type),
|
||||
comment,
|
||||
body_pattern: arena.alloc(loc_pattern),
|
||||
body_expr: &*arena.alloc(loc_def_expr),
|
||||
};
|
||||
|
||||
let region = Region::span_across(&ann_pattern.region, ®ion);
|
||||
|
||||
defs.push_value_def(
|
||||
value_def,
|
||||
region,
|
||||
before_ann_spaces,
|
||||
spaces_before_current,
|
||||
loc_pattern,
|
||||
loc_def_expr,
|
||||
ann_pattern,
|
||||
ann_type,
|
||||
);
|
||||
&[],
|
||||
)
|
||||
}
|
||||
Some((
|
||||
before_ann_spaces,
|
||||
Def::Type(TypeDef::Alias {
|
||||
Some(Ok(TypeDef::Alias {
|
||||
header,
|
||||
ann: ann_type,
|
||||
}),
|
||||
)) => {
|
||||
})) => {
|
||||
// This is a case like
|
||||
// UserId x : [UserId Int]
|
||||
// UserId x = UserId 42
|
||||
// We optimistically parsed the first line as an alias; we now turn it
|
||||
// into an annotation.
|
||||
|
||||
let loc_name =
|
||||
arena.alloc(header.name.map(|x| Pattern::Tag(x)));
|
||||
let ann_pattern = Pattern::Apply(loc_name, header.vars);
|
||||
|
||||
let vars_region =
|
||||
Region::across_all(header.vars.iter().map(|v| &v.region));
|
||||
let region_ann_pattern =
|
||||
Region::span_across(&loc_name.region, &vars_region);
|
||||
let loc_ann_pattern = Loc::at(region_ann_pattern, ann_pattern);
|
||||
|
||||
return append_body_definition_help(
|
||||
arena,
|
||||
defs,
|
||||
let value_def = ValueDef::AnnotatedBody {
|
||||
ann_pattern: arena.alloc(loc_ann_pattern),
|
||||
ann_type: arena.alloc(*ann_type),
|
||||
comment,
|
||||
body_pattern: arena.alloc(loc_pattern),
|
||||
body_expr: &*arena.alloc(loc_def_expr),
|
||||
};
|
||||
|
||||
let region = Region::span_across(&header.name.region, ®ion);
|
||||
|
||||
defs.push_value_def(
|
||||
value_def,
|
||||
region,
|
||||
before_ann_spaces,
|
||||
spaces_before_current,
|
||||
loc_pattern,
|
||||
loc_def_expr,
|
||||
arena.alloc(loc_ann_pattern),
|
||||
ann_type,
|
||||
);
|
||||
&[],
|
||||
)
|
||||
}
|
||||
_ => {
|
||||
defs.extend(last);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// the previous and current def can't be joined up
|
||||
let mut loc_def = Loc::at(
|
||||
region,
|
||||
Def::Value(ValueDef::Body(
|
||||
let value_def = ValueDef::Body(
|
||||
arena.alloc(loc_pattern),
|
||||
&*arena.alloc(loc_def_expr),
|
||||
)),
|
||||
);
|
||||
|
||||
if !spaces_before_current.is_empty() {
|
||||
loc_def = arena
|
||||
.alloc(loc_def.value)
|
||||
.with_spaces_before(spaces_before_current, loc_def.region);
|
||||
defs.push_value_def(
|
||||
value_def,
|
||||
region,
|
||||
spaces_before_current,
|
||||
&[],
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// the previous and current def can't be joined up
|
||||
let value_def = ValueDef::Body(
|
||||
arena.alloc(loc_pattern),
|
||||
&*arena.alloc(loc_def_expr),
|
||||
);
|
||||
|
||||
defs.push(arena.alloc(loc_def));
|
||||
defs.push_value_def(value_def, region, spaces_before_current, &[])
|
||||
}
|
||||
};
|
||||
|
||||
parse_toplevel_defs_end(options, column, defs, arena, state)
|
||||
|
@ -2290,12 +2307,23 @@ pub fn toplevel_defs<'a>(min_indent: u32) -> impl Parser<'a, Defs<'a>, EExpr<'a>
|
|||
|
||||
let output = Defs::default();
|
||||
|
||||
let (_, output, state) =
|
||||
let (_, mut output, state) =
|
||||
parse_toplevel_defs_end(options, start_column, output, arena, state)?;
|
||||
|
||||
let (_, final_space, state) =
|
||||
space0_e(start_column, EExpr::IndentEnd).parse(arena, state)?;
|
||||
|
||||
// add surrounding whitespace
|
||||
let before = Slice::extend_new(&mut output.spaces, initial_space.iter().copied());
|
||||
let after = Slice::extend_new(&mut output.spaces, final_space.iter().copied());
|
||||
|
||||
debug_assert!(output.space_before[0].is_empty());
|
||||
output.space_before[0] = before;
|
||||
|
||||
let last = output.tags.len() - 1;
|
||||
debug_assert!(output.space_after[last].is_empty() || after.is_empty());
|
||||
output.space_after[last] = after;
|
||||
|
||||
Ok((MadeProgress, output, state))
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue