parse defs with the new approach

This commit is contained in:
Folkert 2022-05-26 14:14:39 +02:00
parent d174cb72ae
commit fa9ac912a0
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C
3 changed files with 76 additions and 49 deletions

View file

@ -7,9 +7,8 @@ extern crate roc_fmt;
mod test_fmt { mod test_fmt {
use bumpalo::Bump; use bumpalo::Bump;
use roc_fmt::annotation::{Formattable, Newlines, Parens}; 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::module::fmt_module;
use roc_fmt::spaces::fmt_spaces;
use roc_fmt::Buf; use roc_fmt::Buf;
use roc_parse::ast::Module; use roc_parse::ast::Module;
use roc_parse::module::{self, module_defs}; use roc_parse::module::{self, module_defs};
@ -89,7 +88,7 @@ mod test_fmt {
match module_defs().parse(arena, state) { match module_defs().parse(arena, state) {
Ok((_, loc_defs, _)) => { Ok((_, loc_defs, _)) => {
fmt_toplevel_defs(buf, loc_defs, 0); fmt_toplevel_defs(buf, &loc_defs, 0);
} }
Err(error) => panic!( Err(error) => panic!(
r"Unexpected parse failure when parsing this for defs formatting:\n\n{:?}\n\nParse error was:\n\n{:?}\n\n", r"Unexpected parse failure when parsing this for defs formatting:\n\n{:?}\n\nParse error was:\n\n{:?}\n\n",

View file

@ -346,7 +346,7 @@ pub struct Defs<'a> {
} }
impl<'a> 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() { self.tags.iter().map(|tag| match tag.split() {
Ok(type_index) => Ok(&self.type_defs[type_index.index()]), Ok(type_index) => Ok(&self.type_defs[type_index.index()]),
Err(value_index) => Err(&self.value_defs[value_index.index()]), Err(value_index) => Err(&self.value_defs[value_index.index()]),

View file

@ -17,6 +17,7 @@ use crate::state::State;
use crate::type_annotation; use crate::type_annotation;
use bumpalo::collections::Vec; use bumpalo::collections::Vec;
use bumpalo::Bump; use bumpalo::Bump;
use roc_collections::soa::Slice;
use roc_module::called_via::{BinOp, CalledVia, UnaryOp}; use roc_module::called_via::{BinOp, CalledVia, UnaryOp};
use roc_region::all::{Loc, Position, Region}; 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); let region = Region::span_across(&loc_pattern.region, &loc_def_expr.region);
if spaces_before_current.len() <= 1 { 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() { match defs.last() {
Some(( Some(Err(ValueDef::Annotation(ann_pattern, ann_type))) => {
before_ann_spaces, // join this body with the preceding annotation
Def::Value(ValueDef::Annotation(ann_pattern, ann_type)),
)) => { let value_def = ValueDef::AnnotatedBody {
return append_body_definition_help( ann_pattern: arena.alloc(*ann_pattern),
arena, ann_type: arena.alloc(*ann_type),
defs, comment,
body_pattern: arena.alloc(loc_pattern),
body_expr: &*arena.alloc(loc_def_expr),
};
let region = Region::span_across(&ann_pattern.region, &region);
defs.push_value_def(
value_def,
region, region,
before_ann_spaces,
spaces_before_current, spaces_before_current,
loc_pattern, &[],
loc_def_expr, )
ann_pattern,
ann_type,
);
} }
Some(( Some(Ok(TypeDef::Alias {
before_ann_spaces, header,
Def::Type(TypeDef::Alias { ann: ann_type,
header, })) => {
ann: ann_type,
}),
)) => {
// This is a case like // This is a case like
// UserId x : [UserId Int] // UserId x : [UserId Int]
// UserId x = UserId 42 // UserId x = UserId 42
// We optimistically parsed the first line as an alias; we now turn it // We optimistically parsed the first line as an alias; we now turn it
// into an annotation. // into an annotation.
let loc_name = let loc_name =
arena.alloc(header.name.map(|x| Pattern::Tag(x))); arena.alloc(header.name.map(|x| Pattern::Tag(x)));
let ann_pattern = Pattern::Apply(loc_name, header.vars); let ann_pattern = Pattern::Apply(loc_name, header.vars);
let vars_region = let vars_region =
Region::across_all(header.vars.iter().map(|v| &v.region)); Region::across_all(header.vars.iter().map(|v| &v.region));
let region_ann_pattern = let region_ann_pattern =
Region::span_across(&loc_name.region, &vars_region); Region::span_across(&loc_name.region, &vars_region);
let loc_ann_pattern = Loc::at(region_ann_pattern, ann_pattern); let loc_ann_pattern = Loc::at(region_ann_pattern, ann_pattern);
return append_body_definition_help( let value_def = ValueDef::AnnotatedBody {
arena, ann_pattern: arena.alloc(loc_ann_pattern),
defs, 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, &region);
defs.push_value_def(
value_def,
region, region,
before_ann_spaces,
spaces_before_current, 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 value_def = ValueDef::Body(
arena.alloc(loc_pattern),
&*arena.alloc(loc_def_expr),
);
defs.push_value_def(
value_def,
region,
spaces_before_current,
&[],
)
} }
} }
} } else {
// the previous and current def can't be joined up
// the previous and current def can't be joined up let value_def = ValueDef::Body(
let mut loc_def = Loc::at(
region,
Def::Value(ValueDef::Body(
arena.alloc(loc_pattern), arena.alloc(loc_pattern),
&*arena.alloc(loc_def_expr), &*arena.alloc(loc_def_expr),
)), );
);
if !spaces_before_current.is_empty() { defs.push_value_def(value_def, region, spaces_before_current, &[])
loc_def = arena
.alloc(loc_def.value)
.with_spaces_before(spaces_before_current, loc_def.region);
} }
defs.push(arena.alloc(loc_def));
}; };
parse_toplevel_defs_end(options, column, defs, arena, state) 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 = Defs::default();
let (_, output, state) = let (_, mut output, state) =
parse_toplevel_defs_end(options, start_column, output, arena, state)?; parse_toplevel_defs_end(options, start_column, output, arena, state)?;
let (_, final_space, state) = let (_, final_space, state) =
space0_e(start_column, EExpr::IndentEnd).parse(arena, 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)) Ok((MadeProgress, output, state))
} }
} }