mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 14:24:45 +00:00
Extract spacing from parse::header::* items into explicit Spaced enum
This commit is contained in:
parent
86c8764012
commit
0786e554c6
11 changed files with 378 additions and 470 deletions
|
@ -7,11 +7,11 @@ use roc_fmt::module::fmt_module;
|
||||||
use roc_fmt::Buf;
|
use roc_fmt::Buf;
|
||||||
use roc_module::called_via::{BinOp, UnaryOp};
|
use roc_module::called_via::{BinOp, UnaryOp};
|
||||||
use roc_parse::ast::{
|
use roc_parse::ast::{
|
||||||
AssignedField, Collection, Expr, Pattern, StrLiteral, StrSegment, Tag, TypeAnnotation,
|
AssignedField, Collection, Expr, Pattern, Spaced, StrLiteral, StrSegment, Tag, TypeAnnotation,
|
||||||
WhenBranch,
|
WhenBranch,
|
||||||
};
|
};
|
||||||
use roc_parse::header::{
|
use roc_parse::header::{
|
||||||
AppHeader, Effects, ExposesEntry, ImportsEntry, InterfaceHeader, ModuleName, PackageEntry,
|
AppHeader, Effects, ExposedName, ImportsEntry, InterfaceHeader, ModuleName, PackageEntry,
|
||||||
PackageName, PackageOrPath, PlatformHeader, PlatformRequires, PlatformRigid, To, TypedIdent,
|
PackageName, PackageOrPath, PlatformHeader, PlatformRequires, PlatformRigid, To, TypedIdent,
|
||||||
};
|
};
|
||||||
use roc_parse::{
|
use roc_parse::{
|
||||||
|
@ -228,16 +228,22 @@ impl<'a> RemoveSpaces<'a> for &'a str {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: RemoveSpaces<'a> + Copy> RemoveSpaces<'a> for ExposesEntry<'a, T> {
|
impl<'a, T: RemoveSpaces<'a> + Copy> RemoveSpaces<'a> for Spaced<'a, T> {
|
||||||
fn remove_spaces(&self, arena: &'a Bump) -> Self {
|
fn remove_spaces(&self, arena: &'a Bump) -> Self {
|
||||||
match *self {
|
match *self {
|
||||||
ExposesEntry::Exposed(a) => ExposesEntry::Exposed(a.remove_spaces(arena)),
|
Spaced::Item(a) => Spaced::Item(a.remove_spaces(arena)),
|
||||||
ExposesEntry::SpaceBefore(a, _) => a.remove_spaces(arena),
|
Spaced::SpaceBefore(a, _) => a.remove_spaces(arena),
|
||||||
ExposesEntry::SpaceAfter(a, _) => a.remove_spaces(arena),
|
Spaced::SpaceAfter(a, _) => a.remove_spaces(arena),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> RemoveSpaces<'a> for ExposedName<'a> {
|
||||||
|
fn remove_spaces(&self, _arena: &'a Bump) -> Self {
|
||||||
|
*self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> RemoveSpaces<'a> for ModuleName<'a> {
|
impl<'a> RemoveSpaces<'a> for ModuleName<'a> {
|
||||||
fn remove_spaces(&self, _arena: &'a Bump) -> Self {
|
fn remove_spaces(&self, _arena: &'a Bump) -> Self {
|
||||||
*self
|
*self
|
||||||
|
@ -261,18 +267,10 @@ impl<'a> RemoveSpaces<'a> for To<'a> {
|
||||||
|
|
||||||
impl<'a> RemoveSpaces<'a> for TypedIdent<'a> {
|
impl<'a> RemoveSpaces<'a> for TypedIdent<'a> {
|
||||||
fn remove_spaces(&self, arena: &'a Bump) -> Self {
|
fn remove_spaces(&self, arena: &'a Bump) -> Self {
|
||||||
match *self {
|
TypedIdent {
|
||||||
TypedIdent::Entry {
|
ident: self.ident.remove_spaces(arena),
|
||||||
ident,
|
|
||||||
spaces_before_colon: _,
|
|
||||||
ann,
|
|
||||||
} => TypedIdent::Entry {
|
|
||||||
ident: ident.remove_spaces(arena),
|
|
||||||
spaces_before_colon: &[],
|
spaces_before_colon: &[],
|
||||||
ann: ann.remove_spaces(arena),
|
ann: self.ann.remove_spaces(arena),
|
||||||
},
|
|
||||||
TypedIdent::SpaceBefore(a, _) => a.remove_spaces(arena),
|
|
||||||
TypedIdent::SpaceAfter(a, _) => a.remove_spaces(arena),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -287,29 +285,17 @@ impl<'a> RemoveSpaces<'a> for PlatformRequires<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> RemoveSpaces<'a> for PlatformRigid<'a> {
|
impl<'a> RemoveSpaces<'a> for PlatformRigid<'a> {
|
||||||
fn remove_spaces(&self, arena: &'a Bump) -> Self {
|
fn remove_spaces(&self, _arena: &'a Bump) -> Self {
|
||||||
match *self {
|
*self
|
||||||
PlatformRigid::Entry { rigid, alias } => PlatformRigid::Entry { rigid, alias },
|
|
||||||
PlatformRigid::SpaceBefore(a, _) => a.remove_spaces(arena),
|
|
||||||
PlatformRigid::SpaceAfter(a, _) => a.remove_spaces(arena),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> RemoveSpaces<'a> for PackageEntry<'a> {
|
impl<'a> RemoveSpaces<'a> for PackageEntry<'a> {
|
||||||
fn remove_spaces(&self, arena: &'a Bump) -> Self {
|
fn remove_spaces(&self, arena: &'a Bump) -> Self {
|
||||||
match *self {
|
PackageEntry {
|
||||||
PackageEntry::Entry {
|
shorthand: self.shorthand,
|
||||||
shorthand,
|
|
||||||
spaces_after_shorthand: _,
|
|
||||||
package_or_path,
|
|
||||||
} => PackageEntry::Entry {
|
|
||||||
shorthand,
|
|
||||||
spaces_after_shorthand: &[],
|
spaces_after_shorthand: &[],
|
||||||
package_or_path: package_or_path.remove_spaces(arena),
|
package_or_path: self.package_or_path.remove_spaces(arena),
|
||||||
},
|
|
||||||
PackageEntry::SpaceBefore(a, _) => a.remove_spaces(arena),
|
|
||||||
PackageEntry::SpaceAfter(a, _) => a.remove_spaces(arena),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -328,8 +314,6 @@ impl<'a> RemoveSpaces<'a> for ImportsEntry<'a> {
|
||||||
match *self {
|
match *self {
|
||||||
ImportsEntry::Module(a, b) => ImportsEntry::Module(a, b.remove_spaces(arena)),
|
ImportsEntry::Module(a, b) => ImportsEntry::Module(a, b.remove_spaces(arena)),
|
||||||
ImportsEntry::Package(a, b, c) => ImportsEntry::Package(a, b, c.remove_spaces(arena)),
|
ImportsEntry::Package(a, b, c) => ImportsEntry::Package(a, b, c.remove_spaces(arena)),
|
||||||
ImportsEntry::SpaceBefore(a, _) => a.remove_spaces(arena),
|
|
||||||
ImportsEntry::SpaceAfter(a, _) => a.remove_spaces(arena),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,7 +83,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A Located formattable value is also formattable
|
/// A Located formattable value is also formattable
|
||||||
impl<'a, T> Formattable for Located<T>
|
impl<T> Formattable for Located<T>
|
||||||
where
|
where
|
||||||
T: Formattable,
|
T: Formattable,
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,9 +3,9 @@ use crate::collection::fmt_collection;
|
||||||
use crate::expr::fmt_str_literal;
|
use crate::expr::fmt_str_literal;
|
||||||
use crate::spaces::{fmt_default_spaces, fmt_spaces, INDENT};
|
use crate::spaces::{fmt_default_spaces, fmt_spaces, INDENT};
|
||||||
use crate::Buf;
|
use crate::Buf;
|
||||||
use roc_parse::ast::{Collection, Module};
|
use roc_parse::ast::{Collection, Module, Spaced};
|
||||||
use roc_parse::header::{
|
use roc_parse::header::{
|
||||||
AppHeader, Effects, ExposesEntry, ImportsEntry, InterfaceHeader, ModuleName, PackageEntry,
|
AppHeader, Effects, ExposedName, ImportsEntry, InterfaceHeader, ModuleName, PackageEntry,
|
||||||
PackageName, PackageOrPath, PlatformHeader, PlatformRequires, PlatformRigid, To, TypedIdent,
|
PackageName, PackageOrPath, PlatformHeader, PlatformRequires, PlatformRigid, To, TypedIdent,
|
||||||
};
|
};
|
||||||
use roc_region::all::Located;
|
use roc_region::all::Located;
|
||||||
|
@ -135,7 +135,7 @@ fn fmt_requires<'a, 'buf>(buf: &mut Buf<'buf>, requires: &PlatformRequires<'a>,
|
||||||
fmt_collection(buf, indent, '{', '}', requires.rigids, Newlines::No);
|
fmt_collection(buf, indent, '{', '}', requires.rigids, Newlines::No);
|
||||||
|
|
||||||
buf.push_str(" { ");
|
buf.push_str(" { ");
|
||||||
fmt_typed_ident(buf, &requires.signature.value, indent);
|
requires.signature.value.format(buf, indent);
|
||||||
buf.push_str(" }");
|
buf.push_str(" }");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,48 +155,17 @@ fn fmt_effects<'a, 'buf>(buf: &mut Buf<'buf>, effects: &Effects<'a>, indent: u16
|
||||||
fmt_collection(buf, indent, '{', '}', effects.entries, Newlines::No)
|
fmt_collection(buf, indent, '{', '}', effects.entries, Newlines::No)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fmt_typed_ident<'a, 'buf>(buf: &mut Buf<'buf>, entry: &TypedIdent<'a>, indent: u16) {
|
|
||||||
use TypedIdent::*;
|
|
||||||
match entry {
|
|
||||||
Entry {
|
|
||||||
ident,
|
|
||||||
spaces_before_colon,
|
|
||||||
ann,
|
|
||||||
} => {
|
|
||||||
buf.indent(indent);
|
|
||||||
buf.push_str(ident.value);
|
|
||||||
fmt_default_spaces(buf, spaces_before_colon, " ", indent);
|
|
||||||
buf.push_str(": ");
|
|
||||||
ann.value.format(buf, indent);
|
|
||||||
}
|
|
||||||
SpaceBefore(sub_entry, spaces) => {
|
|
||||||
fmt_spaces(buf, spaces.iter(), indent);
|
|
||||||
fmt_typed_ident(buf, sub_entry, indent);
|
|
||||||
}
|
|
||||||
SpaceAfter(sub_entry, spaces) => {
|
|
||||||
fmt_typed_ident(buf, sub_entry, indent);
|
|
||||||
fmt_spaces(buf, spaces.iter(), indent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Formattable for TypedIdent<'a> {
|
impl<'a> Formattable for TypedIdent<'a> {
|
||||||
fn is_multiline(&self) -> bool {
|
fn is_multiline(&self) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn format<'buf>(&self, buf: &mut Buf<'buf>, indent: u16) {
|
fn format<'buf>(&self, buf: &mut Buf<'buf>, indent: u16) {
|
||||||
fmt_typed_ident(buf, self, indent);
|
buf.indent(indent);
|
||||||
}
|
buf.push_str(self.ident.value);
|
||||||
}
|
fmt_default_spaces(buf, self.spaces_before_colon, " ", indent);
|
||||||
|
buf.push_str(": ");
|
||||||
impl<'a> Formattable for PlatformRigid<'a> {
|
self.ann.value.format(buf, indent);
|
||||||
fn is_multiline(&self) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn format<'buf>(&self, buf: &mut Buf<'buf>, indent: u16) {
|
|
||||||
fmt_platform_rigid(buf, self, indent);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,30 +175,50 @@ fn fmt_package_name<'buf>(buf: &mut Buf<'buf>, name: PackageName) {
|
||||||
buf.push_str(name.pkg);
|
buf.push_str(name.pkg);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fmt_platform_rigid<'a, 'buf>(buf: &mut Buf<'buf>, entry: &PlatformRigid<'a>, indent: u16) {
|
impl<'a, T: Formattable> Formattable for Spaced<'a, T> {
|
||||||
use roc_parse::header::PlatformRigid::*;
|
fn is_multiline(&self) -> bool {
|
||||||
|
// TODO
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
match entry {
|
fn format_with_options<'buf>(
|
||||||
Entry { rigid, alias } => {
|
&self,
|
||||||
buf.push_str(rigid);
|
buf: &mut Buf<'buf>,
|
||||||
|
parens: crate::annotation::Parens,
|
||||||
|
newlines: Newlines,
|
||||||
|
indent: u16,
|
||||||
|
) {
|
||||||
|
match self {
|
||||||
|
Spaced::Item(item) => {
|
||||||
|
item.format_with_options(buf, parens, newlines, indent);
|
||||||
|
}
|
||||||
|
Spaced::SpaceBefore(item, spaces) => {
|
||||||
|
fmt_spaces(buf, spaces.iter(), indent);
|
||||||
|
item.format_with_options(buf, parens, newlines, indent);
|
||||||
|
}
|
||||||
|
Spaced::SpaceAfter(item, spaces) => {
|
||||||
|
item.format_with_options(buf, parens, newlines, indent);
|
||||||
|
fmt_spaces(buf, spaces.iter(), indent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Formattable for PlatformRigid<'a> {
|
||||||
|
fn is_multiline(&self) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn format<'buf>(&self, buf: &mut Buf<'buf>, _indent: u16) {
|
||||||
|
buf.push_str(self.rigid);
|
||||||
buf.push_str("=>");
|
buf.push_str("=>");
|
||||||
buf.push_str(alias);
|
buf.push_str(self.alias);
|
||||||
}
|
|
||||||
|
|
||||||
SpaceBefore(sub_entry, spaces) => {
|
|
||||||
fmt_spaces(buf, spaces.iter(), indent);
|
|
||||||
fmt_platform_rigid(buf, sub_entry, indent);
|
|
||||||
}
|
|
||||||
SpaceAfter(sub_entry, spaces) => {
|
|
||||||
fmt_platform_rigid(buf, sub_entry, indent);
|
|
||||||
fmt_spaces(buf, spaces.iter(), indent);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fmt_imports<'a, 'buf>(
|
fn fmt_imports<'a, 'buf>(
|
||||||
buf: &mut Buf<'buf>,
|
buf: &mut Buf<'buf>,
|
||||||
loc_entries: Collection<'a, Located<ImportsEntry<'a>>>,
|
loc_entries: Collection<'a, Located<Spaced<'a, ImportsEntry<'a>>>>,
|
||||||
indent: u16,
|
indent: u16,
|
||||||
) {
|
) {
|
||||||
fmt_collection(buf, indent, '[', ']', loc_entries, Newlines::No)
|
fmt_collection(buf, indent, '[', ']', loc_entries, Newlines::No)
|
||||||
|
@ -237,7 +226,7 @@ fn fmt_imports<'a, 'buf>(
|
||||||
|
|
||||||
fn fmt_provides<'a, 'buf>(
|
fn fmt_provides<'a, 'buf>(
|
||||||
buf: &mut Buf<'buf>,
|
buf: &mut Buf<'buf>,
|
||||||
loc_entries: Collection<'a, Located<ExposesEntry<'a, &'a str>>>,
|
loc_entries: Collection<'a, Located<Spaced<'a, ExposedName<'a>>>>,
|
||||||
indent: u16,
|
indent: u16,
|
||||||
) {
|
) {
|
||||||
fmt_collection(buf, indent, '[', ']', loc_entries, Newlines::No)
|
fmt_collection(buf, indent, '[', ']', loc_entries, Newlines::No)
|
||||||
|
@ -252,24 +241,14 @@ fn fmt_to<'buf>(buf: &mut Buf<'buf>, to: To, indent: u16) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fmt_exposes<'a, 'buf, N: FormatName + Copy + 'a>(
|
fn fmt_exposes<'buf, N: Formattable + Copy>(
|
||||||
buf: &mut Buf<'buf>,
|
buf: &mut Buf<'buf>,
|
||||||
loc_entries: Collection<'_, Located<ExposesEntry<'_, N>>>,
|
loc_entries: Collection<'_, Located<Spaced<'_, N>>>,
|
||||||
indent: u16,
|
indent: u16,
|
||||||
) {
|
) {
|
||||||
fmt_collection(buf, indent, '[', ']', loc_entries, Newlines::No)
|
fmt_collection(buf, indent, '[', ']', loc_entries, Newlines::No)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, N: FormatName> Formattable for ExposesEntry<'a, N> {
|
|
||||||
fn is_multiline(&self) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn format<'buf>(&self, buf: &mut Buf<'buf>, indent: u16) {
|
|
||||||
fmt_exposes_entry(buf, self, indent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait FormatName {
|
pub trait FormatName {
|
||||||
fn format<'buf>(&self, buf: &mut Buf<'buf>);
|
fn format<'buf>(&self, buf: &mut Buf<'buf>);
|
||||||
}
|
}
|
||||||
|
@ -286,30 +265,35 @@ impl<'a> FormatName for ModuleName<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fmt_exposes_entry<'a, 'buf, N: FormatName>(
|
impl<'a> Formattable for ModuleName<'a> {
|
||||||
buf: &mut Buf<'buf>,
|
fn is_multiline(&self) -> bool {
|
||||||
entry: &ExposesEntry<'a, N>,
|
false
|
||||||
indent: u16,
|
|
||||||
) {
|
|
||||||
use roc_parse::header::ExposesEntry::*;
|
|
||||||
|
|
||||||
match entry {
|
|
||||||
Exposed(ident) => ident.format(buf),
|
|
||||||
|
|
||||||
SpaceBefore(sub_entry, spaces) => {
|
|
||||||
fmt_spaces(buf, spaces.iter(), indent);
|
|
||||||
fmt_exposes_entry(buf, sub_entry, indent);
|
|
||||||
}
|
}
|
||||||
SpaceAfter(sub_entry, spaces) => {
|
|
||||||
fmt_exposes_entry(buf, sub_entry, indent);
|
fn format<'buf>(&self, buf: &mut Buf<'buf>, _indent: u16) {
|
||||||
fmt_spaces(buf, spaces.iter(), indent);
|
buf.push_str(self.as_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> Formattable for ExposedName<'a> {
|
||||||
|
fn is_multiline(&self) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn format<'buf>(&self, buf: &mut Buf<'buf>, _indent: u16) {
|
||||||
|
buf.push_str(self.as_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> FormatName for ExposedName<'a> {
|
||||||
|
fn format<'buf>(&self, buf: &mut Buf<'buf>) {
|
||||||
|
buf.push_str(self.as_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fmt_packages<'a, 'buf>(
|
fn fmt_packages<'a, 'buf>(
|
||||||
buf: &mut Buf<'buf>,
|
buf: &mut Buf<'buf>,
|
||||||
loc_entries: Collection<'a, Located<PackageEntry<'a>>>,
|
loc_entries: Collection<'a, Located<Spaced<'a, PackageEntry<'a>>>>,
|
||||||
indent: u16,
|
indent: u16,
|
||||||
) {
|
) {
|
||||||
fmt_collection(buf, indent, '{', '}', loc_entries, Newlines::No)
|
fmt_collection(buf, indent, '{', '}', loc_entries, Newlines::No)
|
||||||
|
@ -335,27 +319,10 @@ impl<'a> Formattable for ImportsEntry<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn fmt_packages_entry<'a, 'buf>(buf: &mut Buf<'buf>, entry: &PackageEntry<'a>, indent: u16) {
|
fn fmt_packages_entry<'a, 'buf>(buf: &mut Buf<'buf>, entry: &PackageEntry<'a>, indent: u16) {
|
||||||
use PackageEntry::*;
|
buf.push_str(entry.shorthand);
|
||||||
match entry {
|
|
||||||
Entry {
|
|
||||||
shorthand,
|
|
||||||
spaces_after_shorthand,
|
|
||||||
package_or_path,
|
|
||||||
} => {
|
|
||||||
buf.push_str(shorthand);
|
|
||||||
buf.push(':');
|
buf.push(':');
|
||||||
fmt_default_spaces(buf, spaces_after_shorthand, " ", indent);
|
fmt_default_spaces(buf, entry.spaces_after_shorthand, " ", indent);
|
||||||
fmt_package_or_path(buf, &package_or_path.value, indent);
|
fmt_package_or_path(buf, &entry.package_or_path.value, indent);
|
||||||
}
|
|
||||||
SpaceBefore(sub_entry, spaces) => {
|
|
||||||
fmt_spaces(buf, spaces.iter(), indent);
|
|
||||||
fmt_packages_entry(buf, sub_entry, indent);
|
|
||||||
}
|
|
||||||
SpaceAfter(sub_entry, spaces) => {
|
|
||||||
fmt_packages_entry(buf, sub_entry, indent);
|
|
||||||
fmt_spaces(buf, spaces.iter(), indent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fmt_package_or_path<'a, 'buf>(
|
fn fmt_package_or_path<'a, 'buf>(
|
||||||
|
@ -396,14 +363,5 @@ fn fmt_imports_entry<'a, 'buf>(buf: &mut Buf<'buf>, entry: &ImportsEntry<'a>, in
|
||||||
fmt_collection(buf, indent, '{', '}', *entries, Newlines::No)
|
fmt_collection(buf, indent, '{', '}', *entries, Newlines::No)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SpaceBefore(sub_entry, spaces) => {
|
|
||||||
fmt_spaces(buf, spaces.iter(), indent);
|
|
||||||
fmt_imports_entry(buf, sub_entry, indent);
|
|
||||||
}
|
|
||||||
SpaceAfter(sub_entry, spaces) => {
|
|
||||||
fmt_imports_entry(buf, sub_entry, indent);
|
|
||||||
fmt_spaces(buf, spaces.iter(), indent);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,14 +23,13 @@ use roc_mono::ir::{
|
||||||
UpdateModeIds,
|
UpdateModeIds,
|
||||||
};
|
};
|
||||||
use roc_mono::layout::{Layout, LayoutCache, LayoutProblem};
|
use roc_mono::layout::{Layout, LayoutCache, LayoutProblem};
|
||||||
use roc_parse::ast::{self, ExtractSpaces, StrLiteral, TypeAnnotation};
|
use roc_parse::ast::{self, ExtractSpaces, Spaced, StrLiteral, TypeAnnotation};
|
||||||
use roc_parse::header::{
|
use roc_parse::header::{
|
||||||
ExposesEntry, ImportsEntry, PackageEntry, PackageOrPath, PlatformHeader, To, TypedIdent,
|
ExposedName, ImportsEntry, PackageEntry, PackageOrPath, PlatformHeader, To, TypedIdent,
|
||||||
};
|
};
|
||||||
use roc_parse::module::module_defs;
|
use roc_parse::module::module_defs;
|
||||||
use roc_parse::parser::{self, ParseProblem, Parser, SyntaxError};
|
use roc_parse::parser::{self, ParseProblem, Parser, SyntaxError};
|
||||||
use roc_region::all::{Located, Region};
|
use roc_region::all::{Located, Region};
|
||||||
use roc_reporting::internal_error;
|
|
||||||
use roc_solve::module::SolvedModule;
|
use roc_solve::module::SolvedModule;
|
||||||
use roc_solve::solve;
|
use roc_solve::solve;
|
||||||
use roc_types::solved_types::Solved;
|
use roc_types::solved_types::Solved;
|
||||||
|
@ -2603,19 +2602,18 @@ fn parse_header<'a>(
|
||||||
|
|
||||||
match header.to.value {
|
match header.to.value {
|
||||||
To::ExistingPackage(existing_package) => {
|
To::ExistingPackage(existing_package) => {
|
||||||
let opt_base_package = packages.iter().find(|loc_package_entry| {
|
let opt_base_package = packages.iter().find_map(|loc_package_entry| {
|
||||||
let Located { value, .. } = loc_package_entry;
|
let Located { value, .. } = loc_package_entry;
|
||||||
|
|
||||||
match value.extract_spaces().item {
|
let item = value.extract_spaces().item;
|
||||||
PackageEntry::Entry { shorthand, .. } => shorthand == existing_package,
|
if item.shorthand == existing_package {
|
||||||
_ => internal_error!(),
|
Some(item)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
match opt_base_package {
|
if let Some(PackageEntry {
|
||||||
Some(Located {
|
|
||||||
value:
|
|
||||||
PackageEntry::Entry {
|
|
||||||
shorthand,
|
shorthand,
|
||||||
package_or_path:
|
package_or_path:
|
||||||
Located {
|
Located {
|
||||||
|
@ -2623,9 +2621,8 @@ fn parse_header<'a>(
|
||||||
..
|
..
|
||||||
},
|
},
|
||||||
..
|
..
|
||||||
},
|
}) = opt_base_package
|
||||||
..
|
{
|
||||||
}) => {
|
|
||||||
match package_or_path {
|
match package_or_path {
|
||||||
PackageOrPath::Path(StrLiteral::PlainLine(package)) => {
|
PackageOrPath::Path(StrLiteral::PlainLine(package)) => {
|
||||||
// check whether we can find a Package-Config.roc file
|
// check whether we can find a Package-Config.roc file
|
||||||
|
@ -2646,10 +2643,7 @@ fn parse_header<'a>(
|
||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
module_id,
|
module_id,
|
||||||
Msg::Many(vec![
|
Msg::Many(vec![app_module_header_msg, load_pkg_config_msg]),
|
||||||
app_module_header_msg,
|
|
||||||
load_pkg_config_msg,
|
|
||||||
]),
|
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
Ok((module_id, app_module_header_msg))
|
Ok((module_id, app_module_header_msg))
|
||||||
|
@ -2657,8 +2651,8 @@ fn parse_header<'a>(
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
_ => panic!("could not find base"),
|
panic!("could not find base")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
To::NewPackage(package_or_path) => match package_or_path {
|
To::NewPackage(package_or_path) => match package_or_path {
|
||||||
|
@ -2765,9 +2759,9 @@ struct HeaderInfo<'a> {
|
||||||
is_root_module: bool,
|
is_root_module: bool,
|
||||||
opt_shorthand: Option<&'a str>,
|
opt_shorthand: Option<&'a str>,
|
||||||
header_src: &'a str,
|
header_src: &'a str,
|
||||||
packages: &'a [Located<PackageEntry<'a>>],
|
packages: &'a [Located<Spaced<'a, PackageEntry<'a>>>],
|
||||||
exposes: &'a [Located<ExposesEntry<'a, &'a str>>],
|
exposes: &'a [Located<Spaced<'a, ExposedName<'a>>>],
|
||||||
imports: &'a [Located<ImportsEntry<'a>>],
|
imports: &'a [Located<Spaced<'a, ImportsEntry<'a>>>],
|
||||||
to_platform: Option<To<'a>>,
|
to_platform: Option<To<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2900,7 +2894,8 @@ fn send_header<'a>(
|
||||||
// For example, if module A has [ B.{ foo } ], then
|
// For example, if module A has [ B.{ foo } ], then
|
||||||
// when we get here for B, `foo` will already have
|
// when we get here for B, `foo` will already have
|
||||||
// an IdentId. We must reuse that!
|
// an IdentId. We must reuse that!
|
||||||
let ident_id = ident_ids.get_or_insert(&loc_exposed.value.as_str().into());
|
let ident_id =
|
||||||
|
ident_ids.get_or_insert(&loc_exposed.value.extract_spaces().item.as_str().into());
|
||||||
let symbol = Symbol::new(home, ident_id);
|
let symbol = Symbol::new(home, ident_id);
|
||||||
|
|
||||||
exposed.push(symbol);
|
exposed.push(symbol);
|
||||||
|
@ -2913,24 +2908,13 @@ fn send_header<'a>(
|
||||||
ident_ids.clone()
|
ident_ids.clone()
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut parse_entries: Vec<_> = packages.iter().map(|x| &x.value).collect();
|
let package_entries = packages
|
||||||
let mut package_entries = MutMap::default();
|
.iter()
|
||||||
|
.map(|pkg| {
|
||||||
while let Some(parse_entry) = parse_entries.pop() {
|
let pkg = pkg.value.extract_spaces().item;
|
||||||
use PackageEntry::*;
|
(pkg.shorthand, pkg.package_or_path.value)
|
||||||
match parse_entry {
|
})
|
||||||
Entry {
|
.collect::<MutMap<_, _>>();
|
||||||
shorthand,
|
|
||||||
package_or_path,
|
|
||||||
..
|
|
||||||
} => {
|
|
||||||
package_entries.insert(*shorthand, package_or_path.value);
|
|
||||||
}
|
|
||||||
SpaceBefore(inner, _) | SpaceAfter(inner, _) => {
|
|
||||||
parse_entries.push(inner);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send the deps to the coordinator thread for processing,
|
// Send the deps to the coordinator thread for processing,
|
||||||
// then continue on to parsing and canonicalizing defs.
|
// then continue on to parsing and canonicalizing defs.
|
||||||
|
@ -2989,15 +2973,14 @@ struct PlatformHeaderInfo<'a> {
|
||||||
header_src: &'a str,
|
header_src: &'a str,
|
||||||
app_module_id: ModuleId,
|
app_module_id: ModuleId,
|
||||||
packages: &'a [Located<PackageEntry<'a>>],
|
packages: &'a [Located<PackageEntry<'a>>],
|
||||||
provides: &'a [Located<ExposesEntry<'a, &'a str>>],
|
provides: &'a [Located<Spaced<'a, ExposedName<'a>>>],
|
||||||
requires: &'a [Located<TypedIdent<'a>>],
|
requires: &'a [Located<TypedIdent<'a>>],
|
||||||
imports: &'a [Located<ImportsEntry<'a>>],
|
imports: &'a [Located<Spaced<'a, ImportsEntry<'a>>>],
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO refactor so more logic is shared with `send_header`
|
// TODO refactor so more logic is shared with `send_header`
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn send_header_two<'a>(
|
fn send_header_two<'a>(
|
||||||
arena: &'a Bump,
|
|
||||||
info: PlatformHeaderInfo<'a>,
|
info: PlatformHeaderInfo<'a>,
|
||||||
parse_state: parser::State<'a>,
|
parse_state: parser::State<'a>,
|
||||||
module_ids: Arc<Mutex<PackageModuleIds<'a>>>,
|
module_ids: Arc<Mutex<PackageModuleIds<'a>>>,
|
||||||
|
@ -3105,15 +3088,17 @@ fn send_header_two<'a>(
|
||||||
.entry(app_module_id)
|
.entry(app_module_id)
|
||||||
.or_insert_with(IdentIds::default);
|
.or_insert_with(IdentIds::default);
|
||||||
|
|
||||||
for (loc_ident, _) in unpack_exposes_entries(arena, requires) {
|
for entry in requires {
|
||||||
let ident: Ident = loc_ident.value.into();
|
let entry = entry.value;
|
||||||
|
|
||||||
|
let ident: Ident = entry.ident.value.into();
|
||||||
let ident_id = ident_ids.get_or_insert(&ident);
|
let ident_id = ident_ids.get_or_insert(&ident);
|
||||||
let symbol = Symbol::new(app_module_id, ident_id);
|
let symbol = Symbol::new(app_module_id, ident_id);
|
||||||
|
|
||||||
// Since this value is exposed, add it to our module's default scope.
|
// Since this value is exposed, add it to our module's default scope.
|
||||||
debug_assert!(!scope.contains_key(&ident.clone()));
|
debug_assert!(!scope.contains_key(&ident.clone()));
|
||||||
|
|
||||||
scope.insert(ident, (symbol, loc_ident.region));
|
scope.insert(ident, (symbol, entry.ident.region));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3133,7 +3118,8 @@ fn send_header_two<'a>(
|
||||||
// For example, if module A has [ B.{ foo } ], then
|
// For example, if module A has [ B.{ foo } ], then
|
||||||
// when we get here for B, `foo` will already have
|
// when we get here for B, `foo` will already have
|
||||||
// an IdentId. We must reuse that!
|
// an IdentId. We must reuse that!
|
||||||
let ident_id = ident_ids.get_or_insert(&loc_exposed.value.as_str().into());
|
let ident_id =
|
||||||
|
ident_ids.get_or_insert(&loc_exposed.value.extract_spaces().item.as_str().into());
|
||||||
let symbol = Symbol::new(home, ident_id);
|
let symbol = Symbol::new(home, ident_id);
|
||||||
|
|
||||||
exposed.push(symbol);
|
exposed.push(symbol);
|
||||||
|
@ -3146,24 +3132,10 @@ fn send_header_two<'a>(
|
||||||
ident_ids.clone()
|
ident_ids.clone()
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut parse_entries: Vec<_> = packages.iter().map(|x| &x.value).collect();
|
let package_entries = packages
|
||||||
let mut package_entries = MutMap::default();
|
.iter()
|
||||||
|
.map(|pkg| (pkg.value.shorthand, pkg.value.package_or_path.value))
|
||||||
while let Some(parse_entry) = parse_entries.pop() {
|
.collect::<MutMap<_, _>>();
|
||||||
use PackageEntry::*;
|
|
||||||
match parse_entry {
|
|
||||||
Entry {
|
|
||||||
shorthand,
|
|
||||||
package_or_path,
|
|
||||||
..
|
|
||||||
} => {
|
|
||||||
package_entries.insert(*shorthand, package_or_path.value);
|
|
||||||
}
|
|
||||||
SpaceBefore(inner, _) | SpaceAfter(inner, _) => {
|
|
||||||
parse_entries.push(inner);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send the deps to the coordinator thread for processing,
|
// Send the deps to the coordinator thread for processing,
|
||||||
// then continue on to parsing and canonicalizing defs.
|
// then continue on to parsing and canonicalizing defs.
|
||||||
|
@ -3174,7 +3146,7 @@ fn send_header_two<'a>(
|
||||||
let module_name = ModuleNameEnum::PkgConfig;
|
let module_name = ModuleNameEnum::PkgConfig;
|
||||||
|
|
||||||
let main_for_host = {
|
let main_for_host = {
|
||||||
let ident_str: Ident = provides[0].value.as_str().into();
|
let ident_str: Ident = provides[0].value.extract_spaces().item.as_str().into();
|
||||||
let ident_id = ident_ids.get_or_insert(&ident_str);
|
let ident_id = ident_ids.get_or_insert(&ident_str);
|
||||||
|
|
||||||
Symbol::new(home, ident_id)
|
Symbol::new(home, ident_id)
|
||||||
|
@ -3355,7 +3327,7 @@ fn fabricate_pkg_config_module<'a>(
|
||||||
header_src: &'a str,
|
header_src: &'a str,
|
||||||
module_timing: ModuleTiming,
|
module_timing: ModuleTiming,
|
||||||
) -> (ModuleId, Msg<'a>) {
|
) -> (ModuleId, Msg<'a>) {
|
||||||
let provides: &'a [Located<ExposesEntry<'a, &'a str>>] = header.provides.items;
|
let provides: &'a [Located<Spaced<'a, ExposedName<'a>>>] = header.provides.items;
|
||||||
|
|
||||||
let info = PlatformHeaderInfo {
|
let info = PlatformHeaderInfo {
|
||||||
filename,
|
filename,
|
||||||
|
@ -3365,12 +3337,14 @@ fn fabricate_pkg_config_module<'a>(
|
||||||
app_module_id,
|
app_module_id,
|
||||||
packages: &[],
|
packages: &[],
|
||||||
provides,
|
provides,
|
||||||
requires: arena.alloc([header.requires.signature]),
|
requires: &*arena.alloc([Located::at(
|
||||||
|
header.requires.signature.region,
|
||||||
|
header.requires.signature.extract_spaces().item,
|
||||||
|
)]),
|
||||||
imports: header.imports.items,
|
imports: header.imports.items,
|
||||||
};
|
};
|
||||||
|
|
||||||
send_header_two(
|
send_header_two(
|
||||||
arena,
|
|
||||||
info,
|
info,
|
||||||
parse_state,
|
parse_state,
|
||||||
module_ids,
|
module_ids,
|
||||||
|
@ -3413,14 +3387,14 @@ fn fabricate_effects_module<'a>(
|
||||||
let mut module_ids = (*module_ids).lock();
|
let mut module_ids = (*module_ids).lock();
|
||||||
|
|
||||||
for exposed in header.exposes.iter() {
|
for exposed in header.exposes.iter() {
|
||||||
if let ExposesEntry::Exposed(module_name) = exposed.value {
|
let module_name = exposed.value.extract_spaces().item;
|
||||||
|
|
||||||
module_ids.get_or_insert(&PQModuleName::Qualified(
|
module_ids.get_or_insert(&PQModuleName::Qualified(
|
||||||
shorthand,
|
shorthand,
|
||||||
module_name.as_str().into(),
|
module_name.as_str().into(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
let exposed_ident_ids = {
|
let exposed_ident_ids = {
|
||||||
// Lock just long enough to perform the minimal operations necessary.
|
// Lock just long enough to perform the minimal operations necessary.
|
||||||
|
@ -3633,33 +3607,16 @@ fn fabricate_effects_module<'a>(
|
||||||
|
|
||||||
fn unpack_exposes_entries<'a>(
|
fn unpack_exposes_entries<'a>(
|
||||||
arena: &'a Bump,
|
arena: &'a Bump,
|
||||||
entries: &'a [Located<TypedIdent<'a>>],
|
entries: &'a [Located<Spaced<'a, TypedIdent<'a>>>],
|
||||||
) -> bumpalo::collections::Vec<'a, (&'a Located<&'a str>, &'a Located<TypeAnnotation<'a>>)> {
|
) -> bumpalo::collections::Vec<'a, (Located<&'a str>, Located<TypeAnnotation<'a>>)> {
|
||||||
use bumpalo::collections::Vec;
|
use bumpalo::collections::Vec;
|
||||||
|
|
||||||
let mut stack: Vec<&TypedIdent> = Vec::with_capacity_in(entries.len(), arena);
|
let iter = entries.iter().map(|entry| {
|
||||||
let mut output = Vec::with_capacity_in(entries.len(), arena);
|
let entry: TypedIdent<'a> = entry.value.extract_spaces().item;
|
||||||
|
(entry.ident, entry.ann)
|
||||||
|
});
|
||||||
|
|
||||||
for entry in entries.iter() {
|
Vec::from_iter_in(iter, arena)
|
||||||
stack.push(&entry.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
while let Some(effects_entry) = stack.pop() {
|
|
||||||
match effects_entry {
|
|
||||||
TypedIdent::Entry {
|
|
||||||
ident,
|
|
||||||
spaces_before_colon: _,
|
|
||||||
ann,
|
|
||||||
} => {
|
|
||||||
output.push((ident, ann));
|
|
||||||
}
|
|
||||||
TypedIdent::SpaceAfter(nested, _) | TypedIdent::SpaceBefore(nested, _) => {
|
|
||||||
stack.push(nested);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
output
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
@ -3816,10 +3773,12 @@ fn parse<'a>(arena: &'a Bump, header: ModuleHeader<'a>) -> Result<Msg<'a>, Loadi
|
||||||
Ok(Msg::Parsed(parsed))
|
Ok(Msg::Parsed(parsed))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn exposed_from_import<'a>(entry: &ImportsEntry<'a>) -> (QualifiedModuleName<'a>, Vec<Ident>) {
|
fn exposed_from_import<'a>(
|
||||||
|
entry: &Spaced<'a, ImportsEntry<'a>>,
|
||||||
|
) -> (QualifiedModuleName<'a>, Vec<Ident>) {
|
||||||
use roc_parse::header::ImportsEntry::*;
|
use roc_parse::header::ImportsEntry::*;
|
||||||
|
|
||||||
match entry {
|
match entry.extract_spaces().item {
|
||||||
Module(module_name, exposes) => {
|
Module(module_name, exposes) => {
|
||||||
let mut exposed = Vec::with_capacity(exposes.len());
|
let mut exposed = Vec::with_capacity(exposes.len());
|
||||||
|
|
||||||
|
@ -3849,21 +3808,11 @@ fn exposed_from_import<'a>(entry: &ImportsEntry<'a>) -> (QualifiedModuleName<'a>
|
||||||
|
|
||||||
(qualified_module_name, exposed)
|
(qualified_module_name, exposed)
|
||||||
}
|
}
|
||||||
|
|
||||||
SpaceBefore(sub_entry, _) | SpaceAfter(sub_entry, _) => {
|
|
||||||
// Ignore spaces.
|
|
||||||
exposed_from_import(*sub_entry)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ident_from_exposed(entry: &ExposesEntry<'_, &str>) -> Ident {
|
fn ident_from_exposed(entry: &Spaced<'_, ExposedName<'_>>) -> Ident {
|
||||||
use roc_parse::header::ExposesEntry::*;
|
entry.extract_spaces().item.as_str().into()
|
||||||
|
|
||||||
match entry {
|
|
||||||
Exposed(ident) => (*ident).into(),
|
|
||||||
SpaceBefore(sub_entry, _) | SpaceAfter(sub_entry, _) => ident_from_exposed(sub_entry),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
use crate::header::{
|
use crate::header::{AppHeader, InterfaceHeader, PlatformHeader};
|
||||||
AppHeader, ExposesEntry, ImportsEntry, InterfaceHeader, PackageEntry, PlatformHeader,
|
|
||||||
PlatformRigid, TypedIdent,
|
|
||||||
};
|
|
||||||
use crate::ident::Ident;
|
use crate::ident::Ident;
|
||||||
use bumpalo::collections::{String, Vec};
|
use bumpalo::collections::{String, Vec};
|
||||||
use bumpalo::Bump;
|
use bumpalo::Bump;
|
||||||
|
@ -17,6 +14,33 @@ pub struct Spaces<'a, T> {
|
||||||
pub after: &'a [CommentOrNewline<'a>],
|
pub after: &'a [CommentOrNewline<'a>],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, PartialEq)]
|
||||||
|
pub enum Spaced<'a, T> {
|
||||||
|
Item(T),
|
||||||
|
|
||||||
|
// Spaces
|
||||||
|
SpaceBefore(&'a Spaced<'a, T>, &'a [CommentOrNewline<'a>]),
|
||||||
|
SpaceAfter(&'a Spaced<'a, T>, &'a [CommentOrNewline<'a>]),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T: Debug> Debug for Spaced<'a, T> {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::Item(item) => item.fmt(f),
|
||||||
|
Self::SpaceBefore(item, space) => f
|
||||||
|
.debug_tuple("SpaceBefore")
|
||||||
|
.field(item)
|
||||||
|
.field(space)
|
||||||
|
.finish(),
|
||||||
|
Self::SpaceAfter(item, space) => f
|
||||||
|
.debug_tuple("SpaceAfter")
|
||||||
|
.field(item)
|
||||||
|
.field(space)
|
||||||
|
.finish(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub trait ExtractSpaces<'a>: Sized + Copy {
|
pub trait ExtractSpaces<'a>: Sized + Copy {
|
||||||
type Item;
|
type Item;
|
||||||
fn extract_spaces(&self) -> Spaces<'a, Self::Item>;
|
fn extract_spaces(&self) -> Spaces<'a, Self::Item>;
|
||||||
|
@ -674,6 +698,15 @@ pub trait Spaceable<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a, T> Spaceable<'a> for Spaced<'a, T> {
|
||||||
|
fn before(&'a self, spaces: &'a [CommentOrNewline<'a>]) -> Self {
|
||||||
|
Spaced::SpaceBefore(self, spaces)
|
||||||
|
}
|
||||||
|
fn after(&'a self, spaces: &'a [CommentOrNewline<'a>]) -> Self {
|
||||||
|
Spaced::SpaceAfter(self, spaces)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> Spaceable<'a> for Expr<'a> {
|
impl<'a> Spaceable<'a> for Expr<'a> {
|
||||||
fn before(&'a self, spaces: &'a [CommentOrNewline<'a>]) -> Self {
|
fn before(&'a self, spaces: &'a [CommentOrNewline<'a>]) -> Self {
|
||||||
Expr::SpaceBefore(self, spaces)
|
Expr::SpaceBefore(self, spaces)
|
||||||
|
@ -701,24 +734,6 @@ impl<'a> Spaceable<'a> for TypeAnnotation<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Spaceable<'a> for ImportsEntry<'a> {
|
|
||||||
fn before(&'a self, spaces: &'a [CommentOrNewline<'a>]) -> Self {
|
|
||||||
ImportsEntry::SpaceBefore(self, spaces)
|
|
||||||
}
|
|
||||||
fn after(&'a self, spaces: &'a [CommentOrNewline<'a>]) -> Self {
|
|
||||||
ImportsEntry::SpaceAfter(self, spaces)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Spaceable<'a> for TypedIdent<'a> {
|
|
||||||
fn before(&'a self, spaces: &'a [CommentOrNewline<'a>]) -> Self {
|
|
||||||
TypedIdent::SpaceBefore(self, spaces)
|
|
||||||
}
|
|
||||||
fn after(&'a self, spaces: &'a [CommentOrNewline<'a>]) -> Self {
|
|
||||||
TypedIdent::SpaceAfter(self, spaces)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, Val> Spaceable<'a> for AssignedField<'a, Val> {
|
impl<'a, Val> Spaceable<'a> for AssignedField<'a, Val> {
|
||||||
fn before(&'a self, spaces: &'a [CommentOrNewline<'a>]) -> Self {
|
fn before(&'a self, spaces: &'a [CommentOrNewline<'a>]) -> Self {
|
||||||
AssignedField::SpaceBefore(self, spaces)
|
AssignedField::SpaceBefore(self, spaces)
|
||||||
|
@ -823,8 +838,55 @@ macro_rules! impl_extract_spaces {
|
||||||
impl_extract_spaces!(Expr);
|
impl_extract_spaces!(Expr);
|
||||||
impl_extract_spaces!(Tag);
|
impl_extract_spaces!(Tag);
|
||||||
impl_extract_spaces!(AssignedField<T>);
|
impl_extract_spaces!(AssignedField<T>);
|
||||||
impl_extract_spaces!(PlatformRigid);
|
|
||||||
impl_extract_spaces!(TypedIdent);
|
impl<'a, T: Copy> ExtractSpaces<'a> for Spaced<'a, T> {
|
||||||
impl_extract_spaces!(ImportsEntry);
|
type Item = T;
|
||||||
impl_extract_spaces!(ExposesEntry<T>);
|
|
||||||
impl_extract_spaces!(PackageEntry);
|
fn extract_spaces(&self) -> Spaces<'a, T> {
|
||||||
|
match self {
|
||||||
|
Spaced::SpaceBefore(item, before) => match item {
|
||||||
|
Spaced::SpaceBefore(_, _) => todo!(),
|
||||||
|
Spaced::SpaceAfter(item, after) => {
|
||||||
|
if let Spaced::Item(item) = item {
|
||||||
|
Spaces {
|
||||||
|
before,
|
||||||
|
item: *item,
|
||||||
|
after,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Spaced::Item(item) => Spaces {
|
||||||
|
before,
|
||||||
|
item: *item,
|
||||||
|
after: &[],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Spaced::SpaceAfter(item, after) => match item {
|
||||||
|
Spaced::SpaceBefore(item, before) => {
|
||||||
|
if let Spaced::Item(item) = item {
|
||||||
|
Spaces {
|
||||||
|
before,
|
||||||
|
item: *item,
|
||||||
|
after,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Spaced::SpaceAfter(_, _) => todo!(),
|
||||||
|
Spaced::Item(item) => Spaces {
|
||||||
|
before: &[],
|
||||||
|
item: *item,
|
||||||
|
after,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Spaced::Item(item) => Spaces {
|
||||||
|
before: &[],
|
||||||
|
item: *item,
|
||||||
|
after: &[],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::ast::{Collection, CommentOrNewline, Spaceable, StrLiteral, TypeAnnotation};
|
use crate::ast::{Collection, CommentOrNewline, Spaced, StrLiteral, TypeAnnotation};
|
||||||
use crate::blankspace::space0_e;
|
use crate::blankspace::space0_e;
|
||||||
use crate::ident::lowercase_ident;
|
use crate::ident::lowercase_ident;
|
||||||
use crate::parser::Progress::{self, *};
|
use crate::parser::Progress::{self, *};
|
||||||
|
@ -57,11 +57,30 @@ impl<'a> ModuleName<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
|
||||||
|
pub struct ExposedName<'a>(&'a str);
|
||||||
|
|
||||||
|
impl<'a> From<ExposedName<'a>> for &'a str {
|
||||||
|
fn from(name: ExposedName<'a>) -> Self {
|
||||||
|
name.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ExposedName<'a> {
|
||||||
|
pub fn new(name: &'a str) -> Self {
|
||||||
|
ExposedName(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_str(&'a self) -> &'a str {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct InterfaceHeader<'a> {
|
pub struct InterfaceHeader<'a> {
|
||||||
pub name: Loc<ModuleName<'a>>,
|
pub name: Loc<ModuleName<'a>>,
|
||||||
pub exposes: Collection<'a, Loc<ExposesEntry<'a, &'a str>>>,
|
pub exposes: Collection<'a, Loc<Spaced<'a, ExposedName<'a>>>>,
|
||||||
pub imports: Collection<'a, Loc<ImportsEntry<'a>>>,
|
pub imports: Collection<'a, Loc<Spaced<'a, ImportsEntry<'a>>>>,
|
||||||
|
|
||||||
// Potential comments and newlines - these will typically all be empty.
|
// Potential comments and newlines - these will typically all be empty.
|
||||||
pub before_header: &'a [CommentOrNewline<'a>],
|
pub before_header: &'a [CommentOrNewline<'a>],
|
||||||
|
@ -81,9 +100,9 @@ pub enum To<'a> {
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct AppHeader<'a> {
|
pub struct AppHeader<'a> {
|
||||||
pub name: Loc<StrLiteral<'a>>,
|
pub name: Loc<StrLiteral<'a>>,
|
||||||
pub packages: Collection<'a, Loc<PackageEntry<'a>>>,
|
pub packages: Collection<'a, Loc<Spaced<'a, PackageEntry<'a>>>>,
|
||||||
pub imports: Collection<'a, Loc<ImportsEntry<'a>>>,
|
pub imports: Collection<'a, Loc<Spaced<'a, ImportsEntry<'a>>>>,
|
||||||
pub provides: Collection<'a, Loc<ExposesEntry<'a, &'a str>>>,
|
pub provides: Collection<'a, Loc<Spaced<'a, ExposedName<'a>>>>,
|
||||||
pub to: Loc<To<'a>>,
|
pub to: Loc<To<'a>>,
|
||||||
|
|
||||||
// Potential comments and newlines - these will typically all be empty.
|
// Potential comments and newlines - these will typically all be empty.
|
||||||
|
@ -102,7 +121,7 @@ pub struct AppHeader<'a> {
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct PackageHeader<'a> {
|
pub struct PackageHeader<'a> {
|
||||||
pub name: Loc<PackageName<'a>>,
|
pub name: Loc<PackageName<'a>>,
|
||||||
pub exposes: Vec<'a, Loc<ExposesEntry<'a, &'a str>>>,
|
pub exposes: Vec<'a, Loc<Spaced<'a, ExposedName<'a>>>>,
|
||||||
pub packages: Vec<'a, (Loc<&'a str>, Loc<PackageOrPath<'a>>)>,
|
pub packages: Vec<'a, (Loc<&'a str>, Loc<PackageOrPath<'a>>)>,
|
||||||
pub imports: Vec<'a, Loc<ImportsEntry<'a>>>,
|
pub imports: Vec<'a, Loc<ImportsEntry<'a>>>,
|
||||||
|
|
||||||
|
@ -118,37 +137,25 @@ pub struct PackageHeader<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||||
pub enum PlatformRigid<'a> {
|
pub struct PlatformRigid<'a> {
|
||||||
Entry { rigid: &'a str, alias: &'a str },
|
pub rigid: &'a str,
|
||||||
|
pub alias: &'a str,
|
||||||
// Spaces
|
|
||||||
SpaceBefore(&'a PlatformRigid<'a>, &'a [CommentOrNewline<'a>]),
|
|
||||||
SpaceAfter(&'a PlatformRigid<'a>, &'a [CommentOrNewline<'a>]),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Spaceable<'a> for PlatformRigid<'a> {
|
|
||||||
fn before(&'a self, spaces: &'a [CommentOrNewline<'a>]) -> Self {
|
|
||||||
PlatformRigid::SpaceBefore(self, spaces)
|
|
||||||
}
|
|
||||||
fn after(&'a self, spaces: &'a [CommentOrNewline<'a>]) -> Self {
|
|
||||||
PlatformRigid::SpaceAfter(self, spaces)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct PlatformRequires<'a> {
|
pub struct PlatformRequires<'a> {
|
||||||
pub rigids: Collection<'a, Loc<PlatformRigid<'a>>>,
|
pub rigids: Collection<'a, Loc<Spaced<'a, PlatformRigid<'a>>>>,
|
||||||
pub signature: Loc<TypedIdent<'a>>,
|
pub signature: Loc<Spaced<'a, TypedIdent<'a>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct PlatformHeader<'a> {
|
pub struct PlatformHeader<'a> {
|
||||||
pub name: Loc<PackageName<'a>>,
|
pub name: Loc<PackageName<'a>>,
|
||||||
pub requires: PlatformRequires<'a>,
|
pub requires: PlatformRequires<'a>,
|
||||||
pub exposes: Collection<'a, Loc<ExposesEntry<'a, ModuleName<'a>>>>,
|
pub exposes: Collection<'a, Loc<Spaced<'a, ModuleName<'a>>>>,
|
||||||
pub packages: Collection<'a, Loc<PackageEntry<'a>>>,
|
pub packages: Collection<'a, Loc<Spaced<'a, PackageEntry<'a>>>>,
|
||||||
pub imports: Collection<'a, Loc<ImportsEntry<'a>>>,
|
pub imports: Collection<'a, Loc<Spaced<'a, ImportsEntry<'a>>>>,
|
||||||
pub provides: Collection<'a, Loc<ExposesEntry<'a, &'a str>>>,
|
pub provides: Collection<'a, Loc<Spaced<'a, ExposedName<'a>>>>,
|
||||||
pub effects: Effects<'a>,
|
pub effects: Effects<'a>,
|
||||||
|
|
||||||
// Potential comments and newlines - these will typically all be empty.
|
// Potential comments and newlines - these will typically all be empty.
|
||||||
|
@ -174,26 +181,7 @@ pub struct Effects<'a> {
|
||||||
pub spaces_after_type_name: &'a [CommentOrNewline<'a>],
|
pub spaces_after_type_name: &'a [CommentOrNewline<'a>],
|
||||||
pub effect_shortname: &'a str,
|
pub effect_shortname: &'a str,
|
||||||
pub effect_type_name: &'a str,
|
pub effect_type_name: &'a str,
|
||||||
pub entries: Collection<'a, Loc<TypedIdent<'a>>>,
|
pub entries: Collection<'a, Loc<Spaced<'a, TypedIdent<'a>>>>,
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub enum ExposesEntry<'a, T> {
|
|
||||||
/// e.g. `Task`
|
|
||||||
Exposed(T),
|
|
||||||
|
|
||||||
// Spaces
|
|
||||||
SpaceBefore(&'a ExposesEntry<'a, T>, &'a [CommentOrNewline<'a>]),
|
|
||||||
SpaceAfter(&'a ExposesEntry<'a, T>, &'a [CommentOrNewline<'a>]),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, T> Spaceable<'a> for ExposesEntry<'a, T> {
|
|
||||||
fn before(&'a self, spaces: &'a [CommentOrNewline<'a>]) -> Self {
|
|
||||||
ExposesEntry::SpaceBefore(self, spaces)
|
|
||||||
}
|
|
||||||
fn after(&'a self, spaces: &'a [CommentOrNewline<'a>]) -> Self {
|
|
||||||
ExposesEntry::SpaceAfter(self, spaces)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||||
|
@ -201,71 +189,35 @@ pub enum ImportsEntry<'a> {
|
||||||
/// e.g. `Task` or `Task.{ Task, after }`
|
/// e.g. `Task` or `Task.{ Task, after }`
|
||||||
Module(
|
Module(
|
||||||
ModuleName<'a>,
|
ModuleName<'a>,
|
||||||
Collection<'a, Loc<ExposesEntry<'a, &'a str>>>,
|
Collection<'a, Loc<Spaced<'a, ExposedName<'a>>>>,
|
||||||
),
|
),
|
||||||
|
|
||||||
/// e.g. `pf.Task` or `pf.Task.{ after }` or `pf.{ Task.{ Task, after } }`
|
/// e.g. `pf.Task` or `pf.Task.{ after }` or `pf.{ Task.{ Task, after } }`
|
||||||
Package(
|
Package(
|
||||||
&'a str,
|
&'a str,
|
||||||
ModuleName<'a>,
|
ModuleName<'a>,
|
||||||
Collection<'a, Loc<ExposesEntry<'a, &'a str>>>,
|
Collection<'a, Loc<Spaced<'a, ExposedName<'a>>>>,
|
||||||
),
|
),
|
||||||
|
|
||||||
// Spaces
|
|
||||||
SpaceBefore(&'a ImportsEntry<'a>, &'a [CommentOrNewline<'a>]),
|
|
||||||
SpaceAfter(&'a ImportsEntry<'a>, &'a [CommentOrNewline<'a>]),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ExposesEntry<'a, &'a str> {
|
|
||||||
pub fn as_str(&'a self) -> &'a str {
|
|
||||||
use ExposesEntry::*;
|
|
||||||
|
|
||||||
match self {
|
|
||||||
Exposed(string) => string,
|
|
||||||
SpaceBefore(sub_entry, _) | SpaceAfter(sub_entry, _) => sub_entry.as_str(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
pub enum TypedIdent<'a> {
|
|
||||||
/// e.g.
|
/// e.g.
|
||||||
///
|
///
|
||||||
/// printLine : Str -> Effect {}
|
/// printLine : Str -> Effect {}
|
||||||
Entry {
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||||
ident: Loc<&'a str>,
|
pub struct TypedIdent<'a> {
|
||||||
spaces_before_colon: &'a [CommentOrNewline<'a>],
|
pub ident: Loc<&'a str>,
|
||||||
ann: Loc<TypeAnnotation<'a>>,
|
pub spaces_before_colon: &'a [CommentOrNewline<'a>],
|
||||||
},
|
pub ann: Loc<TypeAnnotation<'a>>,
|
||||||
|
|
||||||
// Spaces
|
|
||||||
SpaceBefore(&'a TypedIdent<'a>, &'a [CommentOrNewline<'a>]),
|
|
||||||
SpaceAfter(&'a TypedIdent<'a>, &'a [CommentOrNewline<'a>]),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||||
pub enum PackageEntry<'a> {
|
pub struct PackageEntry<'a> {
|
||||||
Entry {
|
pub shorthand: &'a str,
|
||||||
shorthand: &'a str,
|
pub spaces_after_shorthand: &'a [CommentOrNewline<'a>],
|
||||||
spaces_after_shorthand: &'a [CommentOrNewline<'a>],
|
pub package_or_path: Loc<PackageOrPath<'a>>,
|
||||||
package_or_path: Loc<PackageOrPath<'a>>,
|
|
||||||
},
|
|
||||||
|
|
||||||
// Spaces
|
|
||||||
SpaceBefore(&'a PackageEntry<'a>, &'a [CommentOrNewline<'a>]),
|
|
||||||
SpaceAfter(&'a PackageEntry<'a>, &'a [CommentOrNewline<'a>]),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Spaceable<'a> for PackageEntry<'a> {
|
pub fn package_entry<'a>() -> impl Parser<'a, Spaced<'a, PackageEntry<'a>>, EPackageEntry<'a>> {
|
||||||
fn before(&'a self, spaces: &'a [CommentOrNewline<'a>]) -> Self {
|
|
||||||
PackageEntry::SpaceBefore(self, spaces)
|
|
||||||
}
|
|
||||||
fn after(&'a self, spaces: &'a [CommentOrNewline<'a>]) -> Self {
|
|
||||||
PackageEntry::SpaceAfter(self, spaces)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn package_entry<'a>() -> impl Parser<'a, PackageEntry<'a>, EPackageEntry<'a>> {
|
|
||||||
move |arena, state| {
|
move |arena, state| {
|
||||||
// You may optionally have a package shorthand,
|
// You may optionally have a package shorthand,
|
||||||
// e.g. "uc" in `uc: roc/unicode 1.0.0`
|
// e.g. "uc" in `uc: roc/unicode 1.0.0`
|
||||||
|
@ -293,19 +245,19 @@ pub fn package_entry<'a>() -> impl Parser<'a, PackageEntry<'a>, EPackageEntry<'a
|
||||||
.parse(arena, state)?;
|
.parse(arena, state)?;
|
||||||
|
|
||||||
let entry = match opt_shorthand {
|
let entry = match opt_shorthand {
|
||||||
Some((shorthand, spaces_after_shorthand)) => PackageEntry::Entry {
|
Some((shorthand, spaces_after_shorthand)) => PackageEntry {
|
||||||
shorthand,
|
shorthand,
|
||||||
spaces_after_shorthand,
|
spaces_after_shorthand,
|
||||||
package_or_path,
|
package_or_path,
|
||||||
},
|
},
|
||||||
None => PackageEntry::Entry {
|
None => PackageEntry {
|
||||||
shorthand: "",
|
shorthand: "",
|
||||||
spaces_after_shorthand: &[],
|
spaces_after_shorthand: &[],
|
||||||
package_or_path,
|
package_or_path,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok((MadeProgress, entry, state))
|
Ok((MadeProgress, Spaced::Item(entry), state))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::ast::{Collection, CommentOrNewline, Def, Module};
|
use crate::ast::{Collection, CommentOrNewline, Def, Module, Spaced};
|
||||||
use crate::blankspace::{space0_around_ee, space0_before_e, space0_e};
|
use crate::blankspace::{space0_around_ee, space0_before_e, space0_e};
|
||||||
use crate::header::{
|
use crate::header::{
|
||||||
package_entry, package_name, package_or_path, AppHeader, Effects, ExposesEntry, ImportsEntry,
|
package_entry, package_name, package_or_path, AppHeader, Effects, ExposedName, ImportsEntry,
|
||||||
InterfaceHeader, ModuleName, PackageEntry, PlatformHeader, PlatformRequires, PlatformRigid, To,
|
InterfaceHeader, ModuleName, PackageEntry, PlatformHeader, PlatformRequires, PlatformRigid, To,
|
||||||
TypedIdent,
|
TypedIdent,
|
||||||
};
|
};
|
||||||
|
@ -220,7 +220,7 @@ fn app_header<'a>() -> impl Parser<'a, AppHeader<'a>, EHeader<'a>> {
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
let opt_imports: Option<(
|
let opt_imports: Option<(
|
||||||
(&'a [CommentOrNewline<'a>], &'a [CommentOrNewline<'a>]),
|
(&'a [CommentOrNewline<'a>], &'a [CommentOrNewline<'a>]),
|
||||||
Collection<'a, Located<ImportsEntry<'a>>>,
|
Collection<'a, Located<Spaced<'a, ImportsEntry<'a>>>>,
|
||||||
)> = opt_imports;
|
)> = opt_imports;
|
||||||
|
|
||||||
let ((before_imports, after_imports), imports) =
|
let ((before_imports, after_imports), imports) =
|
||||||
|
@ -303,7 +303,7 @@ fn platform_header<'a>() -> impl Parser<'a, PlatformHeader<'a>, EHeader<'a>> {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct ProvidesTo<'a> {
|
struct ProvidesTo<'a> {
|
||||||
entries: Collection<'a, Located<ExposesEntry<'a, &'a str>>>,
|
entries: Collection<'a, Located<Spaced<'a, ExposedName<'a>>>>,
|
||||||
to: Located<To<'a>>,
|
to: Located<To<'a>>,
|
||||||
|
|
||||||
before_provides_keyword: &'a [CommentOrNewline<'a>],
|
before_provides_keyword: &'a [CommentOrNewline<'a>],
|
||||||
|
@ -362,7 +362,7 @@ fn provides_without_to<'a>() -> impl Parser<
|
||||||
'a,
|
'a,
|
||||||
(
|
(
|
||||||
(&'a [CommentOrNewline<'a>], &'a [CommentOrNewline<'a>]),
|
(&'a [CommentOrNewline<'a>], &'a [CommentOrNewline<'a>]),
|
||||||
Collection<'a, Located<ExposesEntry<'a, &'a str>>>,
|
Collection<'a, Located<Spaced<'a, ExposedName<'a>>>>,
|
||||||
),
|
),
|
||||||
EProvides<'a>,
|
EProvides<'a>,
|
||||||
> {
|
> {
|
||||||
|
@ -385,14 +385,14 @@ fn provides_without_to<'a>() -> impl Parser<
|
||||||
EProvides::Open,
|
EProvides::Open,
|
||||||
EProvides::Space,
|
EProvides::Space,
|
||||||
EProvides::IndentListEnd,
|
EProvides::IndentListEnd,
|
||||||
ExposesEntry::SpaceBefore
|
Spaced::SpaceBefore
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn exposes_entry<'a, F, E>(
|
fn exposes_entry<'a, F, E>(
|
||||||
to_expectation: F,
|
to_expectation: F,
|
||||||
) -> impl Parser<'a, Located<ExposesEntry<'a, &'a str>>, E>
|
) -> impl Parser<'a, Located<Spaced<'a, ExposedName<'a>>>, E>
|
||||||
where
|
where
|
||||||
F: Fn(crate::parser::Row, crate::parser::Col) -> E,
|
F: Fn(crate::parser::Row, crate::parser::Col) -> E,
|
||||||
F: Copy,
|
F: Copy,
|
||||||
|
@ -400,7 +400,7 @@ where
|
||||||
{
|
{
|
||||||
loc!(map!(
|
loc!(map!(
|
||||||
specialize(|_, r, c| to_expectation(r, c), unqualified_ident()),
|
specialize(|_, r, c| to_expectation(r, c), unqualified_ident()),
|
||||||
ExposesEntry::Exposed
|
|n| Spaced::Item(ExposedName::new(n))
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -444,7 +444,7 @@ fn platform_requires<'a>() -> impl Parser<'a, PlatformRequires<'a>, ERequires<'a
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn requires_rigids<'a>(
|
fn requires_rigids<'a>(
|
||||||
min_indent: u16,
|
min_indent: u16,
|
||||||
) -> impl Parser<'a, Collection<'a, Located<PlatformRigid<'a>>>, ERequires<'a>> {
|
) -> impl Parser<'a, Collection<'a, Located<Spaced<'a, PlatformRigid<'a>>>>, ERequires<'a>> {
|
||||||
collection_trailing_sep_e!(
|
collection_trailing_sep_e!(
|
||||||
word1(b'{', ERequires::ListStart),
|
word1(b'{', ERequires::ListStart),
|
||||||
specialize(|_, r, c| ERequires::Rigid(r, c), loc!(requires_rigid())),
|
specialize(|_, r, c| ERequires::Rigid(r, c), loc!(requires_rigid())),
|
||||||
|
@ -454,23 +454,24 @@ fn requires_rigids<'a>(
|
||||||
ERequires::Open,
|
ERequires::Open,
|
||||||
ERequires::Space,
|
ERequires::Space,
|
||||||
ERequires::IndentListEnd,
|
ERequires::IndentListEnd,
|
||||||
PlatformRigid::SpaceBefore
|
Spaced::SpaceBefore
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn requires_rigid<'a>() -> impl Parser<'a, PlatformRigid<'a>, ()> {
|
fn requires_rigid<'a>() -> impl Parser<'a, Spaced<'a, PlatformRigid<'a>>, ()> {
|
||||||
map!(
|
map!(
|
||||||
and!(
|
and!(
|
||||||
lowercase_ident(),
|
lowercase_ident(),
|
||||||
skip_first!(word2(b'=', b'>', |_, _| ()), uppercase_ident())
|
skip_first!(word2(b'=', b'>', |_, _| ()), uppercase_ident())
|
||||||
),
|
),
|
||||||
|(rigid, alias)| PlatformRigid::Entry { rigid, alias }
|
|(rigid, alias)| Spaced::Item(PlatformRigid { rigid, alias })
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn requires_typed_ident<'a>() -> impl Parser<'a, Located<TypedIdent<'a>>, ERequires<'a>> {
|
fn requires_typed_ident<'a>() -> impl Parser<'a, Located<Spaced<'a, TypedIdent<'a>>>, ERequires<'a>>
|
||||||
|
{
|
||||||
skip_first!(
|
skip_first!(
|
||||||
word1(b'{', ERequires::ListStart),
|
word1(b'{', ERequires::ListStart),
|
||||||
skip_second!(
|
skip_second!(
|
||||||
|
@ -491,7 +492,7 @@ fn exposes_values<'a>() -> impl Parser<
|
||||||
'a,
|
'a,
|
||||||
(
|
(
|
||||||
(&'a [CommentOrNewline<'a>], &'a [CommentOrNewline<'a>]),
|
(&'a [CommentOrNewline<'a>], &'a [CommentOrNewline<'a>]),
|
||||||
Collection<'a, Located<ExposesEntry<'a, &'a str>>>,
|
Collection<'a, Located<Spaced<'a, ExposedName<'a>>>>,
|
||||||
),
|
),
|
||||||
EExposes,
|
EExposes,
|
||||||
> {
|
> {
|
||||||
|
@ -515,7 +516,7 @@ fn exposes_values<'a>() -> impl Parser<
|
||||||
EExposes::Open,
|
EExposes::Open,
|
||||||
EExposes::Space,
|
EExposes::Space,
|
||||||
EExposes::IndentListEnd,
|
EExposes::IndentListEnd,
|
||||||
ExposesEntry::SpaceBefore
|
Spaced::SpaceBefore
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -545,7 +546,7 @@ fn exposes_modules<'a>() -> impl Parser<
|
||||||
'a,
|
'a,
|
||||||
(
|
(
|
||||||
(&'a [CommentOrNewline<'a>], &'a [CommentOrNewline<'a>]),
|
(&'a [CommentOrNewline<'a>], &'a [CommentOrNewline<'a>]),
|
||||||
Collection<'a, Located<ExposesEntry<'a, ModuleName<'a>>>>,
|
Collection<'a, Located<Spaced<'a, ModuleName<'a>>>>,
|
||||||
),
|
),
|
||||||
EExposes,
|
EExposes,
|
||||||
> {
|
> {
|
||||||
|
@ -569,14 +570,14 @@ fn exposes_modules<'a>() -> impl Parser<
|
||||||
EExposes::Open,
|
EExposes::Open,
|
||||||
EExposes::Space,
|
EExposes::Space,
|
||||||
EExposes::IndentListEnd,
|
EExposes::IndentListEnd,
|
||||||
ExposesEntry::SpaceBefore
|
Spaced::SpaceBefore
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn exposes_module<'a, F, E>(
|
fn exposes_module<'a, F, E>(
|
||||||
to_expectation: F,
|
to_expectation: F,
|
||||||
) -> impl Parser<'a, Located<ExposesEntry<'a, ModuleName<'a>>>, E>
|
) -> impl Parser<'a, Located<Spaced<'a, ModuleName<'a>>>, E>
|
||||||
where
|
where
|
||||||
F: Fn(crate::parser::Row, crate::parser::Col) -> E,
|
F: Fn(crate::parser::Row, crate::parser::Col) -> E,
|
||||||
F: Copy,
|
F: Copy,
|
||||||
|
@ -584,13 +585,13 @@ where
|
||||||
{
|
{
|
||||||
loc!(map!(
|
loc!(map!(
|
||||||
specialize(|_, r, c| to_expectation(r, c), module_name()),
|
specialize(|_, r, c| to_expectation(r, c), module_name()),
|
||||||
ExposesEntry::Exposed
|
Spaced::Item
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Packages<'a> {
|
struct Packages<'a> {
|
||||||
entries: Collection<'a, Located<PackageEntry<'a>>>,
|
entries: Collection<'a, Located<Spaced<'a, PackageEntry<'a>>>>,
|
||||||
before_packages_keyword: &'a [CommentOrNewline<'a>],
|
before_packages_keyword: &'a [CommentOrNewline<'a>],
|
||||||
after_packages_keyword: &'a [CommentOrNewline<'a>],
|
after_packages_keyword: &'a [CommentOrNewline<'a>],
|
||||||
}
|
}
|
||||||
|
@ -618,7 +619,7 @@ fn packages<'a>() -> impl Parser<'a, Packages<'a>, EPackages<'a>> {
|
||||||
EPackages::Open,
|
EPackages::Open,
|
||||||
EPackages::Space,
|
EPackages::Space,
|
||||||
EPackages::IndentListEnd,
|
EPackages::IndentListEnd,
|
||||||
PackageEntry::SpaceBefore
|
Spaced::SpaceBefore
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|((before_packages_keyword, after_packages_keyword), entries): (
|
|((before_packages_keyword, after_packages_keyword), entries): (
|
||||||
|
@ -639,7 +640,7 @@ fn imports<'a>() -> impl Parser<
|
||||||
'a,
|
'a,
|
||||||
(
|
(
|
||||||
(&'a [CommentOrNewline<'a>], &'a [CommentOrNewline<'a>]),
|
(&'a [CommentOrNewline<'a>], &'a [CommentOrNewline<'a>]),
|
||||||
Collection<'a, Located<ImportsEntry<'a>>>,
|
Collection<'a, Located<Spaced<'a, ImportsEntry<'a>>>>,
|
||||||
),
|
),
|
||||||
EImports,
|
EImports,
|
||||||
> {
|
> {
|
||||||
|
@ -663,7 +664,7 @@ fn imports<'a>() -> impl Parser<
|
||||||
EImports::Open,
|
EImports::Open,
|
||||||
EImports::Space,
|
EImports::Space,
|
||||||
EImports::IndentListEnd,
|
EImports::IndentListEnd,
|
||||||
ImportsEntry::SpaceBefore
|
Spaced::SpaceBefore
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -706,7 +707,7 @@ fn effects<'a>() -> impl Parser<'a, Effects<'a>, EEffects<'a>> {
|
||||||
EEffects::Open,
|
EEffects::Open,
|
||||||
EEffects::Space,
|
EEffects::Space,
|
||||||
EEffects::IndentListEnd,
|
EEffects::IndentListEnd,
|
||||||
TypedIdent::SpaceBefore
|
Spaced::SpaceBefore
|
||||||
)
|
)
|
||||||
.parse(arena, state)?;
|
.parse(arena, state)?;
|
||||||
|
|
||||||
|
@ -726,7 +727,7 @@ fn effects<'a>() -> impl Parser<'a, Effects<'a>, EEffects<'a>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn typed_ident<'a>() -> impl Parser<'a, TypedIdent<'a>, ETypedIdent<'a>> {
|
fn typed_ident<'a>() -> impl Parser<'a, Spaced<'a, TypedIdent<'a>>, ETypedIdent<'a>> {
|
||||||
// e.g.
|
// e.g.
|
||||||
//
|
//
|
||||||
// printLine : Str -> Effect {}
|
// printLine : Str -> Effect {}
|
||||||
|
@ -752,11 +753,11 @@ fn typed_ident<'a>() -> impl Parser<'a, TypedIdent<'a>, ETypedIdent<'a>> {
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|((ident, spaces_before_colon), ann)| {
|
|((ident, spaces_before_colon), ann)| {
|
||||||
TypedIdent::Entry {
|
Spaced::Item(TypedIdent {
|
||||||
ident,
|
ident,
|
||||||
spaces_before_colon,
|
spaces_before_colon,
|
||||||
ann,
|
ann,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -775,12 +776,12 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn imports_entry<'a>() -> impl Parser<'a, ImportsEntry<'a>, EImports> {
|
fn imports_entry<'a>() -> impl Parser<'a, Spaced<'a, ImportsEntry<'a>>, EImports> {
|
||||||
let min_indent = 1;
|
let min_indent = 1;
|
||||||
|
|
||||||
type Temp<'a> = (
|
type Temp<'a> = (
|
||||||
(Option<&'a str>, ModuleName<'a>),
|
(Option<&'a str>, ModuleName<'a>),
|
||||||
Option<Collection<'a, Located<ExposesEntry<'a, &'a str>>>>,
|
Option<Collection<'a, Located<Spaced<'a, ExposedName<'a>>>>>,
|
||||||
);
|
);
|
||||||
|
|
||||||
map_with_arena!(
|
map_with_arena!(
|
||||||
|
@ -806,18 +807,20 @@ fn imports_entry<'a>() -> impl Parser<'a, ImportsEntry<'a>, EImports> {
|
||||||
EImports::Open,
|
EImports::Open,
|
||||||
EImports::Space,
|
EImports::Space,
|
||||||
EImports::IndentSetEnd,
|
EImports::IndentSetEnd,
|
||||||
ExposesEntry::SpaceBefore
|
Spaced::SpaceBefore
|
||||||
)
|
)
|
||||||
))
|
))
|
||||||
),
|
),
|
||||||
|_arena, ((opt_shortname, module_name), opt_values): Temp<'a>| {
|
|_arena, ((opt_shortname, module_name), opt_values): Temp<'a>| {
|
||||||
let exposed_values = opt_values.unwrap_or_else(Collection::empty);
|
let exposed_values = opt_values.unwrap_or_else(Collection::empty);
|
||||||
|
|
||||||
match opt_shortname {
|
let entry = match opt_shortname {
|
||||||
Some(shortname) => ImportsEntry::Package(shortname, module_name, exposed_values),
|
Some(shortname) => ImportsEntry::Package(shortname, module_name, exposed_values),
|
||||||
|
|
||||||
None => ImportsEntry::Module(module_name, exposed_values),
|
None => ImportsEntry::Module(module_name, exposed_values),
|
||||||
}
|
};
|
||||||
|
|
||||||
|
Spaced::Item(entry)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ Platform {
|
||||||
},
|
},
|
||||||
requires: PlatformRequires {
|
requires: PlatformRequires {
|
||||||
rigids: [],
|
rigids: [],
|
||||||
signature: |L 0-0, C 38-47| Entry {
|
signature: |L 0-0, C 38-47| TypedIdent {
|
||||||
ident: |L 0-0, C 38-42| "main",
|
ident: |L 0-0, C 38-42| "main",
|
||||||
spaces_before_colon: [],
|
spaces_before_colon: [],
|
||||||
ann: |L 0-0, C 45-47| Record {
|
ann: |L 0-0, C 45-47| Record {
|
||||||
|
|
|
@ -4,7 +4,7 @@ App {
|
||||||
"quicksort",
|
"quicksort",
|
||||||
),
|
),
|
||||||
packages: [
|
packages: [
|
||||||
|L 1-1, C 15-31| Entry {
|
|L 1-1, C 15-31| PackageEntry {
|
||||||
shorthand: "pf",
|
shorthand: "pf",
|
||||||
spaces_after_shorthand: [],
|
spaces_after_shorthand: [],
|
||||||
package_or_path: |L 1-1, C 19-31| Path(
|
package_or_path: |L 1-1, C 19-31| Path(
|
||||||
|
@ -24,7 +24,7 @@ App {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
provides: [
|
provides: [
|
||||||
|L 3-3, C 15-24| Exposed(
|
|L 3-3, C 15-24| ExposedName(
|
||||||
"quicksort",
|
"quicksort",
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
@ -4,7 +4,7 @@ App {
|
||||||
"quicksort",
|
"quicksort",
|
||||||
),
|
),
|
||||||
packages: [
|
packages: [
|
||||||
|L 1-1, C 15-31| Entry {
|
|L 1-1, C 15-31| PackageEntry {
|
||||||
shorthand: "pf",
|
shorthand: "pf",
|
||||||
spaces_after_shorthand: [],
|
spaces_after_shorthand: [],
|
||||||
package_or_path: |L 1-1, C 19-31| Path(
|
package_or_path: |L 1-1, C 19-31| Path(
|
||||||
|
@ -23,7 +23,7 @@ App {
|
||||||
Collection {
|
Collection {
|
||||||
items: [
|
items: [
|
||||||
|L 3-3, C 8-11| SpaceBefore(
|
|L 3-3, C 8-11| SpaceBefore(
|
||||||
Exposed(
|
ExposedName(
|
||||||
"Baz",
|
"Baz",
|
||||||
),
|
),
|
||||||
[
|
[
|
||||||
|
@ -31,7 +31,7 @@ App {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|L 4-4, C 8-16| SpaceBefore(
|
|L 4-4, C 8-16| SpaceBefore(
|
||||||
Exposed(
|
ExposedName(
|
||||||
"FortyTwo",
|
"FortyTwo",
|
||||||
),
|
),
|
||||||
[
|
[
|
||||||
|
@ -49,7 +49,7 @@ App {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
provides: [
|
provides: [
|
||||||
|L 7-7, C 15-24| Exposed(
|
|L 7-7, C 15-24| ExposedName(
|
||||||
"quicksort",
|
"quicksort",
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
@ -6,12 +6,12 @@ Platform {
|
||||||
},
|
},
|
||||||
requires: PlatformRequires {
|
requires: PlatformRequires {
|
||||||
rigids: [
|
rigids: [
|
||||||
|L 1-1, C 14-26| Entry {
|
|L 1-1, C 14-26| PlatformRigid {
|
||||||
rigid: "model",
|
rigid: "model",
|
||||||
alias: "Model",
|
alias: "Model",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
signature: |L 1-1, C 30-39| Entry {
|
signature: |L 1-1, C 30-39| TypedIdent {
|
||||||
ident: |L 1-1, C 30-34| "main",
|
ident: |L 1-1, C 30-34| "main",
|
||||||
spaces_before_colon: [],
|
spaces_before_colon: [],
|
||||||
ann: |L 1-1, C 37-39| Record {
|
ann: |L 1-1, C 37-39| Record {
|
||||||
|
@ -22,7 +22,7 @@ Platform {
|
||||||
},
|
},
|
||||||
exposes: [],
|
exposes: [],
|
||||||
packages: [
|
packages: [
|
||||||
|L 3-3, C 15-27| Entry {
|
|L 3-3, C 15-27| PackageEntry {
|
||||||
shorthand: "foo",
|
shorthand: "foo",
|
||||||
spaces_after_shorthand: [],
|
spaces_after_shorthand: [],
|
||||||
package_or_path: |L 3-3, C 20-27| Path(
|
package_or_path: |L 3-3, C 20-27| Path(
|
||||||
|
@ -34,7 +34,7 @@ Platform {
|
||||||
],
|
],
|
||||||
imports: [],
|
imports: [],
|
||||||
provides: [
|
provides: [
|
||||||
|L 5-5, C 15-26| Exposed(
|
|L 5-5, C 15-26| ExposedName(
|
||||||
"mainForHost",
|
"mainForHost",
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue