Upgrade hosted header in the style module header

This commit is contained in:
Sam Mohr 2025-01-26 15:07:57 -08:00
parent 3f09235d6a
commit 631e59ce06
No known key found for this signature in database
GPG key ID: EA41D161A3C1BC99
22 changed files with 256 additions and 185 deletions

View file

@ -199,15 +199,10 @@ pub fn fmt_module_header<'a>(buf: &mut Buf, header: &'a ModuleHeader<'a>) {
pub fn fmt_hosted_header<'a>(buf: &mut Buf, header: &'a HostedHeader<'a>) {
buf.indent(0);
buf.push_str("hosted");
let indent = INDENT;
fmt_default_spaces(buf, header.before_name, indent);
buf.push_str(header.name.value.as_str());
let indent = fmt_spaces_with_outdent(buf, header.before_exposes, 0);
header.exposes.keyword.format(buf, indent);
fmt_exposes(buf, header.exposes.item, indent);
header.imports.keyword.format(buf, indent);
fmt_imports(buf, header.imports.item, indent);
fmt_exposes(buf, header.exposes, indent);
}
pub fn fmt_app_header<'a>(buf: &mut Buf, header: &'a AppHeader<'a>) {

View file

@ -3952,17 +3952,25 @@ fn parse_header<'a>(
},
parse_state,
)) => {
let module_name = match opt_expected_module_name {
Some(pq_name) => arena.alloc_str(pq_name.as_inner().as_str()),
None => {
// [modules-revamp] [privacy-changes] TODO: Support test/check on nested modules
arena.alloc_str(filename.file_stem().unwrap().to_str().unwrap())
}
};
let info = HeaderInfo {
filename,
is_root_module,
opt_shorthand,
packages: &[],
header_type: HeaderType::Hosted {
name: header.name.value,
exposes: unspace(arena, header.exposes.item.items),
name: roc_parse::header::ModuleName::new(module_name),
exposes: unspace(arena, header.exposes.items),
},
module_comments: comments,
header_imports: Some(header.imports),
header_imports: header.old_imports,
};
let (module_id, _, header) =

View file

@ -172,7 +172,14 @@ impl<'a> Header<'a> {
}),
Self::header_imports_to_defs(arena, header.old_imports),
),
Header::Package(_) | Header::Platform(_) | Header::Hosted(_) => (self, Defs::default()),
Header::Hosted(header) => (
Header::Hosted(HostedHeader {
old_imports: None,
..header
}),
Self::header_imports_to_defs(arena, header.old_imports),
),
Header::Package(_) | Header::Platform(_) => (self, Defs::default()),
};
(header, defs)

View file

@ -103,7 +103,7 @@ pub fn header<'a>() -> impl Parser<'a, SpacesBefore<'a, Header<'a>>, EHeader<'a>
map(
skip_first(
keyword("hosted", EHeader::Start),
increment_min_indent(hosted_header())
increment_min_indent(one_of![hosted_header(), old_hosted_header()])
),
Header::Hosted
),
@ -184,15 +184,38 @@ fn imports_none_if_empty(value: ImportsKeywordItem<'_>) -> Option<ImportsKeyword
#[inline(always)]
fn hosted_header<'a>() -> impl Parser<'a, HostedHeader<'a>, EHeader<'a>> {
record!(HostedHeader {
before_name: space0_e(EHeader::IndentStart),
name: loc(module_name_help(EHeader::ModuleName)),
exposes: specialize_err(EHeader::Exposes, exposes_values_kw()),
imports: specialize_err(EHeader::Imports, imports()),
})
map(
and(
backtrackable(space0_e(EHeader::IndentStart)),
specialize_err(EHeader::Exposes, exposes_list()),
),
|(before_exposes, exposes)| HostedHeader {
before_exposes,
exposes,
old_imports: None,
},
)
.trace("hosted_header")
}
#[inline(always)]
fn old_hosted_header<'a>() -> impl Parser<'a, HostedHeader<'a>, EHeader<'a>> {
map(
record!(OldHostedHeader {
before_name: space0_e(EHeader::IndentStart),
name: loc(module_name_help(EHeader::ModuleName)),
exposes: specialize_err(EHeader::Exposes, exposes_values_kw()),
imports: specialize_err(EHeader::Imports, imports()),
}),
|old_hosted| HostedHeader {
before_exposes: old_hosted.before_name,
exposes: old_hosted.exposes.item,
old_imports: Some(old_hosted.imports),
},
)
.trace("old_hosted_header")
}
fn chomp_module_name(buffer: &[u8]) -> Result<&str, Progress> {
use encode_unicode::CharExt;
@ -1196,6 +1219,15 @@ pub type ImportsCollection<'a> = Collection<'a, Loc<Spaced<'a, ImportsEntry<'a>>
#[derive(Clone, Debug, PartialEq)]
pub struct HostedHeader<'a> {
pub before_exposes: &'a [CommentOrNewline<'a>],
pub exposes: Collection<'a, Loc<Spaced<'a, ExposedName<'a>>>>,
// Keeping this so we can format old interface header into module headers
pub old_imports: Option<KeywordItem<'a, ImportsKeyword, ImportsCollection<'a>>>,
}
#[derive(Clone, Debug, PartialEq)]
pub struct OldHostedHeader<'a> {
pub before_name: &'a [CommentOrNewline<'a>],
pub name: Loc<ModuleName<'a>>,
pub exposes: KeywordItem<'a, ExposesKeyword, Collection<'a, Loc<Spaced<'a, ExposedName<'a>>>>>,

View file

@ -172,10 +172,9 @@ impl<'a> Normalize<'a> for Header<'a> {
provides: header.provides.normalize(arena),
}),
Header::Hosted(header) => Header::Hosted(HostedHeader {
before_name: &[],
name: header.name.normalize(arena),
before_exposes: &[],
exposes: header.exposes.normalize(arena),
imports: header.imports.normalize(arena),
old_imports: None,
}),
}
}

View file

@ -2,26 +2,9 @@ SpacesBefore {
before: [],
item: Hosted(
HostedHeader {
before_name: [],
name: @7-10 ModuleName(
"Foo",
),
exposes: KeywordItem {
keyword: Spaces {
before: [],
item: ExposesKeyword,
after: [],
},
item: [],
},
imports: KeywordItem {
keyword: Spaces {
before: [],
item: ImportsKeyword,
after: [],
},
item: [],
},
before_exposes: [],
exposes: [],
old_imports: None,
},
),
}

View file

@ -1 +1 @@
hosted Foo exposes [] imports []
hosted []

View file

@ -0,0 +1,19 @@
SpacesBefore {
before: [],
item: Hosted(
HostedHeader {
before_exposes: [],
exposes: [],
old_imports: Some(
KeywordItem {
keyword: Spaces {
before: [],
item: ImportsKeyword,
after: [],
},
item: [],
},
),
},
),
}

View file

@ -0,0 +1 @@
hosted Foo exposes [] imports []

View file

@ -1,12 +1,5 @@
hosted Foo
exposes
[
Stuff,
Things,
somethingElse,
]
imports
[
Blah,
Baz.{ stuff, things },
]
hosted [
Stuff,
Things,
somethingElse,
]

View file

@ -2,99 +2,29 @@ SpacesBefore {
before: [],
item: Hosted(
HostedHeader {
before_name: [],
name: @7-10 ModuleName(
"Foo",
),
exposes: KeywordItem {
keyword: Spaces {
before: [
Newline,
],
item: ExposesKeyword,
after: [
Newline,
],
},
item: Collection {
items: [
@45-50 SpaceBefore(
ExposedName(
"Stuff",
),
[
Newline,
],
before_exposes: [],
exposes: Collection {
items: [
@8-13 ExposedName(
"Stuff",
),
@15-21 ExposedName(
"Things",
),
@27-40 SpaceBefore(
ExposedName(
"somethingElse",
),
@64-70 SpaceBefore(
ExposedName(
"Things",
),
[
Newline,
],
),
@84-97 SpaceBefore(
ExposedName(
"somethingElse",
),
[
Newline,
],
),
],
final_comments: [
Newline,
],
},
},
imports: KeywordItem {
keyword: Spaces {
before: [
Newline,
],
item: ImportsKeyword,
after: [
Newline,
],
},
item: Collection {
items: [
@143-147 SpaceBefore(
Module(
ModuleName(
"Blah",
),
[],
),
[
Newline,
],
),
@161-182 SpaceBefore(
Module(
ModuleName(
"Baz",
),
[
@167-172 ExposedName(
"stuff",
),
@174-180 ExposedName(
"things",
),
],
),
[
Newline,
],
),
],
final_comments: [
Newline,
],
},
[
Newline,
],
),
],
final_comments: [
Newline,
],
},
old_imports: None,
},
),
}

View file

@ -1,12 +1,3 @@
hosted Foo
exposes
[
Stuff,
Things,
somethingElse,
]
imports
[
Blah,
Baz.{ stuff, things },
]
hosted [Stuff, Things,
somethingElse,
]

View file

@ -0,0 +1,5 @@
hosted [
Stuff,
Things,
somethingElse,
]

View file

@ -0,0 +1,88 @@
SpacesBefore {
before: [],
item: Hosted(
HostedHeader {
before_exposes: [],
exposes: Collection {
items: [
@45-50 SpaceBefore(
ExposedName(
"Stuff",
),
[
Newline,
],
),
@64-70 SpaceBefore(
ExposedName(
"Things",
),
[
Newline,
],
),
@84-97 SpaceBefore(
ExposedName(
"somethingElse",
),
[
Newline,
],
),
],
final_comments: [
Newline,
],
},
old_imports: Some(
KeywordItem {
keyword: Spaces {
before: [
Newline,
],
item: ImportsKeyword,
after: [
Newline,
],
},
item: Collection {
items: [
@143-147 SpaceBefore(
Module(
ModuleName(
"Blah",
),
[],
),
[
Newline,
],
),
@161-182 SpaceBefore(
Module(
ModuleName(
"Baz",
),
[
@167-172 ExposedName(
"stuff",
),
@174-180 ExposedName(
"things",
),
],
),
[
Newline,
],
),
],
final_comments: [
Newline,
],
},
},
),
},
),
}

View file

@ -0,0 +1,12 @@
hosted Foo
exposes
[
Stuff,
Things,
somethingElse,
]
imports
[
Blah,
Baz.{ stuff, things },
]

View file

@ -5813,27 +5813,40 @@ mod test_fmt {
#[test]
fn single_line_hosted() {
module_formats_same(indoc!(
r"
hosted Foo exposes [] imports []"
));
module_formats_to(
indoc!(
r"
hosted Foo exposes [] imports []"
),
indoc!(
r"
hosted []"
),
);
}
#[test]
fn multi_line_hosted() {
module_formats_same(indoc!(
r"
hosted Foo
exposes [
module_formats_to(
indoc!(
r"
hosted Foo
exposes [
Stuff,
Things,
somethingElse,
]
imports []"
),
indoc!(
r"
hosted [
Stuff,
Things,
somethingElse,
]
imports [
Blah,
Baz.{ stuff, things },
]"
));
),
);
}
/// Annotations and aliases

View file

@ -436,6 +436,7 @@ mod test_snapshots {
pass/empty_hosted_header.header,
pass/empty_list.expr,
pass/empty_module_header.header,
pass/empty_old_hosted_header.header,
pass/empty_package_header.header,
pass/empty_platform_header.header,
pass/empty_record.expr,
@ -589,6 +590,7 @@ mod test_snapshots {
pass/newline_singleton_list.expr,
pass/no_newline_after_implements.expr,
pass/nonempty_hosted_header.header,
pass/nonempty_old_hosted_header.header,
pass/nonempty_package_header.header,
pass/nonempty_platform_header.header,
pass/not_double_parens.expr,