mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-27 05:49:08 +00:00
Parse and format top-level import defs with no alias or exposed members
This commit is contained in:
parent
ebfcd71e8d
commit
933fde77a0
12 changed files with 117 additions and 25 deletions
|
@ -196,6 +196,7 @@ impl<'a> Formattable for ValueDef<'a> {
|
||||||
Expect { condition, .. } => condition.is_multiline(),
|
Expect { condition, .. } => condition.is_multiline(),
|
||||||
ExpectFx { condition, .. } => condition.is_multiline(),
|
ExpectFx { condition, .. } => condition.is_multiline(),
|
||||||
Dbg { condition, .. } => condition.is_multiline(),
|
Dbg { condition, .. } => condition.is_multiline(),
|
||||||
|
ModuleImport { name: _ } => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,6 +239,13 @@ impl<'a> Formattable for ValueDef<'a> {
|
||||||
buf.newline();
|
buf.newline();
|
||||||
fmt_body(buf, &body_pattern.value, &body_expr.value, indent);
|
fmt_body(buf, &body_pattern.value, &body_expr.value, indent);
|
||||||
}
|
}
|
||||||
|
ModuleImport { name } => {
|
||||||
|
buf.indent(indent);
|
||||||
|
|
||||||
|
buf.push_str("import");
|
||||||
|
buf.spaces(1);
|
||||||
|
buf.push_str(name.value.as_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -565,6 +565,9 @@ impl<'a> RemoveSpaces<'a> for ValueDef<'a> {
|
||||||
condition: arena.alloc(condition.remove_spaces(arena)),
|
condition: arena.alloc(condition.remove_spaces(arena)),
|
||||||
preceding_comment: Region::zero(),
|
preceding_comment: Region::zero(),
|
||||||
},
|
},
|
||||||
|
ModuleImport { name } => ModuleImport {
|
||||||
|
name: name.remove_spaces(arena),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -455,6 +455,11 @@ pub enum ValueDef<'a> {
|
||||||
condition: &'a Loc<Expr<'a>>,
|
condition: &'a Loc<Expr<'a>>,
|
||||||
preceding_comment: Region,
|
preceding_comment: Region,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/// e.g. `import [Req] as Http from InternalHttp`.
|
||||||
|
ModuleImport {
|
||||||
|
name: Loc<crate::header::ModuleName<'a>>,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Default)]
|
#[derive(Debug, Clone, PartialEq, Default)]
|
||||||
|
@ -1792,6 +1797,7 @@ impl<'a> Malformed for ValueDef<'a> {
|
||||||
condition,
|
condition,
|
||||||
preceding_comment: _,
|
preceding_comment: _,
|
||||||
} => condition.is_malformed(),
|
} => condition.is_malformed(),
|
||||||
|
ValueDef::ModuleImport { name } => name.value.contains_dot(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,8 +12,8 @@ use crate::keyword;
|
||||||
use crate::parser::{
|
use crate::parser::{
|
||||||
self, backtrackable, increment_min_indent, line_min_indent, optional, reset_min_indent,
|
self, backtrackable, increment_min_indent, line_min_indent, optional, reset_min_indent,
|
||||||
sep_by1, sep_by1_e, set_min_indent, specialize, specialize_ref, then, word1, word1_indent,
|
sep_by1, sep_by1_e, set_min_indent, specialize, specialize_ref, then, word1, word1_indent,
|
||||||
word2, EClosure, EExpect, EExpr, EIf, EInParens, EList, ENumber, EPattern, ERecord, EString,
|
word2, EClosure, EExpect, EExpr, EIf, EImport, EInParens, EList, ENumber, EPattern, ERecord,
|
||||||
EType, EWhen, Either, ParseResult, Parser,
|
EString, EType, EWhen, Either, ParseResult, Parser,
|
||||||
};
|
};
|
||||||
use crate::pattern::{closure_param, loc_implements_parser};
|
use crate::pattern::{closure_param, loc_implements_parser};
|
||||||
use crate::state::State;
|
use crate::state::State;
|
||||||
|
@ -574,6 +574,8 @@ pub fn parse_single_def<'a>(
|
||||||
min_indent,
|
min_indent,
|
||||||
) {
|
) {
|
||||||
Err((NoProgress, _)) => {
|
Err((NoProgress, _)) => {
|
||||||
|
match loc!(import()).parse(arena, state.clone(), min_indent) {
|
||||||
|
Err((_, _)) => {
|
||||||
match parse_expect.parse(arena, state.clone(), min_indent) {
|
match parse_expect.parse(arena, state.clone(), min_indent) {
|
||||||
Err((_, _)) => {
|
Err((_, _)) => {
|
||||||
// a hacky way to get expression-based error messages. TODO fix this
|
// a hacky way to get expression-based error messages. TODO fix this
|
||||||
|
@ -600,6 +602,17 @@ pub fn parse_single_def<'a>(
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Ok((_, loc_import, state)) => Ok((
|
||||||
|
MadeProgress,
|
||||||
|
Some(SingleDef {
|
||||||
|
type_or_value: Either::Second(loc_import.value),
|
||||||
|
region: loc_import.region,
|
||||||
|
spaces_before: spaces_before_current,
|
||||||
|
}),
|
||||||
|
state,
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
}
|
||||||
Err((MadeProgress, _)) => {
|
Err((MadeProgress, _)) => {
|
||||||
// a hacky way to get expression-based error messages. TODO fix this
|
// a hacky way to get expression-based error messages. TODO fix this
|
||||||
Ok((NoProgress, None, initial))
|
Ok((NoProgress, None, initial))
|
||||||
|
@ -823,6 +836,24 @@ pub fn parse_single_def<'a>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn import<'a>() -> impl Parser<'a, ValueDef<'a>, EImport> {
|
||||||
|
map!(
|
||||||
|
skip_first!(
|
||||||
|
and!(
|
||||||
|
crate::parser::keyword_e(crate::keyword::IMPORT, EImport::Import),
|
||||||
|
spaces()
|
||||||
|
),
|
||||||
|
loc!(crate::module::module_name_help(EImport::ModuleName))
|
||||||
|
),
|
||||||
|
|loc_module_name| {
|
||||||
|
ValueDef::ModuleImport {
|
||||||
|
name: loc_module_name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/// e.g. Things that can be on their own line in a def, e.g. `expect`, `expect-fx`, or `dbg`
|
/// e.g. Things that can be on their own line in a def, e.g. `expect`, `expect-fx`, or `dbg`
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn parse_statement_inside_def<'a>(
|
fn parse_statement_inside_def<'a>(
|
||||||
|
|
|
@ -128,6 +128,10 @@ impl<'a> ModuleName<'a> {
|
||||||
pub const fn as_str(&'a self) -> &'a str {
|
pub const fn as_str(&'a self) -> &'a str {
|
||||||
self.0
|
self.0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn contains_dot(&self) -> bool {
|
||||||
|
self.0.contains('.')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
|
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
|
||||||
|
|
|
@ -6,6 +6,7 @@ pub const WHEN: &str = "when";
|
||||||
pub const AS: &str = "as";
|
pub const AS: &str = "as";
|
||||||
pub const IS: &str = "is";
|
pub const IS: &str = "is";
|
||||||
pub const DBG: &str = "dbg";
|
pub const DBG: &str = "dbg";
|
||||||
|
pub const IMPORT: &str = "import";
|
||||||
pub const EXPECT: &str = "expect";
|
pub const EXPECT: &str = "expect";
|
||||||
pub const EXPECT_FX: &str = "expect-fx";
|
pub const EXPECT_FX: &str = "expect-fx";
|
||||||
pub const CRASH: &str = "crash";
|
pub const CRASH: &str = "crash";
|
||||||
|
@ -14,4 +15,6 @@ pub const CRASH: &str = "crash";
|
||||||
pub const IMPLEMENTS: &str = "implements";
|
pub const IMPLEMENTS: &str = "implements";
|
||||||
pub const WHERE: &str = "where";
|
pub const WHERE: &str = "where";
|
||||||
|
|
||||||
pub const KEYWORDS: [&str; 10] = [IF, THEN, ELSE, WHEN, AS, IS, DBG, EXPECT, EXPECT_FX, CRASH];
|
pub const KEYWORDS: [&str; 11] = [
|
||||||
|
IF, THEN, ELSE, WHEN, AS, IS, DBG, IMPORT, EXPECT, EXPECT_FX, CRASH,
|
||||||
|
];
|
||||||
|
|
|
@ -590,7 +590,7 @@ fn shortname<'a>() -> impl Parser<'a, &'a str, EImports> {
|
||||||
specialize(|_, pos| EImports::Shorthand(pos), lowercase_ident())
|
specialize(|_, pos| EImports::Shorthand(pos), lowercase_ident())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn module_name_help<'a, F, E>(to_expectation: F) -> impl Parser<'a, ModuleName<'a>, E>
|
pub fn module_name_help<'a, F, E>(to_expectation: F) -> impl Parser<'a, ModuleName<'a>, E>
|
||||||
where
|
where
|
||||||
F: Fn(Position) -> E,
|
F: Fn(Position) -> E,
|
||||||
E: 'a,
|
E: 'a,
|
||||||
|
|
|
@ -87,6 +87,7 @@ impl_space_problem! {
|
||||||
EGeneratesWith,
|
EGeneratesWith,
|
||||||
EHeader<'a>,
|
EHeader<'a>,
|
||||||
EIf<'a>,
|
EIf<'a>,
|
||||||
|
EImport,
|
||||||
EImports,
|
EImports,
|
||||||
EInParens<'a>,
|
EInParens<'a>,
|
||||||
EClosure<'a>,
|
EClosure<'a>,
|
||||||
|
@ -346,6 +347,7 @@ pub enum EExpr<'a> {
|
||||||
|
|
||||||
Expect(EExpect<'a>, Position),
|
Expect(EExpect<'a>, Position),
|
||||||
Dbg(EExpect<'a>, Position),
|
Dbg(EExpect<'a>, Position),
|
||||||
|
Import(EImport, Position),
|
||||||
|
|
||||||
Closure(EClosure<'a>, Position),
|
Closure(EClosure<'a>, Position),
|
||||||
Underscore(Position),
|
Underscore(Position),
|
||||||
|
@ -517,6 +519,13 @@ pub enum EExpect<'a> {
|
||||||
IndentCondition(Position),
|
IndentCondition(Position),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub enum EImport {
|
||||||
|
Import(Position),
|
||||||
|
ModuleName(Position),
|
||||||
|
Space(BadInputError, Position),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum EPattern<'a> {
|
pub enum EPattern<'a> {
|
||||||
Record(PRecord<'a>, Position),
|
Record(PRecord<'a>, Position),
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
import Json
|
|
@ -0,0 +1,23 @@
|
||||||
|
Defs {
|
||||||
|
tags: [
|
||||||
|
Index(2147483648),
|
||||||
|
],
|
||||||
|
regions: [
|
||||||
|
@0-12,
|
||||||
|
],
|
||||||
|
space_before: [
|
||||||
|
Slice(start = 0, length = 0),
|
||||||
|
],
|
||||||
|
space_after: [
|
||||||
|
Slice(start = 0, length = 0),
|
||||||
|
],
|
||||||
|
spaces: [],
|
||||||
|
type_defs: [],
|
||||||
|
value_defs: [
|
||||||
|
ModuleImport {
|
||||||
|
name: @8-12 ModuleName(
|
||||||
|
"Json",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
import Json
|
|
@ -323,6 +323,7 @@ mod test_snapshots {
|
||||||
pass/highest_float.expr,
|
pass/highest_float.expr,
|
||||||
pass/highest_int.expr,
|
pass/highest_int.expr,
|
||||||
pass/if_def.expr,
|
pass/if_def.expr,
|
||||||
|
pass/import.moduledefs,
|
||||||
pass/int_with_underscore.expr,
|
pass/int_with_underscore.expr,
|
||||||
pass/interface_with_newline.header,
|
pass/interface_with_newline.header,
|
||||||
pass/lambda_in_chain.expr,
|
pass/lambda_in_chain.expr,
|
||||||
|
@ -568,6 +569,8 @@ mod test_snapshots {
|
||||||
Err(err) => Err(format!("{err:?}")),
|
Err(err) => Err(format!("{err:?}")),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
println!("{:?}", result);
|
||||||
|
|
||||||
if expect == TestExpectation::Pass {
|
if expect == TestExpectation::Pass {
|
||||||
let tokens = roc_parse::highlight::highlight(&source);
|
let tokens = roc_parse::highlight::highlight(&source);
|
||||||
for token in tokens {
|
for token in tokens {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue