mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 13:29:12 +00:00
Parse and format inline ingested file imports
This commit is contained in:
parent
42e755677c
commit
4d6e641864
10 changed files with 165 additions and 12 deletions
|
@ -1,5 +1,6 @@
|
|||
use crate::annotation::{is_collection_multiline, Formattable, Newlines, Parens};
|
||||
use crate::collection::{fmt_collection, Braces};
|
||||
use crate::expr::fmt_str_literal;
|
||||
use crate::pattern::fmt_pattern;
|
||||
use crate::spaces::{fmt_default_newline, fmt_default_spaces, fmt_spaces, INDENT};
|
||||
use crate::Buf;
|
||||
|
@ -287,6 +288,11 @@ impl<'a> Formattable for ValueDef<'a> {
|
|||
a.keyword.is_multiline() || is_collection_multiline(&a.item)
|
||||
})
|
||||
}
|
||||
IngestedFileImport {
|
||||
before_path,
|
||||
path: _,
|
||||
name,
|
||||
} => !before_path.is_empty() || name.is_multiline(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -365,6 +371,20 @@ impl<'a> Formattable for ValueDef<'a> {
|
|||
fmt_collection(buf, list_indent, Braces::Square, exposed.item, Newlines::No);
|
||||
}
|
||||
}
|
||||
IngestedFileImport {
|
||||
before_path,
|
||||
path,
|
||||
name,
|
||||
} => {
|
||||
buf.indent(indent);
|
||||
buf.push_str("import");
|
||||
|
||||
let indent = indent + INDENT;
|
||||
|
||||
fmt_default_spaces(buf, before_path, indent);
|
||||
fmt_str_literal(buf, path.value, indent);
|
||||
name.format(buf, indent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -577,6 +577,15 @@ impl<'a> RemoveSpaces<'a> for ValueDef<'a> {
|
|||
alias: alias.remove_spaces(arena),
|
||||
exposed: exposed.remove_spaces(arena),
|
||||
},
|
||||
IngestedFileImport {
|
||||
before_path: _,
|
||||
path,
|
||||
name,
|
||||
} => IngestedFileImport {
|
||||
before_path: &[],
|
||||
path: path.remove_spaces(arena),
|
||||
name: name.remove_spaces(arena),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -471,6 +471,13 @@ pub enum ValueDef<'a> {
|
|||
>,
|
||||
>,
|
||||
},
|
||||
|
||||
/// e.g. `import "path/to/my/file.txt" as myFile : Str`
|
||||
IngestedFileImport {
|
||||
before_path: &'a [CommentOrNewline<'a>],
|
||||
path: Loc<StrLiteral<'a>>,
|
||||
name: header::KeywordItem<'a, ImportAsKeyword, Loc<Spaced<'a, header::TypedIdent<'a>>>>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||
|
@ -1847,6 +1854,11 @@ impl<'a> Malformed for ValueDef<'a> {
|
|||
alias: _,
|
||||
exposed: _,
|
||||
} => false,
|
||||
ValueDef::IngestedFileImport {
|
||||
before_path: _,
|
||||
path,
|
||||
name: _,
|
||||
} => path.is_malformed(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ use crate::parser::{
|
|||
};
|
||||
use crate::pattern::{closure_param, loc_implements_parser};
|
||||
use crate::state::State;
|
||||
use crate::string_literal::StrLikeLiteral;
|
||||
use crate::string_literal::{self, StrLikeLiteral};
|
||||
use crate::{header, keyword};
|
||||
use crate::{module, type_annotation};
|
||||
use bumpalo::collections::Vec;
|
||||
|
@ -840,14 +840,14 @@ pub fn parse_single_def<'a>(
|
|||
}
|
||||
}
|
||||
|
||||
fn import<'a>() -> impl Parser<'a, ValueDef<'a>, EImport> {
|
||||
fn import<'a>() -> impl Parser<'a, ValueDef<'a>, EImport<'a>> {
|
||||
skip_first!(
|
||||
parser::keyword_e(keyword::IMPORT, EImport::Import),
|
||||
increment_min_indent(import_body())
|
||||
increment_min_indent(one_of!(import_body(), import_ingested_file_body()))
|
||||
)
|
||||
}
|
||||
|
||||
fn import_body<'a>() -> impl Parser<'a, ValueDef<'a>, EImport> {
|
||||
fn import_body<'a>() -> impl Parser<'a, ValueDef<'a>, EImport<'a>> {
|
||||
record!(ValueDef::ModuleImport {
|
||||
before_name: space0_e(EImport::IndentStart),
|
||||
name: loc!(imported_module_name()),
|
||||
|
@ -857,7 +857,7 @@ fn import_body<'a>() -> impl Parser<'a, ValueDef<'a>, EImport> {
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn imported_module_name<'a>() -> impl Parser<'a, ImportedModuleName<'a>, EImport> {
|
||||
fn imported_module_name<'a>() -> impl Parser<'a, ImportedModuleName<'a>, EImport<'a>> {
|
||||
record!(ImportedModuleName {
|
||||
package: optional(skip_second!(
|
||||
specialize(|_, pos| EImport::PackageShorthand(pos), lowercase_ident()),
|
||||
|
@ -869,7 +869,7 @@ fn imported_module_name<'a>() -> impl Parser<'a, ImportedModuleName<'a>, EImport
|
|||
|
||||
#[inline(always)]
|
||||
fn import_as<'a>(
|
||||
) -> impl Parser<'a, header::KeywordItem<'a, ImportAsKeyword, Loc<ImportAlias<'a>>>, EImport> {
|
||||
) -> impl Parser<'a, header::KeywordItem<'a, ImportAsKeyword, Loc<ImportAlias<'a>>>, EImport<'a>> {
|
||||
record!(header::KeywordItem {
|
||||
keyword: module::spaces_around_keyword(
|
||||
ImportAsKeyword,
|
||||
|
@ -892,7 +892,7 @@ fn import_exposing<'a>() -> impl Parser<
|
|||
ImportExposingKeyword,
|
||||
Collection<'a, Loc<Spaced<'a, header::ExposedName<'a>>>>,
|
||||
>,
|
||||
EImport,
|
||||
EImport<'a>,
|
||||
> {
|
||||
record!(header::KeywordItem {
|
||||
keyword: module::spaces_around_keyword(
|
||||
|
@ -913,13 +913,42 @@ fn import_exposing<'a>() -> impl Parser<
|
|||
|
||||
#[inline(always)]
|
||||
fn import_exposed_name<'a>(
|
||||
) -> impl Parser<'a, crate::ast::Spaced<'a, crate::header::ExposedName<'a>>, EImport> {
|
||||
) -> impl Parser<'a, crate::ast::Spaced<'a, crate::header::ExposedName<'a>>, EImport<'a>> {
|
||||
map!(
|
||||
specialize(|_, pos| EImport::ExposedName(pos), unqualified_ident()),
|
||||
|n| Spaced::Item(crate::header::ExposedName::new(n))
|
||||
)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn import_ingested_file_body<'a>() -> impl Parser<'a, ValueDef<'a>, EImport<'a>> {
|
||||
record!(ValueDef::IngestedFileImport {
|
||||
before_path: space0_e(EImport::IndentStart),
|
||||
path: loc!(specialize(
|
||||
|_, pos| EImport::IngestedPath(pos),
|
||||
string_literal::parse_str_literal()
|
||||
)),
|
||||
name: import_ingested_file_as(),
|
||||
})
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn import_ingested_file_as<'a>() -> impl Parser<
|
||||
'a,
|
||||
header::KeywordItem<'a, ImportAsKeyword, Loc<Spaced<'a, header::TypedIdent<'a>>>>,
|
||||
EImport<'a>,
|
||||
> {
|
||||
record!(header::KeywordItem {
|
||||
keyword: module::spaces_around_keyword(
|
||||
ImportAsKeyword,
|
||||
EImport::As,
|
||||
EImport::IndentAs,
|
||||
EImport::IndentIngestedName
|
||||
),
|
||||
item: specialize(EImport::IngestedName, loc!(module::typed_ident()))
|
||||
})
|
||||
}
|
||||
|
||||
/// 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)]
|
||||
fn parse_statement_inside_def<'a>(
|
||||
|
|
|
@ -552,7 +552,7 @@ fn imports<'a>() -> impl Parser<
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn typed_ident<'a>() -> impl Parser<'a, Spaced<'a, TypedIdent<'a>>, ETypedIdent<'a>> {
|
||||
pub fn typed_ident<'a>() -> impl Parser<'a, Spaced<'a, TypedIdent<'a>>, ETypedIdent<'a>> {
|
||||
// e.g.
|
||||
//
|
||||
// printLine : Str -> Effect {}
|
||||
|
|
|
@ -87,7 +87,7 @@ impl_space_problem! {
|
|||
EGeneratesWith,
|
||||
EHeader<'a>,
|
||||
EIf<'a>,
|
||||
EImport,
|
||||
EImport<'a>,
|
||||
EImports,
|
||||
EInParens<'a>,
|
||||
EClosure<'a>,
|
||||
|
@ -347,7 +347,7 @@ pub enum EExpr<'a> {
|
|||
|
||||
Expect(EExpect<'a>, Position),
|
||||
Dbg(EExpect<'a>, Position),
|
||||
Import(EImport, Position),
|
||||
Import(EImport<'a>, Position),
|
||||
|
||||
Closure(EClosure<'a>, Position),
|
||||
Underscore(Position),
|
||||
|
@ -520,7 +520,7 @@ pub enum EExpect<'a> {
|
|||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum EImport {
|
||||
pub enum EImport<'a> {
|
||||
Import(Position),
|
||||
IndentStart(Position),
|
||||
PackageShorthand(Position),
|
||||
|
@ -535,6 +535,10 @@ pub enum EImport {
|
|||
ExposingListStart(Position),
|
||||
ExposedName(Position),
|
||||
ExposingListEnd(Position),
|
||||
IndentIngestedPath(Position),
|
||||
IngestedPath(Position),
|
||||
IndentIngestedName(Position),
|
||||
IngestedName(ETypedIdent<'a>, Position),
|
||||
Space(BadInputError, Position),
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
import "path/to/file.txt" as file : Str
|
||||
import "path/to/file.txt" as file : List U8
|
|
@ -0,0 +1,74 @@
|
|||
Defs {
|
||||
tags: [
|
||||
Index(2147483648),
|
||||
Index(2147483649),
|
||||
],
|
||||
regions: [
|
||||
@0-39,
|
||||
@40-85,
|
||||
],
|
||||
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: [
|
||||
IngestedFileImport {
|
||||
before_path: [],
|
||||
path: @7-25 PlainLine(
|
||||
"path/to/file.txt",
|
||||
),
|
||||
name: KeywordItem {
|
||||
keyword: Spaces {
|
||||
before: [],
|
||||
item: ImportAsKeyword,
|
||||
after: [],
|
||||
},
|
||||
item: @29-39 TypedIdent {
|
||||
ident: @29-33 "file",
|
||||
spaces_before_colon: [],
|
||||
ann: @36-39 Apply(
|
||||
"",
|
||||
"Str",
|
||||
[],
|
||||
),
|
||||
},
|
||||
},
|
||||
},
|
||||
IngestedFileImport {
|
||||
before_path: [],
|
||||
path: @47-65 PlainLine(
|
||||
"path/to/file.txt",
|
||||
),
|
||||
name: KeywordItem {
|
||||
keyword: Spaces {
|
||||
before: [],
|
||||
item: ImportAsKeyword,
|
||||
after: [],
|
||||
},
|
||||
item: @70-85 TypedIdent {
|
||||
ident: @70-74 "file",
|
||||
spaces_before_colon: [],
|
||||
ann: @78-85 Apply(
|
||||
"",
|
||||
"List",
|
||||
[
|
||||
@83-85 Apply(
|
||||
"",
|
||||
"U8",
|
||||
[],
|
||||
),
|
||||
],
|
||||
),
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
import "path/to/file.txt" as file : Str
|
||||
import "path/to/file.txt" as file : List U8
|
|
@ -329,6 +329,7 @@ mod test_snapshots {
|
|||
pass/import_with_alias.moduledefs,
|
||||
pass/import_with_comments.moduledefs,
|
||||
pass/import_with_exposed.moduledefs,
|
||||
pass/ingested_file.moduledefs,
|
||||
pass/int_with_underscore.expr,
|
||||
pass/interface_with_newline.header,
|
||||
pass/lambda_in_chain.expr,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue