mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-04 04:08:19 +00:00
Parse module params in import
This commit is contained in:
parent
08825a9e90
commit
e5a09b5de6
19 changed files with 305 additions and 70 deletions
|
@ -133,6 +133,8 @@ fn desugar_value_def<'a>(
|
|||
ModuleImport(roc_parse::ast::ModuleImport {
|
||||
before_name: _,
|
||||
name: _,
|
||||
// TODO: Desugar params
|
||||
params,
|
||||
alias: _,
|
||||
exposed: _,
|
||||
}) => *def,
|
||||
|
|
|
@ -6,8 +6,8 @@ use crate::spaces::{fmt_default_newline, fmt_default_spaces, fmt_spaces, INDENT}
|
|||
use crate::Buf;
|
||||
use roc_parse::ast::{
|
||||
AbilityMember, Defs, Expr, ExtractSpaces, ImportAlias, ImportAsKeyword, ImportExposingKeyword,
|
||||
ImportedModuleName, IngestedFileAnnotation, IngestedFileImport, ModuleImport, Pattern, Spaces,
|
||||
StrLiteral, TypeAnnotation, TypeDef, TypeHeader, ValueDef,
|
||||
ImportedModuleName, IngestedFileAnnotation, IngestedFileImport, ModuleImport,
|
||||
ModuleImportParams, Pattern, Spaces, StrLiteral, TypeAnnotation, TypeDef, TypeHeader, ValueDef,
|
||||
};
|
||||
use roc_parse::header::Keyword;
|
||||
use roc_region::all::Loc;
|
||||
|
@ -192,12 +192,19 @@ impl<'a> Formattable for ModuleImport<'a> {
|
|||
let Self {
|
||||
before_name,
|
||||
name,
|
||||
params,
|
||||
alias,
|
||||
exposed,
|
||||
} = self;
|
||||
|
||||
!before_name.is_empty()
|
||||
|| name.is_multiline()
|
||||
|| match params {
|
||||
Some(ModuleImportParams { before, params }) => {
|
||||
!before.is_empty() || is_collection_multiline(params)
|
||||
}
|
||||
None => false,
|
||||
}
|
||||
|| alias.is_multiline()
|
||||
|| match exposed {
|
||||
Some(a) => a.keyword.is_multiline() || is_collection_multiline(&a.item),
|
||||
|
@ -215,6 +222,7 @@ impl<'a> Formattable for ModuleImport<'a> {
|
|||
let Self {
|
||||
before_name,
|
||||
name,
|
||||
params,
|
||||
alias,
|
||||
exposed,
|
||||
} = self;
|
||||
|
@ -229,6 +237,10 @@ impl<'a> Formattable for ModuleImport<'a> {
|
|||
buf.indent(indent);
|
||||
name.format(buf, indent);
|
||||
|
||||
if let Some(params) = params {
|
||||
// TODO: Format import params
|
||||
}
|
||||
|
||||
if let Some(alias) = alias {
|
||||
alias.format(buf, indent);
|
||||
}
|
||||
|
|
|
@ -6,9 +6,9 @@ use roc_parse::{
|
|||
AbilityImpls, AbilityMember, AssignedField, Collection, CommentOrNewline, Defs, Expr,
|
||||
Header, Implements, ImplementsAbilities, ImplementsAbility, ImplementsClause, ImportAlias,
|
||||
ImportAsKeyword, ImportExposingKeyword, ImportedModuleName, IngestedFileAnnotation,
|
||||
IngestedFileImport, Module, ModuleImport, Pattern, PatternAs, RecordBuilderField, Spaced,
|
||||
Spaces, StrLiteral, StrSegment, Tag, TypeAnnotation, TypeDef, TypeHeader, ValueDef,
|
||||
WhenBranch,
|
||||
IngestedFileImport, Module, ModuleImport, ModuleImportParams, Pattern, PatternAs,
|
||||
RecordBuilderField, Spaced, Spaces, StrLiteral, StrSegment, Tag, TypeAnnotation, TypeDef,
|
||||
TypeHeader, ValueDef, WhenBranch,
|
||||
},
|
||||
header::{
|
||||
AppHeader, ExposedName, HostedHeader, ImportsEntry, KeywordItem, ModuleHeader, ModuleName,
|
||||
|
@ -600,12 +600,22 @@ impl<'a> RemoveSpaces<'a> for ModuleImport<'a> {
|
|||
ModuleImport {
|
||||
before_name: &[],
|
||||
name: self.name.remove_spaces(arena),
|
||||
params: self.params.remove_spaces(arena),
|
||||
alias: self.alias.remove_spaces(arena),
|
||||
exposed: self.exposed.remove_spaces(arena),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> RemoveSpaces<'a> for ModuleImportParams<'a> {
|
||||
fn remove_spaces(&self, arena: &'a Bump) -> Self {
|
||||
ModuleImportParams {
|
||||
before: &[],
|
||||
params: self.params.remove_spaces(arena),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> RemoveSpaces<'a> for IngestedFileImport<'a> {
|
||||
fn remove_spaces(&self, arena: &'a Bump) -> Self {
|
||||
IngestedFileImport {
|
||||
|
|
|
@ -246,6 +246,7 @@ impl<'a> Module<'a> {
|
|||
name,
|
||||
},
|
||||
},
|
||||
params: None,
|
||||
alias: None,
|
||||
exposed: new_exposed,
|
||||
})
|
||||
|
@ -784,43 +785,6 @@ pub enum ValueDef<'a> {
|
|||
}
|
||||
|
||||
impl<'a> ValueDef<'a> {
|
||||
pub fn expr(&self) -> Option<&'a Expr<'a>> {
|
||||
match self {
|
||||
ValueDef::Body(_, body) => Some(&body.value),
|
||||
|
||||
ValueDef::AnnotatedBody {
|
||||
ann_pattern: _,
|
||||
ann_type: _,
|
||||
comment: _,
|
||||
body_pattern: _,
|
||||
body_expr,
|
||||
} => Some(&body_expr.value),
|
||||
|
||||
ValueDef::Dbg {
|
||||
condition,
|
||||
preceding_comment: _,
|
||||
}
|
||||
| ValueDef::Expect {
|
||||
condition,
|
||||
preceding_comment: _,
|
||||
}
|
||||
| ValueDef::ExpectFx {
|
||||
condition,
|
||||
preceding_comment: _,
|
||||
} => Some(&condition.value),
|
||||
|
||||
ValueDef::Annotation(_, _)
|
||||
| ValueDef::ModuleImport(ModuleImport {
|
||||
before_name: _,
|
||||
name: _,
|
||||
alias: _,
|
||||
exposed: _,
|
||||
})
|
||||
| ValueDef::IngestedFileImport(_) => None,
|
||||
ValueDef::Stmt(loc_expr) => Some(&loc_expr.value),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn replace_expr(&mut self, new_expr: &'a Loc<Expr<'a>>) {
|
||||
match self {
|
||||
ValueDef::Body(_, expr) => *expr = new_expr,
|
||||
|
@ -1019,8 +983,47 @@ impl<'a, 'b> Iterator for RecursiveValueDefIter<'a, 'b> {
|
|||
let def = &self.current.value_defs[def_index.index()];
|
||||
let region = &self.current.regions[self.index];
|
||||
|
||||
if let Some(expr) = def.expr() {
|
||||
self.push_pending_from_expr(expr);
|
||||
match def {
|
||||
ValueDef::Body(_, body) => self.push_pending_from_expr(&body.value),
|
||||
|
||||
ValueDef::AnnotatedBody {
|
||||
ann_pattern: _,
|
||||
ann_type: _,
|
||||
comment: _,
|
||||
body_pattern: _,
|
||||
body_expr,
|
||||
} => self.push_pending_from_expr(&body_expr.value),
|
||||
|
||||
ValueDef::Dbg {
|
||||
condition,
|
||||
preceding_comment: _,
|
||||
}
|
||||
| ValueDef::Expect {
|
||||
condition,
|
||||
preceding_comment: _,
|
||||
}
|
||||
| ValueDef::ExpectFx {
|
||||
condition,
|
||||
preceding_comment: _,
|
||||
} => self.push_pending_from_expr(&condition.value),
|
||||
|
||||
ValueDef::ModuleImport(ModuleImport {
|
||||
before_name: _,
|
||||
name: _,
|
||||
alias: _,
|
||||
exposed: _,
|
||||
params,
|
||||
}) => {
|
||||
if let Some(ModuleImportParams { before: _, params }) = params {
|
||||
for loc_assigned_field in params.items {
|
||||
if let Some(expr) = loc_assigned_field.value.value() {
|
||||
self.push_pending_from_expr(&expr.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ValueDef::Stmt(loc_expr) => self.push_pending_from_expr(&loc_expr.value),
|
||||
ValueDef::Annotation(_, _) | ValueDef::IngestedFileImport(_) => {}
|
||||
}
|
||||
|
||||
self.index += 1;
|
||||
|
@ -1046,6 +1049,7 @@ impl<'a, 'b> Iterator for RecursiveValueDefIter<'a, 'b> {
|
|||
pub struct ModuleImport<'a> {
|
||||
pub before_name: &'a [CommentOrNewline<'a>],
|
||||
pub name: Loc<ImportedModuleName<'a>>,
|
||||
pub params: Option<ModuleImportParams<'a>>,
|
||||
pub alias: Option<header::KeywordItem<'a, ImportAsKeyword, Loc<ImportAlias<'a>>>>,
|
||||
pub exposed: Option<
|
||||
header::KeywordItem<
|
||||
|
@ -1056,6 +1060,12 @@ pub struct ModuleImport<'a> {
|
|||
>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct ModuleImportParams<'a> {
|
||||
pub before: &'a [CommentOrNewline<'a>],
|
||||
pub params: Collection<'a, Loc<AssignedField<'a, Expr<'a>>>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct IngestedFileImport<'a> {
|
||||
pub before_path: &'a [CommentOrNewline<'a>],
|
||||
|
@ -1537,6 +1547,20 @@ pub enum AssignedField<'a, Val> {
|
|||
Malformed(&'a str),
|
||||
}
|
||||
|
||||
impl<'a, Val> AssignedField<'a, Val> {
|
||||
pub fn value(&self) -> Option<&Loc<Val>> {
|
||||
let mut current = self;
|
||||
|
||||
loop {
|
||||
match current {
|
||||
Self::RequiredValue(_, _, val) | Self::OptionalValue(_, _, val) => break Some(val),
|
||||
Self::LabelOnly(_) | Self::Malformed(_) => break None,
|
||||
Self::SpaceBefore(next, _) | Self::SpaceAfter(next, _) => current = *next,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub enum RecordBuilderField<'a> {
|
||||
// A field with a value, e.g. `{ name: "blah" }`
|
||||
|
@ -2635,9 +2659,10 @@ impl<'a> Malformed for ValueDef<'a> {
|
|||
ValueDef::ModuleImport(ModuleImport {
|
||||
before_name: _,
|
||||
name: _,
|
||||
params,
|
||||
alias: _,
|
||||
exposed: _,
|
||||
}) => false,
|
||||
}) => params.is_malformed(),
|
||||
ValueDef::IngestedFileImport(IngestedFileImport {
|
||||
before_path: _,
|
||||
path,
|
||||
|
@ -2649,6 +2674,14 @@ impl<'a> Malformed for ValueDef<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> Malformed for ModuleImportParams<'a> {
|
||||
fn is_malformed(&self) -> bool {
|
||||
let Self { before: _, params } = self;
|
||||
|
||||
params.is_malformed()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Malformed for TypeAnnotation<'a> {
|
||||
fn is_malformed(&self) -> bool {
|
||||
match self {
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
use crate::ast::{
|
||||
is_expr_suffixed, AssignedField, Collection, CommentOrNewline, Defs, Expr, ExtractSpaces,
|
||||
Implements, ImplementsAbilities, ImportAlias, ImportAsKeyword, ImportExposingKeyword,
|
||||
ImportedModuleName, IngestedFileAnnotation, IngestedFileImport, ModuleImport, Pattern,
|
||||
RecordBuilderField, Spaceable, Spaced, Spaces, TypeAnnotation, TypeDef, TypeHeader, ValueDef,
|
||||
ImportedModuleName, IngestedFileAnnotation, IngestedFileImport, ModuleImport,
|
||||
ModuleImportParams, Pattern, RecordBuilderField, Spaceable, Spaced, Spaces, TypeAnnotation,
|
||||
TypeDef, TypeHeader, ValueDef,
|
||||
};
|
||||
use crate::blankspace::{
|
||||
space0_after_e, space0_around_e_no_after_indent_check, space0_around_ee, space0_before_e,
|
||||
|
@ -15,8 +16,8 @@ use crate::module::module_name_help;
|
|||
use crate::parser::{
|
||||
self, backtrackable, byte, byte_indent, increment_min_indent, line_min_indent, optional,
|
||||
reset_min_indent, sep_by1, sep_by1_e, set_min_indent, specialize_err, specialize_err_ref, then,
|
||||
two_bytes, EClosure, EExpect, EExpr, EIf, EImport, EInParens, EList, ENumber, EPattern,
|
||||
ERecord, EString, EType, EWhen, Either, ParseResult, Parser,
|
||||
two_bytes, EClosure, EExpect, EExpr, EIf, EImport, EImportParams, EInParens, EList, ENumber,
|
||||
EPattern, ERecord, EString, EType, EWhen, Either, ParseResult, Parser,
|
||||
};
|
||||
use crate::pattern::{closure_param, loc_implements_parser};
|
||||
use crate::state::State;
|
||||
|
@ -993,6 +994,7 @@ fn import_body<'a>() -> impl Parser<'a, ValueDef<'a>, EImport<'a>> {
|
|||
record!(ModuleImport {
|
||||
before_name: space0_e(EImport::IndentStart),
|
||||
name: loc!(imported_module_name()),
|
||||
params: optional(specialize_err(EImport::Params, import_params())),
|
||||
alias: optional(import_as()),
|
||||
exposed: optional(import_exposing())
|
||||
}),
|
||||
|
@ -1000,6 +1002,37 @@ fn import_body<'a>() -> impl Parser<'a, ValueDef<'a>, EImport<'a>> {
|
|||
)
|
||||
}
|
||||
|
||||
fn import_params<'a>() -> impl Parser<'a, ModuleImportParams<'a>, EImportParams<'a>> {
|
||||
then(
|
||||
and!(
|
||||
backtrackable(space0_e(EImportParams::Indent)),
|
||||
specialize_err(EImportParams::Record, record_help())
|
||||
),
|
||||
|arena, state, _, (before, record): (_, RecordHelp<'a>)| {
|
||||
if let Some(update) = record.update {
|
||||
return Err((
|
||||
MadeProgress,
|
||||
EImportParams::RecordUpdateFound(update.region),
|
||||
));
|
||||
}
|
||||
|
||||
let params = record.fields.map_items_result(arena, |loc_field| {
|
||||
match loc_field.value.to_assigned_field(arena) {
|
||||
Ok(field) => Ok(loc_field.map(|_| field)),
|
||||
Err(FoundApplyValue) => Err((
|
||||
MadeProgress,
|
||||
EImportParams::RecordApplyFound(loc_field.region),
|
||||
)),
|
||||
}
|
||||
})?;
|
||||
|
||||
let import_params = ModuleImportParams { before, params };
|
||||
|
||||
Ok((MadeProgress, import_params, state))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn imported_module_name<'a>() -> impl Parser<'a, ImportedModuleName<'a>, EImport<'a>> {
|
||||
record!(ImportedModuleName {
|
||||
|
|
|
@ -90,6 +90,7 @@ impl_space_problem! {
|
|||
EImport<'a>,
|
||||
EParams<'a>,
|
||||
EImports,
|
||||
EImportParams<'a>,
|
||||
EInParens<'a>,
|
||||
EClosure<'a>,
|
||||
EList<'a>,
|
||||
|
@ -541,6 +542,7 @@ pub enum EImport<'a> {
|
|||
PackageShorthand(Position),
|
||||
PackageShorthandDot(Position),
|
||||
ModuleName(Position),
|
||||
Params(EImportParams<'a>, Position),
|
||||
IndentAs(Position),
|
||||
As(Position),
|
||||
IndentAlias(Position),
|
||||
|
@ -563,6 +565,15 @@ pub enum EImport<'a> {
|
|||
EndNewline(Position),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum EImportParams<'a> {
|
||||
Indent(Position),
|
||||
Record(ERecord<'a>, Position),
|
||||
RecordUpdateFound(Region),
|
||||
RecordApplyFound(Region),
|
||||
Space(BadInputError, Position),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum EPattern<'a> {
|
||||
Record(PRecord<'a>, Position),
|
||||
|
|
|
@ -23,6 +23,7 @@ Defs {
|
|||
"Json",
|
||||
),
|
||||
},
|
||||
params: None,
|
||||
alias: None,
|
||||
exposed: None,
|
||||
},
|
||||
|
|
|
@ -41,6 +41,7 @@ Defs {
|
|||
"Decode",
|
||||
),
|
||||
},
|
||||
params: None,
|
||||
alias: None,
|
||||
exposed: None,
|
||||
},
|
||||
|
@ -56,6 +57,7 @@ Defs {
|
|||
"Decode",
|
||||
),
|
||||
},
|
||||
params: None,
|
||||
alias: Some(
|
||||
KeywordItem {
|
||||
keyword: Spaces {
|
||||
|
@ -82,6 +84,7 @@ Defs {
|
|||
"Decode",
|
||||
),
|
||||
},
|
||||
params: None,
|
||||
alias: None,
|
||||
exposed: Some(
|
||||
KeywordItem {
|
||||
|
@ -118,6 +121,7 @@ Defs {
|
|||
"Decode",
|
||||
),
|
||||
},
|
||||
params: None,
|
||||
alias: Some(
|
||||
KeywordItem {
|
||||
keyword: Spaces {
|
||||
|
|
|
@ -29,6 +29,7 @@ Defs {
|
|||
"JsonEncode",
|
||||
),
|
||||
},
|
||||
params: None,
|
||||
alias: Some(
|
||||
KeywordItem {
|
||||
keyword: Spaces {
|
||||
|
@ -53,6 +54,7 @@ Defs {
|
|||
"Bytes.Decode",
|
||||
),
|
||||
},
|
||||
params: None,
|
||||
alias: Some(
|
||||
KeywordItem {
|
||||
keyword: Spaces {
|
||||
|
|
|
@ -104,6 +104,7 @@ Defs {
|
|||
"Json",
|
||||
),
|
||||
},
|
||||
params: None,
|
||||
alias: Some(
|
||||
KeywordItem {
|
||||
keyword: Spaces {
|
||||
|
@ -141,6 +142,7 @@ Defs {
|
|||
"Json",
|
||||
),
|
||||
},
|
||||
params: None,
|
||||
alias: Some(
|
||||
KeywordItem {
|
||||
keyword: Spaces {
|
||||
|
@ -183,6 +185,7 @@ Defs {
|
|||
"Json",
|
||||
),
|
||||
},
|
||||
params: None,
|
||||
alias: Some(
|
||||
KeywordItem {
|
||||
keyword: Spaces {
|
||||
|
@ -212,6 +215,7 @@ Defs {
|
|||
"Json",
|
||||
),
|
||||
},
|
||||
params: None,
|
||||
alias: Some(
|
||||
KeywordItem {
|
||||
keyword: Spaces {
|
||||
|
@ -254,6 +258,7 @@ Defs {
|
|||
"Json",
|
||||
),
|
||||
},
|
||||
params: None,
|
||||
alias: Some(
|
||||
KeywordItem {
|
||||
keyword: Spaces {
|
||||
|
@ -304,6 +309,7 @@ Defs {
|
|||
"Json",
|
||||
),
|
||||
},
|
||||
params: None,
|
||||
alias: None,
|
||||
exposed: Some(
|
||||
KeywordItem {
|
||||
|
@ -343,6 +349,7 @@ Defs {
|
|||
"Json",
|
||||
),
|
||||
},
|
||||
params: None,
|
||||
alias: Some(
|
||||
KeywordItem {
|
||||
keyword: Spaces {
|
||||
|
@ -385,6 +392,7 @@ Defs {
|
|||
"Json",
|
||||
),
|
||||
},
|
||||
params: None,
|
||||
alias: None,
|
||||
exposed: Some(
|
||||
KeywordItem {
|
||||
|
@ -416,6 +424,7 @@ Defs {
|
|||
"Json",
|
||||
),
|
||||
},
|
||||
params: None,
|
||||
alias: Some(
|
||||
KeywordItem {
|
||||
keyword: Spaces {
|
||||
|
@ -458,6 +467,7 @@ Defs {
|
|||
"Json",
|
||||
),
|
||||
},
|
||||
params: None,
|
||||
alias: Some(
|
||||
KeywordItem {
|
||||
keyword: Spaces {
|
||||
|
@ -513,6 +523,7 @@ Defs {
|
|||
"Json",
|
||||
),
|
||||
},
|
||||
params: None,
|
||||
alias: Some(
|
||||
KeywordItem {
|
||||
keyword: Spaces {
|
||||
|
@ -583,6 +594,7 @@ Defs {
|
|||
"A",
|
||||
),
|
||||
},
|
||||
params: None,
|
||||
alias: None,
|
||||
exposed: None,
|
||||
},
|
||||
|
@ -596,6 +608,7 @@ Defs {
|
|||
"B",
|
||||
),
|
||||
},
|
||||
params: None,
|
||||
alias: None,
|
||||
exposed: None,
|
||||
},
|
||||
|
|
|
@ -34,6 +34,7 @@ Defs {
|
|||
"Json",
|
||||
),
|
||||
},
|
||||
params: None,
|
||||
alias: None,
|
||||
exposed: Some(
|
||||
KeywordItem {
|
||||
|
@ -63,6 +64,7 @@ Defs {
|
|||
"Json",
|
||||
),
|
||||
},
|
||||
params: None,
|
||||
alias: None,
|
||||
exposed: Some(
|
||||
KeywordItem {
|
||||
|
@ -97,6 +99,7 @@ Defs {
|
|||
"Json",
|
||||
),
|
||||
},
|
||||
params: None,
|
||||
alias: None,
|
||||
exposed: Some(
|
||||
KeywordItem {
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
import pf.Menu
|
||||
import Menu
|
|
@ -0,0 +1,83 @@
|
|||
Defs {
|
||||
tags: [
|
||||
Index(2147483648),
|
||||
Index(2147483649),
|
||||
],
|
||||
regions: [
|
||||
@0-29,
|
||||
@30-60,
|
||||
],
|
||||
space_before: [
|
||||
Slice(start = 0, length = 0),
|
||||
Slice(start = 0, length = 1),
|
||||
],
|
||||
space_after: [
|
||||
Slice(start = 0, length = 0),
|
||||
Slice(start = 1, length = 0),
|
||||
],
|
||||
spaces: [
|
||||
Newline,
|
||||
],
|
||||
type_defs: [],
|
||||
value_defs: [
|
||||
ModuleImport(
|
||||
ModuleImport {
|
||||
before_name: [],
|
||||
name: @7-14 ImportedModuleName {
|
||||
package: Some(
|
||||
"pf",
|
||||
),
|
||||
name: ModuleName(
|
||||
"Menu",
|
||||
),
|
||||
},
|
||||
params: Some(
|
||||
ModuleImportParams {
|
||||
before: [],
|
||||
params: [
|
||||
@17-21 LabelOnly(
|
||||
@17-21 "echo",
|
||||
),
|
||||
@23-28 LabelOnly(
|
||||
@23-27 "read",
|
||||
),
|
||||
],
|
||||
},
|
||||
),
|
||||
alias: None,
|
||||
exposed: None,
|
||||
},
|
||||
),
|
||||
ModuleImport(
|
||||
ModuleImport {
|
||||
before_name: [],
|
||||
name: @37-41 ImportedModuleName {
|
||||
package: None,
|
||||
name: ModuleName(
|
||||
"Menu",
|
||||
),
|
||||
},
|
||||
params: Some(
|
||||
ModuleImportParams {
|
||||
before: [],
|
||||
params: [
|
||||
@44-48 LabelOnly(
|
||||
@44-48 "echo",
|
||||
),
|
||||
@54-59 SpaceBefore(
|
||||
LabelOnly(
|
||||
@54-58 "read",
|
||||
),
|
||||
[
|
||||
Newline,
|
||||
],
|
||||
),
|
||||
],
|
||||
},
|
||||
),
|
||||
alias: None,
|
||||
exposed: None,
|
||||
},
|
||||
),
|
||||
],
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
import pf.Menu { echo, read }
|
||||
import Menu { echo,
|
||||
read }
|
|
@ -32,6 +32,7 @@ Defs(
|
|||
"Json",
|
||||
),
|
||||
},
|
||||
params: None,
|
||||
alias: None,
|
||||
exposed: Some(
|
||||
KeywordItem {
|
||||
|
@ -58,6 +59,7 @@ Defs(
|
|||
"Json.Encode",
|
||||
),
|
||||
},
|
||||
params: None,
|
||||
alias: Some(
|
||||
KeywordItem {
|
||||
keyword: Spaces {
|
||||
|
|
|
@ -81,6 +81,7 @@ Full {
|
|||
"Stdout",
|
||||
),
|
||||
},
|
||||
params: None,
|
||||
alias: None,
|
||||
exposed: None,
|
||||
},
|
||||
|
|
|
@ -71,6 +71,7 @@ Full {
|
|||
"Stdout",
|
||||
),
|
||||
},
|
||||
params: None,
|
||||
alias: None,
|
||||
exposed: None,
|
||||
},
|
||||
|
|
|
@ -212,6 +212,8 @@ mod test_snapshots {
|
|||
fail/list_pattern_not_terminated.expr,
|
||||
fail/list_pattern_weird_rest_pattern.expr,
|
||||
fail/list_without_end.expr,
|
||||
fail/module_params_with_missing_arrow.header,
|
||||
fail/module_with_unfinished_params.header,
|
||||
fail/multi_no_end.expr,
|
||||
fail/pattern_binds_keyword.expr,
|
||||
fail/pattern_in_parens_end.expr,
|
||||
|
@ -249,8 +251,6 @@ mod test_snapshots {
|
|||
fail/when_over_indented_underscore.expr,
|
||||
fail/where_type_variable.expr,
|
||||
fail/wild_case_arrow.expr,
|
||||
fail/module_with_unfinished_params.header,
|
||||
fail/module_params_with_missing_arrow.header,
|
||||
malformed/bad_opaque_ref.expr,
|
||||
malformed/malformed_ident_due_to_underscore.expr,
|
||||
malformed/malformed_pattern_field_access.expr, // See https://github.com/roc-lang/roc/issues/399
|
||||
|
@ -332,6 +332,7 @@ mod test_snapshots {
|
|||
pass/import_with_alias.moduledefs,
|
||||
pass/import_with_comments.moduledefs,
|
||||
pass/import_with_exposed.moduledefs,
|
||||
pass/import_with_params.moduledefs,
|
||||
pass/ingested_file.moduledefs,
|
||||
pass/inline_import.expr,
|
||||
pass/inline_ingested_file.expr,
|
||||
|
@ -352,11 +353,11 @@ mod test_snapshots {
|
|||
pass/mixed_docs.expr,
|
||||
pass/module_def_newline.moduledefs,
|
||||
pass/module_multiline_exposes.header,
|
||||
pass/module_with_multiline_params_and_exposes.header,
|
||||
pass/module_with_newline.header,
|
||||
pass/module_with_optional_param.header,
|
||||
pass/module_with_params.header,
|
||||
pass/module_with_params_and_multiline_exposes.header,
|
||||
pass/module_with_optional_param.header,
|
||||
pass/module_with_multiline_params_and_exposes.header,
|
||||
pass/multi_backpassing.expr,
|
||||
pass/multi_backpassing_in_def.moduledefs,
|
||||
pass/multi_backpassing_with_apply.expr,
|
||||
|
|
|
@ -540,22 +540,8 @@ fn to_expr_report<'a>(
|
|||
}
|
||||
}
|
||||
|
||||
EExpr::Record(_erecord, pos) => {
|
||||
let surroundings = Region::new(start, *pos);
|
||||
let region = LineColumnRegion::from_pos(lines.convert_pos(*pos));
|
||||
|
||||
let doc = alloc.stack([
|
||||
alloc.reflow(r"I am partway through parsing a record, but I got stuck here:"),
|
||||
alloc.region_with_subregion(lines.convert_region(surroundings), region),
|
||||
alloc.concat([alloc.reflow("TODO provide more context.")]),
|
||||
]);
|
||||
|
||||
Report {
|
||||
filename,
|
||||
doc,
|
||||
title: "RECORD PARSE PROBLEM".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
EExpr::Record(erecord, pos) => {
|
||||
to_record_report(alloc, lines, filename, erecord, *pos, start)
|
||||
}
|
||||
|
||||
EExpr::OptionalValueInRecordBuilder(region) => {
|
||||
|
@ -711,6 +697,31 @@ fn to_expr_report<'a>(
|
|||
}
|
||||
}
|
||||
|
||||
fn to_record_report<'a>(
|
||||
alloc: &'a RocDocAllocator<'a>,
|
||||
lines: &LineInfo,
|
||||
filename: PathBuf,
|
||||
_parse_problem: &roc_parse::parser::ERecord<'a>,
|
||||
pos: Position,
|
||||
start: Position,
|
||||
) -> Report<'a> {
|
||||
let surroundings = Region::new(start, pos);
|
||||
let region = LineColumnRegion::from_pos(lines.convert_pos(pos));
|
||||
|
||||
let doc = alloc.stack([
|
||||
alloc.reflow(r"I am partway through parsing a record, but I got stuck here:"),
|
||||
alloc.region_with_subregion(lines.convert_region(surroundings), region),
|
||||
alloc.concat([alloc.reflow("TODO provide more context.")]),
|
||||
]);
|
||||
|
||||
Report {
|
||||
filename,
|
||||
doc,
|
||||
title: "RECORD PARSE PROBLEM".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_lambda_report<'a>(
|
||||
alloc: &'a RocDocAllocator<'a>,
|
||||
lines: &LineInfo,
|
||||
|
@ -1450,6 +1461,7 @@ fn to_import_report<'a>(
|
|||
start: Position,
|
||||
) -> Report<'a> {
|
||||
use roc_parse::parser::EImport::*;
|
||||
use roc_parse::parser::EImportParams;
|
||||
|
||||
match parse_problem {
|
||||
Import(_pos) => unreachable!("another branch would be taken"),
|
||||
|
@ -1502,6 +1514,10 @@ fn to_import_report<'a>(
|
|||
]),
|
||||
)
|
||||
}
|
||||
Params(EImportParams::Record(problem, pos), _) => {
|
||||
to_record_report(alloc, lines, filename, problem, *pos, start)
|
||||
}
|
||||
Params(_, _) => todo!("Report param errors"),
|
||||
IndentAlias(pos) | Alias(pos) => to_unfinished_import_report(
|
||||
alloc,
|
||||
lines,
|
||||
|
@ -1593,7 +1609,9 @@ fn to_import_report<'a>(
|
|||
.indent(4),
|
||||
]),
|
||||
),
|
||||
Space(problem, pos) => to_space_report(alloc, lines, filename, problem, *pos),
|
||||
Space(problem, pos) | Params(EImportParams::Space(problem, pos), _) => {
|
||||
to_space_report(alloc, lines, filename, problem, *pos)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue