mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-03 19:58:18 +00:00
Merge branch 'main' into store-all-space-between-annotation-body
This commit is contained in:
commit
125990855f
306 changed files with 12149 additions and 8820 deletions
|
@ -21,6 +21,12 @@ pub struct Spaces<'a, T> {
|
|||
pub after: &'a [CommentOrNewline<'a>],
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub struct SpacesBefore<'a, T> {
|
||||
pub before: &'a [CommentOrNewline<'a>],
|
||||
pub item: T,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
pub enum Spaced<'a, T> {
|
||||
Item(T),
|
||||
|
@ -1204,6 +1210,21 @@ impl<'a> Defs<'a> {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn loc_defs<'b>(
|
||||
&'b self,
|
||||
) -> impl Iterator<Item = Result<Loc<TypeDef<'a>>, Loc<ValueDef<'a>>>> + 'b {
|
||||
self.tags
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, tag)| match tag.split() {
|
||||
Ok(type_index) => Ok(Loc::at(self.regions[i], self.type_defs[type_index.index()])),
|
||||
Err(value_index) => Err(Loc::at(
|
||||
self.regions[i],
|
||||
self.value_defs[value_index.index()],
|
||||
)),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn list_value_defs(&self) -> impl Iterator<Item = (usize, &ValueDef<'a>)> {
|
||||
self.tags
|
||||
.iter()
|
||||
|
@ -2072,6 +2093,28 @@ pub trait Spaceable<'a> {
|
|||
fn before(&'a self, _: &'a [CommentOrNewline<'a>]) -> Self;
|
||||
fn after(&'a self, _: &'a [CommentOrNewline<'a>]) -> Self;
|
||||
|
||||
fn maybe_before(self, arena: &'a Bump, spaces: &'a [CommentOrNewline<'a>]) -> Self
|
||||
where
|
||||
Self: Sized + 'a,
|
||||
{
|
||||
if spaces.is_empty() {
|
||||
self
|
||||
} else {
|
||||
arena.alloc(self).before(spaces)
|
||||
}
|
||||
}
|
||||
|
||||
fn maybe_after(self, arena: &'a Bump, spaces: &'a [CommentOrNewline<'a>]) -> Self
|
||||
where
|
||||
Self: Sized + 'a,
|
||||
{
|
||||
if spaces.is_empty() {
|
||||
self
|
||||
} else {
|
||||
arena.alloc(self).after(spaces)
|
||||
}
|
||||
}
|
||||
|
||||
fn with_spaces_before(&'a self, spaces: &'a [CommentOrNewline<'a>], region: Region) -> Loc<Self>
|
||||
where
|
||||
Self: Sized,
|
||||
|
|
|
@ -333,7 +333,7 @@ where
|
|||
let start = state.pos();
|
||||
match spaces().parse(arena, state, min_indent) {
|
||||
Ok((progress, spaces, state)) => {
|
||||
if progress == NoProgress || state.column() >= min_indent {
|
||||
if spaces.is_empty() || state.column() >= min_indent {
|
||||
Ok((progress, spaces, state))
|
||||
} else {
|
||||
Err((progress, indent_problem(start)))
|
||||
|
@ -344,6 +344,60 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
pub fn require_newline_or_eof<'a, E>(newline_problem: fn(Position) -> E) -> impl Parser<'a, (), E>
|
||||
where
|
||||
E: 'a + SpaceProblem,
|
||||
{
|
||||
move |arena: &'a Bump, state: State<'a>, min_indent| {
|
||||
// TODO: we can do this more efficiently by stopping as soon as we see a '#' or a newline
|
||||
let (_, res, _) = space0_e(newline_problem).parse(arena, state.clone(), min_indent)?;
|
||||
|
||||
if !res.is_empty() || state.has_reached_end() {
|
||||
Ok((NoProgress, (), state))
|
||||
} else {
|
||||
Err((NoProgress, newline_problem(state.pos())))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn loc_space0_e<'a, E>(
|
||||
indent_problem: fn(Position) -> E,
|
||||
) -> impl Parser<'a, Loc<&'a [CommentOrNewline<'a>]>, E>
|
||||
where
|
||||
E: 'a + SpaceProblem,
|
||||
{
|
||||
move |arena, state: State<'a>, min_indent: u32| {
|
||||
let mut newlines = Vec::new_in(arena);
|
||||
let start = state.pos();
|
||||
let mut comment_start = None;
|
||||
let mut comment_end = None;
|
||||
|
||||
let res = consume_spaces(state, |start, space, end| {
|
||||
newlines.push(space);
|
||||
if !matches!(space, CommentOrNewline::Newline) {
|
||||
if comment_start.is_none() {
|
||||
comment_start = Some(start);
|
||||
}
|
||||
comment_end = Some(end);
|
||||
}
|
||||
});
|
||||
|
||||
match res {
|
||||
Ok((progress, state)) => {
|
||||
if newlines.is_empty() || state.column() >= min_indent {
|
||||
let start = comment_start.unwrap_or(state.pos());
|
||||
let end = comment_end.unwrap_or(state.pos());
|
||||
let region = Region::new(start, end);
|
||||
Ok((progress, Loc::at(region, newlines.into_bump_slice()), state))
|
||||
} else {
|
||||
Err((progress, indent_problem(start)))
|
||||
}
|
||||
}
|
||||
Err((progress, err)) => Err((progress, err)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn begins_with_crlf(bytes: &[u8]) -> bool {
|
||||
bytes.len() >= 2 && bytes[0] == b'\r' && bytes[1] == b'\n'
|
||||
}
|
||||
|
@ -387,7 +441,7 @@ where
|
|||
F: FnMut(Position, CommentOrNewline<'a>, Position),
|
||||
{
|
||||
let mut progress = NoProgress;
|
||||
let mut found_newline = false;
|
||||
let mut found_newline = state.is_at_start_of_file();
|
||||
loop {
|
||||
let whitespace = fast_eat_whitespace(state.bytes());
|
||||
if whitespace > 0 {
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -17,6 +17,7 @@ pub mod module;
|
|||
pub mod number_literal;
|
||||
pub mod pattern;
|
||||
pub mod problems;
|
||||
pub mod remove_spaces;
|
||||
pub mod src64;
|
||||
pub mod state;
|
||||
pub mod string_literal;
|
||||
|
|
|
@ -330,6 +330,7 @@ pub enum EExpr<'a> {
|
|||
Start(Position),
|
||||
End(Position),
|
||||
BadExprEnd(Position),
|
||||
StmtAfterExpr(Position),
|
||||
Space(BadInputError, Position),
|
||||
|
||||
Dot(Position),
|
||||
|
@ -355,6 +356,8 @@ pub enum EExpr<'a> {
|
|||
QualifiedTag(Position),
|
||||
BackpassComma(Position),
|
||||
BackpassArrow(Position),
|
||||
BackpassContinue(Position),
|
||||
DbgContinue(Position),
|
||||
|
||||
When(EWhen<'a>, Position),
|
||||
If(EIf<'a>, Position),
|
||||
|
@ -383,6 +386,7 @@ pub enum EExpr<'a> {
|
|||
IndentEnd(Position),
|
||||
|
||||
UnexpectedComma(Position),
|
||||
UnexpectedTopLevelExpr(Position),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
|
@ -851,8 +855,9 @@ where
|
|||
let cur_indent = INDENT.with(|i| *i.borrow());
|
||||
|
||||
println!(
|
||||
"{:<5?}: {}{:<50}",
|
||||
"{:<5?}:{:<2} {}{:<50}",
|
||||
state.pos(),
|
||||
min_indent,
|
||||
&indent_text[..cur_indent * 2],
|
||||
self.message
|
||||
);
|
||||
|
@ -868,8 +873,9 @@ where
|
|||
};
|
||||
|
||||
println!(
|
||||
"{:<5?}: {}{:<50} {:<15} {:?}",
|
||||
"{:<5?}:{:<2} {}{:<50} {:<15} {:?}",
|
||||
state.pos(),
|
||||
min_indent,
|
||||
&indent_text[..cur_indent * 2],
|
||||
self.message,
|
||||
format!("{:?}", progress),
|
||||
|
|
1749
crates/compiler/parse/src/remove_spaces.rs
Normal file
1749
crates/compiler/parse/src/remove_spaces.rs
Normal file
File diff suppressed because it is too large
Load diff
|
@ -129,6 +129,10 @@ impl<'a> State<'a> {
|
|||
pub fn len_region(&self, length: u32) -> Region {
|
||||
Region::new(self.pos(), self.pos().bump_column(length))
|
||||
}
|
||||
|
||||
pub fn is_at_start_of_file(&self) -> bool {
|
||||
self.offset == 0
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> fmt::Debug for State<'a> {
|
||||
|
|
|
@ -22,7 +22,7 @@ pub fn parse_loc_with<'a>(
|
|||
arena: &'a Bump,
|
||||
input: &'a str,
|
||||
) -> Result<Loc<ast::Expr<'a>>, SourceError<'a, SyntaxError<'a>>> {
|
||||
let state = State::new(input.trim().as_bytes());
|
||||
let state = State::new(input.as_bytes());
|
||||
|
||||
match crate::expr::test_parse_expr(0, arena, state.clone()) {
|
||||
Ok(loc_expr) => Ok(loc_expr),
|
||||
|
@ -31,7 +31,7 @@ pub fn parse_loc_with<'a>(
|
|||
}
|
||||
|
||||
pub fn parse_defs_with<'a>(arena: &'a Bump, input: &'a str) -> Result<Defs<'a>, SyntaxError<'a>> {
|
||||
let state = State::new(input.trim().as_bytes());
|
||||
let state = State::new(input.as_bytes());
|
||||
|
||||
parse_module_defs(arena, state, Defs::default())
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ pub fn parse_header_with<'a>(
|
|||
arena: &'a Bump,
|
||||
input: &'a str,
|
||||
) -> Result<ast::Module<'a>, SyntaxError<'a>> {
|
||||
let state = State::new(input.trim().as_bytes());
|
||||
let state = State::new(input.as_bytes());
|
||||
|
||||
match crate::module::parse_header(arena, state.clone()) {
|
||||
Ok((header, _)) => Ok(header),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue