diff --git a/crates/cli/src/format.rs b/crates/cli/src/format.rs index 7080589167..845f255fc2 100644 --- a/crates/cli/src/format.rs +++ b/crates/cli/src/format.rs @@ -8,7 +8,6 @@ use roc_fmt::def::fmt_defs; use roc_fmt::module::fmt_module; use roc_fmt::spaces::RemoveSpaces; use roc_fmt::{Ast, Buf}; -use roc_parse::ast::Defs; use roc_parse::module::parse_module_defs; use roc_parse::{module, parser::SyntaxError, state::State}; @@ -226,7 +225,9 @@ fn parse_all<'a>(arena: &'a Bump, src: &'a str) -> Result, SyntaxError<' let (module, state) = module::parse_header(arena, State::new(src.as_bytes())) .map_err(|e| SyntaxError::Header(e.problem))?; - let defs = parse_module_defs(arena, state, Defs::default())?; + let (module, defs) = module.upgrade_header_imports(arena); + + let defs = parse_module_defs(arena, state, defs)?; Ok(Ast { module, defs }) } diff --git a/crates/compiler/builtins/roc/Bool.roc b/crates/compiler/builtins/roc/Bool.roc index 5f77f62e01..d53d80e55c 100644 --- a/crates/compiler/builtins/roc/Bool.roc +++ b/crates/compiler/builtins/roc/Bool.roc @@ -1,6 +1,4 @@ -interface Bool - exposes [Bool, Eq, true, false, and, or, not, isEq, isNotEq] - imports [] +module [Bool, Eq, true, false, and, or, not, isEq, isNotEq] ## Defines a type that can be compared for total equality. ## diff --git a/crates/compiler/builtins/roc/Box.roc b/crates/compiler/builtins/roc/Box.roc index e7305e5c9f..4812a4e0cd 100644 --- a/crates/compiler/builtins/roc/Box.roc +++ b/crates/compiler/builtins/roc/Box.roc @@ -2,9 +2,7 @@ ## - Holding unknown Roc types when developing [platforms](https://github.com/roc-lang/roc/wiki/Roc-concepts-explained#platform). ## - To improve performance in rare cases. ## -interface Box - exposes [box, unbox] - imports [] +module [box, unbox] ## Allocates a value on the heap. Boxing is an expensive process as it copies ## the value from the stack to the heap. This may provide a performance diff --git a/crates/compiler/builtins/roc/Decode.roc b/crates/compiler/builtins/roc/Decode.roc index 97499eda4b..71e330c4b1 100644 --- a/crates/compiler/builtins/roc/Decode.roc +++ b/crates/compiler/builtins/roc/Decode.roc @@ -1,36 +1,34 @@ -interface Decode - exposes [ - DecodeError, - DecodeResult, - Decoder, - Decoding, - DecoderFormatting, - decoder, - u8, - u16, - u32, - u64, - u128, - i8, - i16, - i32, - i64, - i128, - f32, - f64, - dec, - bool, - string, - list, - record, - tuple, - custom, - decodeWith, - fromBytesPartial, - fromBytes, - mapResult, - ] - imports [] +module [ + DecodeError, + DecodeResult, + Decoder, + Decoding, + DecoderFormatting, + decoder, + u8, + u16, + u32, + u64, + u128, + i8, + i16, + i32, + i64, + i128, + f32, + f64, + dec, + bool, + string, + list, + record, + tuple, + custom, + decodeWith, + fromBytesPartial, + fromBytes, + mapResult, +] import List import Result exposing [Result] diff --git a/crates/compiler/builtins/roc/Dict.roc b/crates/compiler/builtins/roc/Dict.roc index 0d0c296cad..f6d17e2879 100644 --- a/crates/compiler/builtins/roc/Dict.roc +++ b/crates/compiler/builtins/roc/Dict.roc @@ -1,35 +1,33 @@ -interface Dict - exposes [ - Dict, - empty, - withCapacity, - single, - clear, - capacity, - reserve, - releaseExcessCapacity, - len, - isEmpty, - get, - contains, - insert, - remove, - update, - walk, - walkUntil, - keepIf, - dropIf, - toList, - fromList, - keys, - values, - insertAll, - keepShared, - removeAll, - map, - joinMap, - ] - imports [] +module [ + Dict, + empty, + withCapacity, + single, + clear, + capacity, + reserve, + releaseExcessCapacity, + len, + isEmpty, + get, + contains, + insert, + remove, + update, + walk, + walkUntil, + keepIf, + dropIf, + toList, + fromList, + keys, + values, + insertAll, + keepShared, + removeAll, + map, + joinMap, +] import Bool exposing [Bool, Eq] import Result exposing [Result] diff --git a/crates/compiler/builtins/roc/Encode.roc b/crates/compiler/builtins/roc/Encode.roc index 67bf4e5890..b63ad2f35b 100644 --- a/crates/compiler/builtins/roc/Encode.roc +++ b/crates/compiler/builtins/roc/Encode.roc @@ -1,34 +1,32 @@ -interface Encode - exposes [ - Encoder, - Encoding, - toEncoder, - EncoderFormatting, - u8, - u16, - u32, - u64, - u128, - i8, - i16, - i32, - i64, - i128, - f32, - f64, - dec, - bool, - string, - list, - record, - tag, - tuple, - custom, - appendWith, - append, - toBytes, - ] - imports [] +module [ + Encoder, + Encoding, + toEncoder, + EncoderFormatting, + u8, + u16, + u32, + u64, + u128, + i8, + i16, + i32, + i64, + i128, + f32, + f64, + dec, + bool, + string, + list, + record, + tag, + tuple, + custom, + appendWith, + append, + toBytes, +] import Num exposing [ U8, diff --git a/crates/compiler/builtins/roc/Hash.roc b/crates/compiler/builtins/roc/Hash.roc index 99e080bfc6..8dfa548c7d 100644 --- a/crates/compiler/builtins/roc/Hash.roc +++ b/crates/compiler/builtins/roc/Hash.roc @@ -1,26 +1,25 @@ -interface Hash - exposes [ - Hash, - Hasher, - hash, - addBytes, - addU8, - addU16, - addU32, - addU64, - addU128, - hashBool, - hashI8, - hashI16, - hashI32, - hashI64, - hashI128, - hashDec, - complete, - hashStrBytes, - hashList, - hashUnordered, - ] imports [] +module [ + Hash, + Hasher, + hash, + addBytes, + addU8, + addU16, + addU32, + addU64, + addU128, + hashBool, + hashI8, + hashI16, + hashI32, + hashI64, + hashI128, + hashDec, + complete, + hashStrBytes, + hashList, + hashUnordered, +] import Bool exposing [Bool] import List diff --git a/crates/compiler/builtins/roc/Inspect.roc b/crates/compiler/builtins/roc/Inspect.roc index 8bb376ec3a..0f9c08a213 100644 --- a/crates/compiler/builtins/roc/Inspect.roc +++ b/crates/compiler/builtins/roc/Inspect.roc @@ -1,41 +1,39 @@ -interface Inspect - exposes [ - Inspect, - Inspector, - InspectFormatter, - ElemWalker, - KeyValWalker, - inspect, - init, - list, - set, - dict, - tag, - tuple, - record, - bool, - str, - function, - opaque, - u8, - i8, - u16, - i16, - u32, - i32, - u64, - i64, - u128, - i128, - f32, - f64, - dec, - custom, - apply, - toInspector, - toStr, - ] - imports [] +module [ + Inspect, + Inspector, + InspectFormatter, + ElemWalker, + KeyValWalker, + inspect, + init, + list, + set, + dict, + tag, + tuple, + record, + bool, + str, + function, + opaque, + u8, + i8, + u16, + i16, + u32, + i32, + u64, + i64, + u128, + i128, + f32, + f64, + dec, + custom, + apply, + toInspector, + toStr, +] import Bool exposing [Bool] import Num exposing [U8, U16, U32, U64, U128, I8, I16, I32, I64, I128, F32, F64, Dec] diff --git a/crates/compiler/builtins/roc/List.roc b/crates/compiler/builtins/roc/List.roc index 26636753cc..3d6fe798a3 100644 --- a/crates/compiler/builtins/roc/List.roc +++ b/crates/compiler/builtins/roc/List.roc @@ -1,77 +1,75 @@ -interface List - exposes [ - isEmpty, - get, - set, - replace, - update, - append, - appendIfOk, - prepend, - prependIfOk, - map, - len, - withCapacity, - walkBackwards, - concat, - first, - single, - repeat, - reverse, - join, - keepIf, - contains, - sum, - walk, - last, - keepOks, - keepErrs, - mapWithIndex, - map2, - map3, - product, - walkWithIndex, - walkUntil, - walkWithIndexUntil, - walkFrom, - walkFromUntil, - range, - sortWith, - swap, - dropAt, - min, - max, - map4, - mapTry, - walkTry, - joinMap, - any, - takeFirst, - takeLast, - dropFirst, - dropLast, - findFirst, - findLast, - findFirstIndex, - findLastIndex, - sublist, - intersperse, - split, - splitFirst, - splitLast, - startsWith, - endsWith, - all, - dropIf, - sortAsc, - sortDesc, - reserve, - releaseExcessCapacity, - walkBackwardsUntil, - countIf, - chunksOf, - ] - imports [] +module [ + isEmpty, + get, + set, + replace, + update, + append, + appendIfOk, + prepend, + prependIfOk, + map, + len, + withCapacity, + walkBackwards, + concat, + first, + single, + repeat, + reverse, + join, + keepIf, + contains, + sum, + walk, + last, + keepOks, + keepErrs, + mapWithIndex, + map2, + map3, + product, + walkWithIndex, + walkUntil, + walkWithIndexUntil, + walkFrom, + walkFromUntil, + range, + sortWith, + swap, + dropAt, + min, + max, + map4, + mapTry, + walkTry, + joinMap, + any, + takeFirst, + takeLast, + dropFirst, + dropLast, + findFirst, + findLast, + findFirstIndex, + findLastIndex, + sublist, + intersperse, + split, + splitFirst, + splitLast, + startsWith, + endsWith, + all, + dropIf, + sortAsc, + sortDesc, + reserve, + releaseExcessCapacity, + walkBackwardsUntil, + countIf, + chunksOf, +] import Bool exposing [Bool, Eq] import Result exposing [Result] diff --git a/crates/compiler/builtins/roc/Num.roc b/crates/compiler/builtins/roc/Num.roc index d2e6bbca31..f1bf30bc84 100644 --- a/crates/compiler/builtins/roc/Num.roc +++ b/crates/compiler/builtins/roc/Num.roc @@ -1,163 +1,161 @@ -interface Num - exposes [ - Num, - Int, - Frac, - Integer, - FloatingPoint, - I128, - I64, - I32, - I16, - I8, - U128, - U64, - U32, - U16, - U8, - Signed128, - Signed64, - Signed32, - Signed16, - Signed8, - Unsigned128, - Unsigned64, - Unsigned32, - Unsigned16, - Unsigned8, - Dec, - F64, - F32, - Decimal, - Binary32, - Binary64, - e, - pi, - tau, - abs, - absDiff, - neg, - add, - sub, - mul, - min, - max, - isLt, - isLte, - isGt, - isGte, - isApproxEq, - sin, - cos, - tan, - atan, - acos, - asin, - isZero, - isEven, - isOdd, - toFrac, - isPositive, - isNegative, - isNaN, - isInfinite, - isFinite, - rem, - remChecked, - div, - divChecked, - sqrt, - sqrtChecked, - log, - logChecked, - round, - ceiling, - floor, - compare, - pow, - powInt, - countLeadingZeroBits, - countTrailingZeroBits, - countOneBits, - addWrap, - addChecked, - addSaturated, - bitwiseAnd, - bitwiseXor, - bitwiseOr, - bitwiseNot, - shiftLeftBy, - shiftRightBy, - shiftRightZfBy, - subWrap, - subChecked, - subSaturated, - mulWrap, - mulSaturated, - mulChecked, - intCast, - divCeil, - divCeilChecked, - divTrunc, - divTruncChecked, - toStr, - isMultipleOf, - minI8, - maxI8, - minU8, - maxU8, - minI16, - maxI16, - minU16, - maxU16, - minI32, - maxI32, - minU32, - maxU32, - minI64, - maxI64, - minU64, - maxU64, - minI128, - maxI128, - minU128, - maxU128, - minF32, - maxF32, - minF64, - maxF64, - toI8, - toI8Checked, - toI16, - toI16Checked, - toI32, - toI32Checked, - toI64, - toI64Checked, - toI128, - toI128Checked, - toU8, - toU8Checked, - toU16, - toU16Checked, - toU32, - toU32Checked, - toU64, - toU64Checked, - toU128, - toU128Checked, - toF32, - toF32Checked, - toF64, - toF64Checked, - withoutDecimalPoint, - withDecimalPoint, - f32ToParts, - f64ToParts, - f32FromParts, - f64FromParts, - ] - imports [] +module [ + Num, + Int, + Frac, + Integer, + FloatingPoint, + I128, + I64, + I32, + I16, + I8, + U128, + U64, + U32, + U16, + U8, + Signed128, + Signed64, + Signed32, + Signed16, + Signed8, + Unsigned128, + Unsigned64, + Unsigned32, + Unsigned16, + Unsigned8, + Dec, + F64, + F32, + Decimal, + Binary32, + Binary64, + e, + pi, + tau, + abs, + absDiff, + neg, + add, + sub, + mul, + min, + max, + isLt, + isLte, + isGt, + isGte, + isApproxEq, + sin, + cos, + tan, + atan, + acos, + asin, + isZero, + isEven, + isOdd, + toFrac, + isPositive, + isNegative, + isNaN, + isInfinite, + isFinite, + rem, + remChecked, + div, + divChecked, + sqrt, + sqrtChecked, + log, + logChecked, + round, + ceiling, + floor, + compare, + pow, + powInt, + countLeadingZeroBits, + countTrailingZeroBits, + countOneBits, + addWrap, + addChecked, + addSaturated, + bitwiseAnd, + bitwiseXor, + bitwiseOr, + bitwiseNot, + shiftLeftBy, + shiftRightBy, + shiftRightZfBy, + subWrap, + subChecked, + subSaturated, + mulWrap, + mulSaturated, + mulChecked, + intCast, + divCeil, + divCeilChecked, + divTrunc, + divTruncChecked, + toStr, + isMultipleOf, + minI8, + maxI8, + minU8, + maxU8, + minI16, + maxI16, + minU16, + maxU16, + minI32, + maxI32, + minU32, + maxU32, + minI64, + maxI64, + minU64, + maxU64, + minI128, + maxI128, + minU128, + maxU128, + minF32, + maxF32, + minF64, + maxF64, + toI8, + toI8Checked, + toI16, + toI16Checked, + toI32, + toI32Checked, + toI64, + toI64Checked, + toI128, + toI128Checked, + toU8, + toU8Checked, + toU16, + toU16Checked, + toU32, + toU32Checked, + toU64, + toU64Checked, + toU128, + toU128Checked, + toF32, + toF32Checked, + toF64, + toF64Checked, + withoutDecimalPoint, + withDecimalPoint, + f32ToParts, + f64ToParts, + f32FromParts, + f64FromParts, +] import Bool exposing [Bool] import Result exposing [Result] diff --git a/crates/compiler/builtins/roc/Result.roc b/crates/compiler/builtins/roc/Result.roc index bcb199620a..58aecb1d76 100644 --- a/crates/compiler/builtins/roc/Result.roc +++ b/crates/compiler/builtins/roc/Result.roc @@ -1,6 +1,4 @@ -interface Result - exposes [Result, isOk, isErr, map, mapErr, try, onErr, withDefault] - imports [] +module [Result, isOk, isErr, map, mapErr, try, onErr, withDefault] import Bool exposing [Bool] diff --git a/crates/compiler/builtins/roc/Set.roc b/crates/compiler/builtins/roc/Set.roc index bd8d326d77..c68ae1f2fd 100644 --- a/crates/compiler/builtins/roc/Set.roc +++ b/crates/compiler/builtins/roc/Set.roc @@ -1,30 +1,28 @@ -interface Set - exposes [ - Set, - empty, - withCapacity, - reserve, - releaseExcessCapacity, - single, - walk, - walkUntil, - keepIf, - dropIf, - insert, - len, - isEmpty, - capacity, - remove, - contains, - toList, - fromList, - union, - intersection, - difference, - map, - joinMap, - ] - imports [] +module [ + Set, + empty, + withCapacity, + reserve, + releaseExcessCapacity, + single, + walk, + walkUntil, + keepIf, + dropIf, + insert, + len, + isEmpty, + capacity, + remove, + contains, + toList, + fromList, + union, + intersection, + difference, + map, + joinMap, +] import List import Bool exposing [Bool, Eq] diff --git a/crates/compiler/builtins/roc/Str.roc b/crates/compiler/builtins/roc/Str.roc index 310460fffd..1a0efeedec 100644 --- a/crates/compiler/builtins/roc/Str.roc +++ b/crates/compiler/builtins/roc/Str.roc @@ -326,50 +326,48 @@ ## If a situation like this comes up, a slice can be turned into a separate string by using [`Str.concat`](https://www.roc-lang.org/builtins/Str#concat) to concatenate the slice onto an empty string (or one created with [`Str.withCapacity`](https://www.roc-lang.org/builtins/Str#withCapacity)). ## ## Currently, the only way to get seamless slices of strings is by calling certain `Str` functions which return them. In general, `Str` functions which accept a string and return a subset of that string tend to do this. [`Str.trim`](https://www.roc-lang.org/builtins/Str#trim) is another example of a function which returns a seamless slice. -interface Str - exposes [ - Utf8Problem, - Utf8ByteProblem, - concat, - isEmpty, - joinWith, - split, - repeat, - countUtf8Bytes, - toUtf8, - fromUtf8, - startsWith, - endsWith, - trim, - trimStart, - trimEnd, - toDec, - toF64, - toF32, - toU128, - toI128, - toU64, - toI64, - toU32, - toI32, - toU16, - toI16, - toU8, - toI8, - replaceEach, - replaceFirst, - replaceLast, - splitFirst, - splitLast, - walkUtf8, - walkUtf8WithIndex, - reserve, - releaseExcessCapacity, - withCapacity, - withPrefix, - contains, - ] - imports [] +module [ + Utf8Problem, + Utf8ByteProblem, + concat, + isEmpty, + joinWith, + split, + repeat, + countUtf8Bytes, + toUtf8, + fromUtf8, + startsWith, + endsWith, + trim, + trimStart, + trimEnd, + toDec, + toF64, + toF32, + toU128, + toI128, + toU64, + toI64, + toU32, + toI32, + toU16, + toI16, + toU8, + toI8, + replaceEach, + replaceFirst, + replaceLast, + splitFirst, + splitLast, + walkUtf8, + walkUtf8WithIndex, + reserve, + releaseExcessCapacity, + withCapacity, + withPrefix, + contains, +] import Bool exposing [Bool] import Result exposing [Result] diff --git a/crates/compiler/builtins/roc/TotallyNotJson.roc b/crates/compiler/builtins/roc/TotallyNotJson.roc index 2865bf1922..38fdbe421d 100644 --- a/crates/compiler/builtins/roc/TotallyNotJson.roc +++ b/crates/compiler/builtins/roc/TotallyNotJson.roc @@ -1,12 +1,10 @@ ## THIS MODULE IS DEPRECATED AND CURRENTLY IN THE PROCESS OF BEING REMOVED ## FROM STD LIBRARY -interface TotallyNotJson - exposes [ - Json, - json, - jsonWithOptions, - ] - imports [] +module [ + Json, + json, + jsonWithOptions, +] import List import Str diff --git a/crates/compiler/can/src/def.rs b/crates/compiler/can/src/def.rs index 4fc30d99d3..f2346252a6 100644 --- a/crates/compiler/can/src/def.rs +++ b/crates/compiler/can/src/def.rs @@ -506,7 +506,7 @@ fn canonicalize_claimed_ability_impl<'a>( // OPTION-1: The implementation identifier is the only identifier of that name in the // scope. For example, // - // interface F imports [] exposes [] + // module [] // // Hello := {} implements [Encoding.{ toEncoder }] // @@ -518,7 +518,9 @@ fn canonicalize_claimed_ability_impl<'a>( // OPTION-2: The implementation identifier is a unique shadow of the ability member, // which has also been explicitly imported. For example, // - // interface F imports [Encoding.{ toEncoder }] exposes [] + // module [] + // + // import Encoding exposing [toEncoder] // // Hello := {} implements [Encoding.{ toEncoder }] // diff --git a/crates/compiler/fmt/src/module.rs b/crates/compiler/fmt/src/module.rs index 47cc2b7731..3391960251 100644 --- a/crates/compiler/fmt/src/module.rs +++ b/crates/compiler/fmt/src/module.rs @@ -8,7 +8,7 @@ use bumpalo::Bump; use roc_parse::ast::{Collection, Header, Module, Spaced, Spaces}; use roc_parse::header::{ AppHeader, ExposedName, ExposesKeyword, GeneratesKeyword, HostedHeader, ImportsEntry, - ImportsKeyword, InterfaceHeader, Keyword, KeywordItem, ModuleName, PackageEntry, PackageHeader, + ImportsKeyword, Keyword, KeywordItem, ModuleHeader, ModuleName, PackageEntry, PackageHeader, PackageKeyword, PackageName, PackagesKeyword, PlatformHeader, PlatformRequires, ProvidesKeyword, ProvidesTo, RequiresKeyword, To, ToKeyword, TypedIdent, WithKeyword, }; @@ -18,8 +18,8 @@ use roc_region::all::Loc; pub fn fmt_module<'a>(buf: &mut Buf<'_>, module: &'a Module<'a>) { fmt_comments_only(buf, module.comments.iter(), NewlineAt::Bottom, 0); match &module.header { - Header::Interface(header) => { - fmt_interface_header(buf, header); + Header::Module(header) => { + fmt_module_header(buf, header); } Header::App(header) => { fmt_app_header(buf, header); @@ -171,20 +171,19 @@ impl<'a, K: Formattable, V: Formattable> Formattable for KeywordItem<'a, K, V> { } } -pub fn fmt_interface_header<'a>(buf: &mut Buf, header: &'a InterfaceHeader<'a>) { +pub fn fmt_module_header<'a>(buf: &mut Buf, header: &'a ModuleHeader<'a>) { buf.indent(0); - buf.push_str("interface"); - let indent = INDENT; - fmt_default_spaces(buf, header.before_name, indent); + buf.push_str("module"); - // module name - buf.indent(indent); - buf.push_str(header.name.value.as_str()); + if header.before_exposes.iter().all(|c| c.is_newline()) { + buf.spaces(1); + fmt_exposes(buf, header.exposes, 0); + } else { + let indent = INDENT; - 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_default_spaces(buf, header.before_exposes, indent); + fmt_exposes(buf, header.exposes, indent); + }; } pub fn fmt_hosted_header<'a>(buf: &mut Buf, header: &'a HostedHeader<'a>) { diff --git a/crates/compiler/fmt/src/spaces.rs b/crates/compiler/fmt/src/spaces.rs index 631927342e..5766ab59f9 100644 --- a/crates/compiler/fmt/src/spaces.rs +++ b/crates/compiler/fmt/src/spaces.rs @@ -10,9 +10,9 @@ use roc_parse::{ StrSegment, Tag, TypeAnnotation, TypeDef, TypeHeader, ValueDef, WhenBranch, }, header::{ - AppHeader, ExposedName, HostedHeader, ImportsEntry, InterfaceHeader, KeywordItem, - ModuleName, PackageEntry, PackageHeader, PackageName, PlatformHeader, PlatformRequires, - ProvidesTo, To, TypedIdent, + AppHeader, ExposedName, HostedHeader, ImportsEntry, KeywordItem, ModuleHeader, ModuleName, + PackageEntry, PackageHeader, PackageName, PlatformHeader, PlatformRequires, ProvidesTo, To, + TypedIdent, }, ident::{BadIdent, UppercaseIdent}, }; @@ -283,11 +283,10 @@ impl<'a> RemoveSpaces<'a> for ProvidesTo<'a> { impl<'a> RemoveSpaces<'a> for Module<'a> { fn remove_spaces(&self, arena: &'a Bump) -> Self { let header = match &self.header { - Header::Interface(header) => Header::Interface(InterfaceHeader { - before_name: &[], - name: header.name.remove_spaces(arena), + Header::Module(header) => Header::Module(ModuleHeader { + before_exposes: &[], exposes: header.exposes.remove_spaces(arena), - imports: header.imports.remove_spaces(arena), + interface_imports: header.interface_imports.remove_spaces(arena), }), Header::App(header) => Header::App(AppHeader { before_name: &[], diff --git a/crates/compiler/load/tests/test_reporting.rs b/crates/compiler/load/tests/test_reporting.rs index 8e4bf58b88..bb192365f9 100644 --- a/crates/compiler/load/tests/test_reporting.rs +++ b/crates/compiler/load/tests/test_reporting.rs @@ -6109,9 +6109,7 @@ In roc, functions are always written as a lambda, like{} report_header_problem_as( indoc!( r" - interface Foobar - exposes [main, @Foo] - imports [pf.Task, Base64] + module [main, @Foo] " ), indoc!( @@ -6120,39 +6118,12 @@ In roc, functions are always written as a lambda, like{} I am partway through parsing an `exposes` list, but I got stuck here: - 1│ interface Foobar - 2│ exposes [main, @Foo] - ^ + 1│ module [main, @Foo] + ^ I was expecting a type name, value name or function name next, like - exposes [Animal, default, tame] - " - ), - ) - } - - #[test] - fn invalid_module_name() { - report_header_problem_as( - indoc!( - r" - interface foobar - exposes [main, @Foo] - imports [pf.Task, Base64] - " - ), - indoc!( - r" - ── WEIRD MODULE NAME in /code/proj/Main.roc ──────────────────────────────────── - - I am partway through parsing a header, but got stuck here: - - 1│ interface foobar - ^ - - I am expecting a module name next, like BigNum or Main. Module names - must start with an uppercase letter. + [Animal, default, tame] " ), ) diff --git a/crates/compiler/load_internal/src/file.rs b/crates/compiler/load_internal/src/file.rs index cdad1a3cd2..74845bd88c 100644 --- a/crates/compiler/load_internal/src/file.rs +++ b/crates/compiler/load_internal/src/file.rs @@ -49,8 +49,8 @@ use roc_mono::{drop_specialization, inc_dec}; use roc_packaging::cache::RocCacheDir; use roc_parse::ast::{self, CommentOrNewline, ExtractSpaces, Spaced, ValueDef}; use roc_parse::header::{ - ExposedName, HeaderType, ImportsKeywordItem, PackageEntry, PackageHeader, PlatformHeader, To, - TypedIdent, + self, ExposedName, HeaderType, ImportsKeywordItem, PackageEntry, PackageHeader, PlatformHeader, + To, TypedIdent, }; use roc_parse::module::parse_module_defs; use roc_parse::parser::{FileError, SourceError, SyntaxError}; @@ -644,7 +644,7 @@ struct CanAndCon { enum PlatformPath<'a> { NotSpecified, Valid(To<'a>), - RootIsInterface, + RootIsModule, RootIsHosted, RootIsPlatformModule, } @@ -1204,8 +1204,9 @@ fn adjust_header_paths<'a>( { debug_assert_eq!(*header_id, header_output.module_id); - if let HeaderType::Interface { name, .. } = header_type { - // Interface modules can have names like Foo.Bar.Baz, + if let HeaderType::Module { name, .. } = header_type { + // [modules-revamp] TODO: Privacy changes + // Modules can have names like Foo.Bar.Baz, // in which case we need to adjust the src_dir to // remove the "Bar/Baz" directories in order to correctly // resolve this interface module's imports! @@ -2313,13 +2314,13 @@ fn update<'a>( state.exposed_modules = exposes_ids; } } - Builtin { .. } | Interface { .. } => { + Builtin { .. } | Module { .. } => { if header.is_root_module { debug_assert!(matches!( state.platform_path, PlatformPath::NotSpecified )); - state.platform_path = PlatformPath::RootIsInterface; + state.platform_path = PlatformPath::RootIsModule; } } Hosted { .. } => { @@ -2956,7 +2957,7 @@ fn update<'a>( // This happens due to abilities. In detail, consider // // # Default module - // interface Default exposes [default, getDefault] + // module [default, getDefault] // // Default implements default : {} -> a where a implements Default // @@ -3198,7 +3199,7 @@ fn finish_specialization<'a>( let module_id = state.root_id; let uses_prebuilt_platform = match platform_data { Some(data) => data.is_prebuilt, - // If there's no platform data (e.g. because we're building an interface module) + // If there's no platform data (e.g. because we're building a module) // then there's no prebuilt platform either! None => false, }; @@ -3346,12 +3347,12 @@ fn load_package_from_disk<'a>( match parsed { Ok(( ast::Module { - header: ast::Header::Interface(header), + header: ast::Header::Module(header), .. }, _parse_state, )) => Err(LoadingProblem::UnexpectedHeader(format!( - "expected platform/package module, got Interface with header\n{header:?}" + "expected platform/package module, got Module with header\n{header:?}" ))), Ok(( ast::Module { @@ -3477,23 +3478,25 @@ fn load_builtin_module_help<'a>( match parsed { Ok(( ast::Module { - header: ast::Header::Interface(header), + header: ast::Header::Module(header), comments, }, parse_state, )) => { + let name_stem = arena.alloc_str(filename.file_stem().unwrap().to_str().unwrap()); + let info = HeaderInfo { filename, is_root_module, opt_shorthand, packages: &[], header_type: HeaderType::Builtin { - name: header.name.value, - exposes: unspace(arena, header.exposes.item.items), + name: header::ModuleName::new(name_stem), + exposes: unspace(arena, header.exposes.items), generates_with: &[], }, module_comments: comments, - header_imports: Some(header.imports), + header_imports: header.interface_imports, }; (info, parse_state) @@ -3693,45 +3696,6 @@ fn find_task(local: &Worker, global: &Injector, stealers: &[Stealer] }) } -fn verify_interface_matches_file_path<'a>( - interface_name: Loc>, - path: &Path, - state: &roc_parse::state::State<'a>, -) -> Result<(), LoadingProblem<'a>> { - let module_parts = interface_name.value.as_str().split(MODULE_SEPARATOR).rev(); - - let mut is_mismatched = false; - let mut opt_path = Some(path); - for part in module_parts { - match opt_path.and_then(|path| path.file_stem().map(|fi| (path, fi))) { - None => { - is_mismatched = true; - break; - } - Some((path, fi)) => { - if fi != part { - is_mismatched = true; - break; - } - opt_path = path.parent(); - } - } - } - - if !is_mismatched { - return Ok(()); - } - - use roc_parse::parser::EHeader; - let syntax_problem = - SyntaxError::Header(EHeader::InconsistentModuleName(interface_name.region)); - let problem = LoadingProblem::ParsingFailed(FileError { - problem: SourceError::new(syntax_problem, state), - filename: path.to_path_buf(), - }); - Err(problem) -} - #[derive(Debug)] struct HeaderOutput<'a> { module_id: ModuleId, @@ -3798,48 +3762,35 @@ fn parse_header<'a>( match parsed { Ok(( ast::Module { - header: ast::Header::Interface(header), + header: ast::Header::Module(header), comments, }, parse_state, )) => { - verify_interface_matches_file_path(header.name, &filename, &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 header_name_region = header.name.region; let info = HeaderInfo { filename, is_root_module, opt_shorthand, packages: &[], - header_type: HeaderType::Interface { - name: header.name.value, - exposes: unspace(arena, header.exposes.item.items), + header_type: HeaderType::Module { + 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.interface_imports, }; - let (module_id, module_name, header) = + let (module_id, _, header) = build_header(info, parse_state.clone(), module_ids, module_timing)?; - if let Some(expected_module_name) = opt_expected_module_name { - if expected_module_name != module_name { - let problem = SourceError::new( - IncorrectModuleName { - module_id, - found: Loc::at(header_name_region, module_name), - expected: expected_module_name, - }, - &parse_state, - ); - let problem = LoadingProblem::IncorrectModuleName(FileError { - problem, - filename: header.module_path, - }); - return Err(problem); - } - } - Ok(HeaderOutput { module_id, msg: Msg::Header(header), @@ -4217,14 +4168,9 @@ fn build_header<'a>( // Package modules do not have names. String::new().into() } - HeaderType::Interface { name, .. } + HeaderType::Module { name, .. } | HeaderType::Builtin { name, .. } - | HeaderType::Hosted { name, .. } => { - // TODO check to see if name is consistent with filename. - // If it isn't, report a problem! - - name.as_str().into() - } + | HeaderType::Hosted { name, .. } => name.as_str().into(), }; let (name, home) = { @@ -5172,7 +5118,7 @@ fn parse<'a>( } HeaderType::App { .. } | HeaderType::Package { .. } - | HeaderType::Interface { .. } + | HeaderType::Module { .. } | HeaderType::Builtin { .. } | HeaderType::Hosted { .. } => {} }; @@ -6408,12 +6354,12 @@ fn report_cannot_run( severity: Severity::RuntimeError, } } - RootIsInterface => { + RootIsModule => { let doc = alloc.stack([ alloc.reflow( - r"The input file is an `interface` module, but only `app` modules can be run.", + r"The input file is a module, but only `app` modules can be run.", ), - alloc.reflow(r"Tip: You can use `roc check` or `roc test` to verify an interface module like this one."), + alloc.reflow(r"Tip: You can use `roc check` or `roc test` to verify a module like this one."), ]); Report { diff --git a/crates/compiler/load_internal/tests/fixtures/build/interface_with_deps/AStar.roc b/crates/compiler/load_internal/tests/fixtures/build/module_with_deps/AStar.roc similarity index 100% rename from crates/compiler/load_internal/tests/fixtures/build/interface_with_deps/AStar.roc rename to crates/compiler/load_internal/tests/fixtures/build/module_with_deps/AStar.roc diff --git a/crates/compiler/load_internal/tests/fixtures/build/interface_with_deps/Dep1.roc b/crates/compiler/load_internal/tests/fixtures/build/module_with_deps/Dep1.roc similarity index 100% rename from crates/compiler/load_internal/tests/fixtures/build/interface_with_deps/Dep1.roc rename to crates/compiler/load_internal/tests/fixtures/build/module_with_deps/Dep1.roc diff --git a/crates/compiler/load_internal/tests/fixtures/build/interface_with_deps/Dep2.roc b/crates/compiler/load_internal/tests/fixtures/build/module_with_deps/Dep2.roc similarity index 100% rename from crates/compiler/load_internal/tests/fixtures/build/interface_with_deps/Dep2.roc rename to crates/compiler/load_internal/tests/fixtures/build/module_with_deps/Dep2.roc diff --git a/crates/compiler/load_internal/tests/fixtures/build/interface_with_deps/Dep3.roc b/crates/compiler/load_internal/tests/fixtures/build/module_with_deps/Dep3.roc similarity index 100% rename from crates/compiler/load_internal/tests/fixtures/build/interface_with_deps/Dep3.roc rename to crates/compiler/load_internal/tests/fixtures/build/module_with_deps/Dep3.roc diff --git a/crates/compiler/load_internal/tests/fixtures/build/interface_with_deps/ExposedUsedOutsideScope.roc b/crates/compiler/load_internal/tests/fixtures/build/module_with_deps/ExposedUsedOutsideScope.roc similarity index 100% rename from crates/compiler/load_internal/tests/fixtures/build/interface_with_deps/ExposedUsedOutsideScope.roc rename to crates/compiler/load_internal/tests/fixtures/build/module_with_deps/ExposedUsedOutsideScope.roc diff --git a/crates/compiler/load_internal/tests/fixtures/build/interface_with_deps/ImportAlias.roc b/crates/compiler/load_internal/tests/fixtures/build/module_with_deps/ImportAlias.roc similarity index 100% rename from crates/compiler/load_internal/tests/fixtures/build/interface_with_deps/ImportAlias.roc rename to crates/compiler/load_internal/tests/fixtures/build/module_with_deps/ImportAlias.roc diff --git a/crates/compiler/load_internal/tests/fixtures/build/interface_with_deps/ImportInsideDef.roc b/crates/compiler/load_internal/tests/fixtures/build/module_with_deps/ImportInsideDef.roc similarity index 100% rename from crates/compiler/load_internal/tests/fixtures/build/interface_with_deps/ImportInsideDef.roc rename to crates/compiler/load_internal/tests/fixtures/build/module_with_deps/ImportInsideDef.roc diff --git a/crates/compiler/load_internal/tests/fixtures/build/interface_with_deps/ImportUsedOutsideScope.roc b/crates/compiler/load_internal/tests/fixtures/build/module_with_deps/ImportUsedOutsideScope.roc similarity index 100% rename from crates/compiler/load_internal/tests/fixtures/build/interface_with_deps/ImportUsedOutsideScope.roc rename to crates/compiler/load_internal/tests/fixtures/build/module_with_deps/ImportUsedOutsideScope.roc diff --git a/crates/compiler/load_internal/tests/fixtures/build/interface_with_deps/IngestedFile.roc b/crates/compiler/load_internal/tests/fixtures/build/module_with_deps/IngestedFile.roc similarity index 100% rename from crates/compiler/load_internal/tests/fixtures/build/interface_with_deps/IngestedFile.roc rename to crates/compiler/load_internal/tests/fixtures/build/module_with_deps/IngestedFile.roc diff --git a/crates/compiler/load_internal/tests/fixtures/build/interface_with_deps/IngestedFileBytes.roc b/crates/compiler/load_internal/tests/fixtures/build/module_with_deps/IngestedFileBytes.roc similarity index 100% rename from crates/compiler/load_internal/tests/fixtures/build/interface_with_deps/IngestedFileBytes.roc rename to crates/compiler/load_internal/tests/fixtures/build/module_with_deps/IngestedFileBytes.roc diff --git a/crates/compiler/load_internal/tests/fixtures/build/interface_with_deps/ManualAttr.roc b/crates/compiler/load_internal/tests/fixtures/build/module_with_deps/ManualAttr.roc similarity index 100% rename from crates/compiler/load_internal/tests/fixtures/build/interface_with_deps/ManualAttr.roc rename to crates/compiler/load_internal/tests/fixtures/build/module_with_deps/ManualAttr.roc diff --git a/crates/compiler/load_internal/tests/fixtures/build/interface_with_deps/OneDep.roc b/crates/compiler/load_internal/tests/fixtures/build/module_with_deps/OneDep.roc similarity index 100% rename from crates/compiler/load_internal/tests/fixtures/build/interface_with_deps/OneDep.roc rename to crates/compiler/load_internal/tests/fixtures/build/module_with_deps/OneDep.roc diff --git a/crates/compiler/load_internal/tests/fixtures/build/interface_with_deps/Primary.roc b/crates/compiler/load_internal/tests/fixtures/build/module_with_deps/Primary.roc similarity index 100% rename from crates/compiler/load_internal/tests/fixtures/build/interface_with_deps/Primary.roc rename to crates/compiler/load_internal/tests/fixtures/build/module_with_deps/Primary.roc diff --git a/crates/compiler/load_internal/tests/fixtures/build/interface_with_deps/Quicksort.roc b/crates/compiler/load_internal/tests/fixtures/build/module_with_deps/Quicksort.roc similarity index 100% rename from crates/compiler/load_internal/tests/fixtures/build/interface_with_deps/Quicksort.roc rename to crates/compiler/load_internal/tests/fixtures/build/module_with_deps/Quicksort.roc diff --git a/crates/compiler/load_internal/tests/fixtures/build/interface_with_deps/Records.roc b/crates/compiler/load_internal/tests/fixtures/build/module_with_deps/Records.roc similarity index 100% rename from crates/compiler/load_internal/tests/fixtures/build/interface_with_deps/Records.roc rename to crates/compiler/load_internal/tests/fixtures/build/module_with_deps/Records.roc diff --git a/crates/compiler/load_internal/tests/fixtures/build/interface_with_deps/Res.roc b/crates/compiler/load_internal/tests/fixtures/build/module_with_deps/Res.roc similarity index 100% rename from crates/compiler/load_internal/tests/fixtures/build/interface_with_deps/Res.roc rename to crates/compiler/load_internal/tests/fixtures/build/module_with_deps/Res.roc diff --git a/crates/compiler/load_internal/tests/fixtures/build/interface_with_deps/WithBuiltins.roc b/crates/compiler/load_internal/tests/fixtures/build/module_with_deps/WithBuiltins.roc similarity index 100% rename from crates/compiler/load_internal/tests/fixtures/build/interface_with_deps/WithBuiltins.roc rename to crates/compiler/load_internal/tests/fixtures/build/module_with_deps/WithBuiltins.roc diff --git a/crates/compiler/load_internal/tests/test_load.rs b/crates/compiler/load_internal/tests/test_load.rs index 4fd07f7534..7f31496f56 100644 --- a/crates/compiler/load_internal/tests/test_load.rs +++ b/crates/compiler/load_internal/tests/test_load.rs @@ -339,7 +339,7 @@ fn import_transitive_alias() { "RBTree.roc", indoc!( r" - interface RBTree exposes [RedBlackTree, empty] imports [] + module [RedBlackTree, empty] # The color of a node. Leaves are considered Black. NodeColor : [Red, Black] @@ -357,7 +357,7 @@ fn import_transitive_alias() { "Other.roc", indoc!( r" - interface Other exposes [empty] imports [] + module [empty] import RBTree @@ -372,9 +372,9 @@ fn import_transitive_alias() { } #[test] -fn interface_with_deps() { +fn module_with_deps() { let subs_by_module = Default::default(); - let src_dir = fixtures_dir().join("interface_with_deps"); + let src_dir = fixtures_dir().join("module_with_deps"); let filename = src_dir.join("Primary.roc"); let arena = Bump::new(); let loaded = load_and_typecheck( @@ -488,7 +488,7 @@ fn load_docs() { #[test] fn import_alias() { let subs_by_module = Default::default(); - let loaded_module = load_fixture("interface_with_deps", "ImportAlias", subs_by_module); + let loaded_module = load_fixture("module_with_deps", "ImportAlias", subs_by_module); expect_types( loaded_module, @@ -501,7 +501,7 @@ fn import_alias() { #[test] fn import_inside_def() { let subs_by_module = Default::default(); - let loaded_module = load_fixture("interface_with_deps", "ImportInsideDef", subs_by_module); + let loaded_module = load_fixture("module_with_deps", "ImportInsideDef", subs_by_module); expect_types( loaded_module, @@ -517,7 +517,7 @@ fn import_inside_def() { fn exposed_used_outside_scope() { let subs_by_module = Default::default(); load_fixture( - "interface_with_deps", + "module_with_deps", "ExposedUsedOutsideScope", subs_by_module, ); @@ -527,17 +527,13 @@ fn exposed_used_outside_scope() { #[should_panic(expected = "MODULE NOT IMPORTED")] fn import_used_outside_scope() { let subs_by_module = Default::default(); - load_fixture( - "interface_with_deps", - "ImportUsedOutsideScope", - subs_by_module, - ); + load_fixture("module_with_deps", "ImportUsedOutsideScope", subs_by_module); } #[test] fn test_load_and_typecheck() { let subs_by_module = Default::default(); - let loaded_module = load_fixture("interface_with_deps", "WithBuiltins", subs_by_module); + let loaded_module = load_fixture("module_with_deps", "WithBuiltins", subs_by_module); expect_types( loaded_module, @@ -558,7 +554,7 @@ fn test_load_and_typecheck() { #[test] fn iface_quicksort() { let subs_by_module = Default::default(); - let loaded_module = load_fixture("interface_with_deps", "Quicksort", subs_by_module); + let loaded_module = load_fixture("module_with_deps", "Quicksort", subs_by_module); expect_types( loaded_module, @@ -574,7 +570,7 @@ fn iface_quicksort() { #[test] fn load_astar() { let subs_by_module = Default::default(); - let loaded_module = load_fixture("interface_with_deps", "AStar", subs_by_module); + let loaded_module = load_fixture("module_with_deps", "AStar", subs_by_module); expect_types( loaded_module, @@ -606,7 +602,7 @@ fn load_principal_types() { #[test] fn iface_dep_types() { let subs_by_module = Default::default(); - let loaded_module = load_fixture("interface_with_deps", "Primary", subs_by_module); + let loaded_module = load_fixture("module_with_deps", "Primary", subs_by_module); expect_types( loaded_module, @@ -650,7 +646,7 @@ fn app_dep_types() { #[test] fn imported_dep_regression() { let subs_by_module = Default::default(); - let loaded_module = load_fixture("interface_with_deps", "OneDep", subs_by_module); + let loaded_module = load_fixture("module_with_deps", "OneDep", subs_by_module); expect_types( loaded_module, @@ -663,7 +659,7 @@ fn imported_dep_regression() { #[test] fn ingested_file() { let subs_by_module = Default::default(); - let loaded_module = load_fixture("interface_with_deps", "IngestedFile", subs_by_module); + let loaded_module = load_fixture("module_with_deps", "IngestedFile", subs_by_module); expect_types( loaded_module, @@ -678,7 +674,7 @@ fn ingested_file() { #[test] fn ingested_file_bytes() { let subs_by_module = Default::default(); - let loaded_module = load_fixture("interface_with_deps", "IngestedFileBytes", subs_by_module); + let loaded_module = load_fixture("module_with_deps", "IngestedFileBytes", subs_by_module); expect_types( loaded_module, @@ -695,7 +691,7 @@ fn parse_problem() { "Main.roc", indoc!( r" - interface Main exposes [main] imports [] + module [main] main = [ " @@ -732,7 +728,7 @@ fn parse_problem() { #[should_panic(expected = "FILE NOT FOUND")] fn file_not_found() { let subs_by_module = Default::default(); - let loaded_module = load_fixture("interface_with_deps", "invalid$name", subs_by_module); + let loaded_module = load_fixture("module_with_deps", "invalid$name", subs_by_module); expect_types( loaded_module, @@ -887,7 +883,7 @@ fn opaque_wrapped_unwrapped_outside_defining_module() { "Age.roc", indoc!( r" - interface Age exposes [Age] imports [] + module [Age] Age := U32 " @@ -897,7 +893,7 @@ fn opaque_wrapped_unwrapped_outside_defining_module() { "Main.roc", indoc!( r" - interface Main exposes [twenty, readAge] imports [] + module [twenty, readAge] import Age exposing [Age] @@ -965,7 +961,8 @@ fn unused_imports() { "Dep1.roc", indoc!( r#" - interface Dep1 exposes [one] imports [] + module [one] + one = 1 "# ), @@ -974,7 +971,8 @@ fn unused_imports() { "Dep2.roc", indoc!( r#" - interface Dep2 exposes [two] imports [] + module [two] + two = 2 "# ), @@ -983,7 +981,7 @@ fn unused_imports() { "Dep3.roc", indoc!( r#" - interface Dep3 exposes [Three, three] imports [] + module [Three, three] Three : [Three] @@ -995,7 +993,7 @@ fn unused_imports() { "Main.roc", indoc!( r#" - interface Main exposes [usedModule, unusedModule, unusedExposed, unusedWithAlias, usingThreeValue] imports [] + module [usedModule, unusedModule, unusedExposed, usingThreeValue, unusedWithAlias] import Dep1 import Dep3 exposing [Three] @@ -1663,48 +1661,13 @@ fn import_builtin_in_platform_and_check_app() { assert!(result.is_ok(), "should check"); } -#[test] -fn module_doesnt_match_file_path() { - let modules = vec![( - "Age.roc", - indoc!( - r" - interface NotAge exposes [Age] imports [] - - Age := U32 - " - ), - )]; - - let err = multiple_modules("module_doesnt_match_file_path", modules).unwrap_err(); - assert_eq!( - err, - indoc!( - r" - ── WEIRD MODULE NAME in tmp/module_doesnt_match_file_path/Age.roc ────────────── - - This module name does not correspond with the file path it is defined - in: - - 1│ interface NotAge exposes [Age] imports [] - ^^^^^^ - - Module names must correspond with the file paths they are defined in. - For example, I expect to see BigNum defined in BigNum.roc, or Math.Sin - defined in Math/Sin.roc." - ), - "\n{}", - err - ); -} - #[test] fn module_cyclic_import_itself() { let modules = vec![( "Age.roc", indoc!( r" - interface Age exposes [] imports [] + module [] import Age " @@ -1742,7 +1705,8 @@ fn module_cyclic_import_transitive() { "Age.roc", indoc!( r" - interface Age exposes [] imports [] + module [] + import Person " ), @@ -1751,7 +1715,8 @@ fn module_cyclic_import_transitive() { "Person.roc", indoc!( r" - interface Person exposes [] imports [] + module [] + import Age " ), diff --git a/crates/compiler/parse/src/ast.rs b/crates/compiler/parse/src/ast.rs index cacefe1e04..e5b337f36d 100644 --- a/crates/compiler/parse/src/ast.rs +++ b/crates/compiler/parse/src/ast.rs @@ -1,7 +1,7 @@ use std::fmt::Debug; use crate::header::{ - self, AppHeader, HostedHeader, InterfaceHeader, ModuleName, PackageHeader, PlatformHeader, + self, AppHeader, HostedHeader, ModuleHeader, ModuleName, PackageHeader, PlatformHeader, }; use crate::ident::Accessor; use crate::parser::ESingleQuote; @@ -99,6 +99,21 @@ pub struct Module<'a> { } impl<'a> Module<'a> { + pub fn upgrade_header_imports(self, arena: &'a Bump) -> (Self, Defs<'a>) { + let (header, defs) = match self.header { + Header::Module(header) => ( + Header::Module(ModuleHeader { + interface_imports: None, + ..header + }), + Self::header_imports_to_defs(arena, header.interface_imports), + ), + header => (header, Defs::default()), + }; + + (Module { header, ..self }, defs) + } + pub fn header_imports_to_defs( arena: &'a Bump, imports: Option< @@ -209,7 +224,7 @@ impl<'a> Module<'a> { #[derive(Clone, Debug, PartialEq)] pub enum Header<'a> { - Interface(InterfaceHeader<'a>), + Module(ModuleHeader<'a>), App(AppHeader<'a>), Package(PackageHeader<'a>), Platform(PlatformHeader<'a>), @@ -2272,7 +2287,7 @@ impl<'a> Malformed for Module<'a> { impl<'a> Malformed for Header<'a> { fn is_malformed(&self) -> bool { match self { - Header::Interface(header) => header.is_malformed(), + Header::Module(header) => header.is_malformed(), Header::App(header) => header.is_malformed(), Header::Package(header) => header.is_malformed(), Header::Platform(header) => header.is_malformed(), diff --git a/crates/compiler/parse/src/header.rs b/crates/compiler/parse/src/header.rs index 4904ecc7e0..4e6e53a519 100644 --- a/crates/compiler/parse/src/header.rs +++ b/crates/compiler/parse/src/header.rs @@ -19,7 +19,7 @@ impl<'a> HeaderType<'a> { } | HeaderType::Hosted { exposes, .. } | HeaderType::Builtin { exposes, .. } - | HeaderType::Interface { exposes, .. } => exposes, + | HeaderType::Module { exposes, .. } => exposes, HeaderType::Platform { .. } | HeaderType::Package { .. } => &[], } } @@ -30,7 +30,7 @@ impl<'a> HeaderType<'a> { HeaderType::Builtin { .. } => "builtin", HeaderType::Package { .. } => "package", HeaderType::Platform { .. } => "platform", - HeaderType::Interface { .. } => "interface", + HeaderType::Module { .. } => "module", } } } @@ -73,7 +73,7 @@ pub enum HeaderType<'a> { /// usually `pf` config_shorthand: &'a str, }, - Interface { + Module { name: ModuleName<'a>, exposes: &'a [Loc>], }, @@ -82,9 +82,9 @@ pub enum HeaderType<'a> { impl<'a> HeaderType<'a> { pub fn get_name(self) -> Option<&'a str> { match self { - Self::Interface { name, .. } - | Self::Builtin { name, .. } - | Self::Hosted { name, .. } => Some(name.into()), + Self::Module { name, .. } | Self::Builtin { name, .. } | Self::Hosted { name, .. } => { + Some(name.into()) + } Self::App { output_name: StrLiteral::PlainLine(name), .. @@ -106,13 +106,11 @@ impl<'a> HeaderType<'a> { pub fn to_maybe_builtin(self, module_id: ModuleId) -> Self { match self { - HeaderType::Interface { name, exposes } if module_id.is_builtin() => { - HeaderType::Builtin { - name, - exposes, - generates_with: &[], - } - } + HeaderType::Module { name, exposes } if module_id.is_builtin() => HeaderType::Builtin { + name, + exposes, + generates_with: &[], + }, _ => self, } } @@ -246,12 +244,12 @@ pub struct KeywordItem<'a, K, V> { } #[derive(Clone, Debug, PartialEq)] -pub struct InterfaceHeader<'a> { - pub before_name: &'a [CommentOrNewline<'a>], - pub name: Loc>, +pub struct ModuleHeader<'a> { + pub before_exposes: &'a [CommentOrNewline<'a>], + pub exposes: Collection<'a, Loc>>>, - pub exposes: KeywordItem<'a, ExposesKeyword, Collection<'a, Loc>>>>, - pub imports: KeywordItem<'a, ImportsKeyword, Collection<'a, Loc>>>>, + // Keeping this so we can format old interface header into module headers + pub interface_imports: Option>>, } pub type ImportsKeywordItem<'a> = KeywordItem<'a, ImportsKeyword, ImportsCollection<'a>>; @@ -430,7 +428,7 @@ where } } -impl<'a> Malformed for InterfaceHeader<'a> { +impl<'a> Malformed for ModuleHeader<'a> { fn is_malformed(&self) -> bool { false } diff --git a/crates/compiler/parse/src/module.rs b/crates/compiler/parse/src/module.rs index 3bbe21249c..b894cab97a 100644 --- a/crates/compiler/parse/src/module.rs +++ b/crates/compiler/parse/src/module.rs @@ -1,10 +1,11 @@ -use crate::ast::{Collection, Defs, Header, Module, Spaced, Spaces}; +use crate::ast::{Collection, CommentOrNewline, Defs, Header, Module, Spaced, Spaces}; use crate::blankspace::{space0_around_ee, space0_before_e, space0_e}; use crate::header::{ package_entry, package_name, AppHeader, ExposedName, ExposesKeyword, GeneratesKeyword, - HostedHeader, ImportsEntry, ImportsKeyword, InterfaceHeader, Keyword, KeywordItem, ModuleName, - PackageEntry, PackageHeader, PackagesKeyword, PlatformHeader, PlatformRequires, - ProvidesKeyword, ProvidesTo, RequiresKeyword, To, ToKeyword, TypedIdent, WithKeyword, + HostedHeader, ImportsEntry, ImportsKeyword, ImportsKeywordItem, Keyword, KeywordItem, + ModuleHeader, ModuleName, PackageEntry, PackageHeader, PackagesKeyword, PlatformHeader, + PlatformRequires, ProvidesKeyword, ProvidesTo, RequiresKeyword, To, ToKeyword, TypedIdent, + WithKeyword, }; use crate::ident::{self, lowercase_ident, unqualified_ident, uppercase, UppercaseIdent}; use crate::parser::Progress::{self, *}; @@ -60,12 +61,20 @@ pub fn header<'a>() -> impl Parser<'a, Module<'a>, EHeader<'a>> { record!(Module { comments: space0_e(EHeader::IndentStart), header: one_of![ + map!( + skip_first!( + keyword("module", EHeader::Start), + increment_min_indent(module_header()) + ), + Header::Module + ), + // Old headers map!( skip_first!( keyword("interface", EHeader::Start), increment_min_indent(interface_header()) ), - Header::Interface + Header::Module ), map!( skip_first!( @@ -100,22 +109,65 @@ pub fn header<'a>() -> impl Parser<'a, Module<'a>, EHeader<'a>> { } #[inline(always)] -fn interface_header<'a>() -> impl Parser<'a, InterfaceHeader<'a>, EHeader<'a>> { - record!(InterfaceHeader { - before_name: space0_e(EHeader::IndentStart), - name: loc!(module_name_help(EHeader::ModuleName)), - exposes: specialize_err(EHeader::Exposes, exposes_values()), - imports: specialize_err(EHeader::Imports, imports()), +fn module_header<'a>() -> impl Parser<'a, ModuleHeader<'a>, EHeader<'a>> { + record!(ModuleHeader { + before_exposes: space0_e(EHeader::IndentStart), + exposes: specialize_err(EHeader::Exposes, exposes_list()), + interface_imports: succeed!(None) + }) + .trace("module_header") +} + +/// Parse old interface headers so we can format them into module headers +#[inline(always)] +fn interface_header<'a>() -> impl Parser<'a, ModuleHeader<'a>, EHeader<'a>> { + use bumpalo::collections::Vec; + + let before_exposes = map_with_arena!( + and!( + skip_second!( + space0_e(EHeader::IndentStart), + loc!(module_name_help(EHeader::ModuleName)) + ), + specialize_err(EHeader::Exposes, exposes_kw()) + ), + |arena: &'a bumpalo::Bump, + (before_name, kw): (&'a [CommentOrNewline<'a>], Spaces<'a, ExposesKeyword>)| { + let mut combined: Vec = + Vec::with_capacity_in(before_name.len() + kw.before.len() + kw.after.len(), arena); + combined.extend(before_name); + combined.extend(kw.before); + combined.extend(kw.after); + arena.alloc(combined) + } + ); + + record!(ModuleHeader { + before_exposes: before_exposes, + exposes: specialize_err(EHeader::Exposes, exposes_list()).trace("exposes_list"), + interface_imports: map!( + specialize_err(EHeader::Imports, imports()), + imports_none_if_empty + ) + .trace("imports"), }) .trace("interface_header") } +fn imports_none_if_empty(value: ImportsKeywordItem<'_>) -> Option> { + if value.item.is_empty() { + None + } else { + Some(value) + } +} + #[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()), + exposes: specialize_err(EHeader::Exposes, exposes_values_kw()), imports: specialize_err(EHeader::Imports, imports()), generates: specialize_err(EHeader::Generates, generates()), generates_with: specialize_err(EHeader::GeneratesWith, generates_with()), @@ -388,28 +440,39 @@ fn requires_typed_ident<'a>() -> impl Parser<'a, Loc>> } #[inline(always)] -fn exposes_values<'a>() -> impl Parser< +fn exposes_values_kw<'a>() -> impl Parser< 'a, KeywordItem<'a, ExposesKeyword, Collection<'a, Loc>>>>, EExposes, > { record!(KeywordItem { - keyword: spaces_around_keyword( - ExposesKeyword, - EExposes::Exposes, - EExposes::IndentExposes, - EExposes::IndentListStart - ), - item: collection_trailing_sep_e!( - byte(b'[', EExposes::ListStart), - exposes_entry(EExposes::Identifier), - byte(b',', EExposes::ListEnd), - byte(b']', EExposes::ListEnd), - Spaced::SpaceBefore - ) + keyword: exposes_kw(), + item: exposes_list() }) } +#[inline(always)] +fn exposes_kw<'a>() -> impl Parser<'a, Spaces<'a, ExposesKeyword>, EExposes> { + spaces_around_keyword( + ExposesKeyword, + EExposes::Exposes, + EExposes::IndentExposes, + EExposes::IndentListStart, + ) +} + +#[inline(always)] +fn exposes_list<'a>() -> impl Parser<'a, Collection<'a, Loc>>>, EExposes> +{ + collection_trailing_sep_e!( + byte(b'[', EExposes::ListStart), + exposes_entry(EExposes::Identifier), + byte(b',', EExposes::ListEnd), + byte(b']', EExposes::ListEnd), + Spaced::SpaceBefore + ) +} + pub fn spaces_around_keyword<'a, K: Keyword, E>( keyword_item: K, expectation: fn(Position) -> E, diff --git a/crates/compiler/test_syntax/fuzz/dict.txt b/crates/compiler/test_syntax/fuzz/dict.txt index 6368aa3e2d..f57d4e5a41 100644 --- a/crates/compiler/test_syntax/fuzz/dict.txt +++ b/crates/compiler/test_syntax/fuzz/dict.txt @@ -37,4 +37,4 @@ ":=" ":" "@" -"->" \ No newline at end of file +"->" diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/empty_interface_header.header.formatted.roc b/crates/compiler/test_syntax/tests/snapshots/pass/empty_interface_header.header.formatted.roc deleted file mode 100644 index 5959237bda..0000000000 --- a/crates/compiler/test_syntax/tests/snapshots/pass/empty_interface_header.header.formatted.roc +++ /dev/null @@ -1 +0,0 @@ -interface Foo exposes [] imports [] diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/empty_interface_header.header.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/empty_interface_header.header.result-ast deleted file mode 100644 index f76696a1f0..0000000000 --- a/crates/compiler/test_syntax/tests/snapshots/pass/empty_interface_header.header.result-ast +++ /dev/null @@ -1,27 +0,0 @@ -Module { - comments: [], - header: Interface( - InterfaceHeader { - before_name: [], - name: @10-13 ModuleName( - "Foo", - ), - exposes: KeywordItem { - keyword: Spaces { - before: [], - item: ExposesKeyword, - after: [], - }, - item: [], - }, - imports: KeywordItem { - keyword: Spaces { - before: [], - item: ImportsKeyword, - after: [], - }, - item: [], - }, - }, - ), -} diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/empty_interface_header.header.roc b/crates/compiler/test_syntax/tests/snapshots/pass/empty_interface_header.header.roc deleted file mode 100644 index 5959237bda..0000000000 --- a/crates/compiler/test_syntax/tests/snapshots/pass/empty_interface_header.header.roc +++ /dev/null @@ -1 +0,0 @@ -interface Foo exposes [] imports [] diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/empty_module_header.header.formatted.roc b/crates/compiler/test_syntax/tests/snapshots/pass/empty_module_header.header.formatted.roc new file mode 100644 index 0000000000..9fd98c5b23 --- /dev/null +++ b/crates/compiler/test_syntax/tests/snapshots/pass/empty_module_header.header.formatted.roc @@ -0,0 +1 @@ +module [] diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/empty_module_header.header.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/empty_module_header.header.result-ast new file mode 100644 index 0000000000..1a8dc9ac38 --- /dev/null +++ b/crates/compiler/test_syntax/tests/snapshots/pass/empty_module_header.header.result-ast @@ -0,0 +1,10 @@ +Module { + comments: [], + header: Module( + ModuleHeader { + before_exposes: [], + exposes: [], + interface_imports: None, + }, + ), +} diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/empty_module_header.header.roc b/crates/compiler/test_syntax/tests/snapshots/pass/empty_module_header.header.roc new file mode 100644 index 0000000000..9fd98c5b23 --- /dev/null +++ b/crates/compiler/test_syntax/tests/snapshots/pass/empty_module_header.header.roc @@ -0,0 +1 @@ +module [] diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/interface_with_newline.header.formatted.roc b/crates/compiler/test_syntax/tests/snapshots/pass/interface_with_newline.header.formatted.roc deleted file mode 100644 index 18d25e0fb5..0000000000 --- a/crates/compiler/test_syntax/tests/snapshots/pass/interface_with_newline.header.formatted.roc +++ /dev/null @@ -1 +0,0 @@ -interface T exposes [] imports [] diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/interface_with_newline.header.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/interface_with_newline.header.result-ast deleted file mode 100644 index 35be4cfd94..0000000000 --- a/crates/compiler/test_syntax/tests/snapshots/pass/interface_with_newline.header.result-ast +++ /dev/null @@ -1,27 +0,0 @@ -Module { - comments: [], - header: Interface( - InterfaceHeader { - before_name: [], - name: @10-11 ModuleName( - "T", - ), - exposes: KeywordItem { - keyword: Spaces { - before: [], - item: ExposesKeyword, - after: [], - }, - item: [], - }, - imports: KeywordItem { - keyword: Spaces { - before: [], - item: ImportsKeyword, - after: [], - }, - item: [], - }, - }, - ), -} diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/interface_with_newline.header.roc b/crates/compiler/test_syntax/tests/snapshots/pass/interface_with_newline.header.roc deleted file mode 100644 index 18d25e0fb5..0000000000 --- a/crates/compiler/test_syntax/tests/snapshots/pass/interface_with_newline.header.roc +++ /dev/null @@ -1 +0,0 @@ -interface T exposes [] imports [] diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/module_multiline_exposes.header.formatted.roc b/crates/compiler/test_syntax/tests/snapshots/pass/module_multiline_exposes.header.formatted.roc new file mode 100644 index 0000000000..01e08f75b4 --- /dev/null +++ b/crates/compiler/test_syntax/tests/snapshots/pass/module_multiline_exposes.header.formatted.roc @@ -0,0 +1,5 @@ +module [ + a, + b, + c, +] diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/module_multiline_exposes.header.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/module_multiline_exposes.header.result-ast new file mode 100644 index 0000000000..d2c3418a3f --- /dev/null +++ b/crates/compiler/test_syntax/tests/snapshots/pass/module_multiline_exposes.header.result-ast @@ -0,0 +1,25 @@ +Module { + comments: [], + header: Module( + ModuleHeader { + before_exposes: [], + exposes: [ + @8-9 ExposedName( + "a", + ), + @11-12 ExposedName( + "b", + ), + @18-19 SpaceBefore( + ExposedName( + "c", + ), + [ + Newline, + ], + ), + ], + interface_imports: None, + }, + ), +} diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/module_multiline_exposes.header.roc b/crates/compiler/test_syntax/tests/snapshots/pass/module_multiline_exposes.header.roc new file mode 100644 index 0000000000..1be893fce4 --- /dev/null +++ b/crates/compiler/test_syntax/tests/snapshots/pass/module_multiline_exposes.header.roc @@ -0,0 +1,2 @@ +module [a, b, + c] diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/module_with_newline.header.formatted.roc b/crates/compiler/test_syntax/tests/snapshots/pass/module_with_newline.header.formatted.roc new file mode 100644 index 0000000000..9fd98c5b23 --- /dev/null +++ b/crates/compiler/test_syntax/tests/snapshots/pass/module_with_newline.header.formatted.roc @@ -0,0 +1 @@ +module [] diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/module_with_newline.header.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/module_with_newline.header.result-ast new file mode 100644 index 0000000000..1a8dc9ac38 --- /dev/null +++ b/crates/compiler/test_syntax/tests/snapshots/pass/module_with_newline.header.result-ast @@ -0,0 +1,10 @@ +Module { + comments: [], + header: Module( + ModuleHeader { + before_exposes: [], + exposes: [], + interface_imports: None, + }, + ), +} diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/module_with_newline.header.roc b/crates/compiler/test_syntax/tests/snapshots/pass/module_with_newline.header.roc new file mode 100644 index 0000000000..9fd98c5b23 --- /dev/null +++ b/crates/compiler/test_syntax/tests/snapshots/pass/module_with_newline.header.roc @@ -0,0 +1 @@ +module [] diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/nested_module.header.formatted.roc b/crates/compiler/test_syntax/tests/snapshots/pass/nested_module.header.formatted.roc deleted file mode 100644 index f43501c404..0000000000 --- a/crates/compiler/test_syntax/tests/snapshots/pass/nested_module.header.formatted.roc +++ /dev/null @@ -1 +0,0 @@ -interface Foo.Bar.Baz exposes [] imports [] diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/nested_module.header.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/nested_module.header.result-ast deleted file mode 100644 index 6a5064bc38..0000000000 --- a/crates/compiler/test_syntax/tests/snapshots/pass/nested_module.header.result-ast +++ /dev/null @@ -1,27 +0,0 @@ -Module { - comments: [], - header: Interface( - InterfaceHeader { - before_name: [], - name: @10-21 ModuleName( - "Foo.Bar.Baz", - ), - exposes: KeywordItem { - keyword: Spaces { - before: [], - item: ExposesKeyword, - after: [], - }, - item: [], - }, - imports: KeywordItem { - keyword: Spaces { - before: [], - item: ImportsKeyword, - after: [], - }, - item: [], - }, - }, - ), -} diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/nested_module.header.roc b/crates/compiler/test_syntax/tests/snapshots/pass/nested_module.header.roc deleted file mode 100644 index f43501c404..0000000000 --- a/crates/compiler/test_syntax/tests/snapshots/pass/nested_module.header.roc +++ /dev/null @@ -1 +0,0 @@ -interface Foo.Bar.Baz exposes [] imports [] diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/old_interface_header.header.formatted.roc b/crates/compiler/test_syntax/tests/snapshots/pass/old_interface_header.header.formatted.roc new file mode 100644 index 0000000000..517299113f --- /dev/null +++ b/crates/compiler/test_syntax/tests/snapshots/pass/old_interface_header.header.formatted.roc @@ -0,0 +1 @@ +module [Foo, foo, bar] diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/old_interface_header.header.result-ast b/crates/compiler/test_syntax/tests/snapshots/pass/old_interface_header.header.result-ast new file mode 100644 index 0000000000..265abe6b51 --- /dev/null +++ b/crates/compiler/test_syntax/tests/snapshots/pass/old_interface_header.header.result-ast @@ -0,0 +1,20 @@ +Module { + comments: [], + header: Module( + ModuleHeader { + before_exposes: [], + exposes: [ + @23-26 ExposedName( + "Foo", + ), + @28-31 ExposedName( + "foo", + ), + @33-36 ExposedName( + "bar", + ), + ], + interface_imports: None, + }, + ), +} diff --git a/crates/compiler/test_syntax/tests/snapshots/pass/old_interface_header.header.roc b/crates/compiler/test_syntax/tests/snapshots/pass/old_interface_header.header.roc new file mode 100644 index 0000000000..d1abf476b0 --- /dev/null +++ b/crates/compiler/test_syntax/tests/snapshots/pass/old_interface_header.header.roc @@ -0,0 +1 @@ +interface Foo exposes [Foo, foo, bar] imports [] diff --git a/crates/compiler/test_syntax/tests/test_fmt.rs b/crates/compiler/test_syntax/tests/test_fmt.rs index 5ee62a0716..121722bf7f 100644 --- a/crates/compiler/test_syntax/tests/test_fmt.rs +++ b/crates/compiler/test_syntax/tests/test_fmt.rs @@ -4768,10 +4768,10 @@ mod test_fmt { // MODULES #[test] - fn single_line_interface() { + fn single_line_module() { module_formats_same(indoc!( r" - interface Foo exposes [] imports []" + module []" )); } @@ -4781,12 +4781,14 @@ mod test_fmt { module_formats_to( indoc!( r" - interface Foo exposes [] imports [] + module [] + a = 42 # Yay greetings" ), indoc!( r" - interface Foo exposes [] imports [] + module [] + a = 42 # Yay greetings " ), @@ -4794,49 +4796,25 @@ mod test_fmt { } #[test] - fn multiline_interface() { + fn module_exposing() { module_formats_same(indoc!( r" - interface Foo - exposes [] - imports []" + module [Bar, Baz, a, b]" )); } #[test] - fn interface_exposing() { + fn module_exposing_multiline() { module_formats_same(indoc!( r" - interface Foo - exposes [Bar, Baz, a, b] - imports []" - )); - } + module [ + Stuff, + Things, + somethingElse, + ] - #[test] - fn interface_importing() { - module_formats_same(indoc!( - r" - interface Foo - exposes [Bar, Baz, a, b] - imports [Blah, Thing.{ foo, bar }, Stuff]" - )); - } - - #[test] - fn multi_line_interface() { - module_formats_same(indoc!( - r" - interface Foo - exposes [ - Stuff, - Things, - somethingElse, - ] - imports [ - Blah, - Baz.{ stuff, things }, - ]" + import Blah + import Baz exposing [stuff, things]" )); } @@ -4866,9 +4844,7 @@ mod test_fmt { &format!( indoc!( r#" - interface Foo - exposes [] - imports [] + module [] # comment 1{space} def = "" # comment 2{space} @@ -4879,9 +4855,7 @@ mod test_fmt { ), indoc!( r#" - interface Foo - exposes [] - imports [] + module [] # comment 1 def = "" # comment 2 @@ -5700,7 +5674,7 @@ mod test_fmt { module_formats_same(indoc!( r" - interface Foo exposes [] imports [] + module [] expect x == y @@ -5727,7 +5701,7 @@ mod test_fmt { module_formats_same(indoc!( r" - interface Foo exposes [] imports [] + module [] expect foo bar @@ -5831,7 +5805,7 @@ mod test_fmt { fn ability_member_doc_comments() { module_formats_same(indoc!( r" - interface Foo exposes [] imports [] + module [] A implements ## This is member ab @@ -5850,9 +5824,7 @@ mod test_fmt { module_formats_same(indoc!( r" # hello world - interface Foo - exposes [] - imports [] + module [] " )); @@ -5876,6 +5848,17 @@ mod test_fmt { )); } + #[test] + fn comments_before_exposes_preserved() { + module_formats_same(indoc!( + r" + module + # comment + [a, b] + " + )); + } + #[test] fn clauses_with_multiple_abilities() { expr_formats_same(indoc!( diff --git a/crates/compiler/test_syntax/tests/test_snapshots.rs b/crates/compiler/test_syntax/tests/test_snapshots.rs index e678f77cd7..3a634be337 100644 --- a/crates/compiler/test_syntax/tests/test_snapshots.rs +++ b/crates/compiler/test_syntax/tests/test_snapshots.rs @@ -301,8 +301,8 @@ mod test_snapshots { pass/def_without_newline.expr, pass/destructure_tag_assignment.expr, pass/empty_app_header.header, + pass/empty_module_header.header, pass/empty_hosted_header.header, - pass/empty_interface_header.header, pass/empty_list.expr, pass/empty_package_header.header, pass/empty_platform_header.header, @@ -333,7 +333,7 @@ mod test_snapshots { pass/inline_import.expr, pass/inline_ingested_file.expr, pass/int_with_underscore.expr, - pass/interface_with_newline.header, + pass/module_with_newline.header, pass/lambda_in_chain.expr, pass/lambda_indent.expr, pass/list_closing_indent_not_enough.expr, @@ -348,6 +348,7 @@ mod test_snapshots { pass/minus_twelve_minus_five.expr, pass/mixed_docs.expr, pass/module_def_newline.moduledefs, + pass/module_multiline_exposes.header, pass/multi_backpassing.expr, pass/multi_backpassing_in_def.moduledefs, pass/multi_backpassing_with_apply.expr, @@ -369,7 +370,6 @@ mod test_snapshots { pass/nested_def_annotation.moduledefs, pass/nested_def_without_newline.expr, pass/nested_if.expr, - pass/nested_module.header, pass/newline_after_equals.expr, // Regression test for https://github.com/roc-lang/roc/issues/51 pass/newline_after_mul.expr, pass/newline_after_paren.expr, @@ -409,6 +409,7 @@ mod test_snapshots { pass/outdented_colon_in_record.expr, pass/outdented_list.expr, pass/outdented_record.expr, + pass/old_interface_header.header, pass/packed_singleton_list.expr, pass/parens_in_type_def_apply.expr, pass/parens_in_value_def_annotation.expr, diff --git a/crates/language_server/src/analysis/tokens.rs b/crates/language_server/src/analysis/tokens.rs index 0e9eecd412..8f31645131 100644 --- a/crates/language_server/src/analysis/tokens.rs +++ b/crates/language_server/src/analysis/tokens.rs @@ -11,9 +11,8 @@ use roc_parse::{ WhenBranch, }, header::{ - AppHeader, ExposedName, HostedHeader, ImportsEntry, InterfaceHeader, ModuleName, - PackageEntry, PackageHeader, PackageName, PlatformHeader, PlatformRequires, ProvidesTo, To, - TypedIdent, + AppHeader, ExposedName, HostedHeader, ImportsEntry, ModuleHeader, ModuleName, PackageEntry, + PackageHeader, PackageName, PlatformHeader, PlatformRequires, ProvidesTo, To, TypedIdent, }, ident::{Accessor, UppercaseIdent}, }; @@ -202,7 +201,7 @@ impl IterTokens for Module<'_> { impl IterTokens for Header<'_> { fn iter_tokens<'a>(&self, arena: &'a Bump) -> BumpVec<'a, Loc> { match self { - Header::Interface(ih) => ih.iter_tokens(arena), + Header::Module(mh) => mh.iter_tokens(arena), Header::App(app) => app.iter_tokens(arena), Header::Package(pkg) => pkg.iter_tokens(arena), Header::Platform(pf) => pf.iter_tokens(arena), @@ -211,19 +210,15 @@ impl IterTokens for Header<'_> { } } -impl IterTokens for InterfaceHeader<'_> { +impl IterTokens for ModuleHeader<'_> { fn iter_tokens<'a>(&self, arena: &'a Bump) -> BumpVec<'a, Loc> { let Self { - before_name: _, - name, + before_exposes: _, exposes, - imports, + interface_imports: _, } = self; - (name.iter_tokens(arena).into_iter()) - .chain(exposes.item.iter_tokens(arena)) - .chain(imports.item.iter_tokens(arena)) - .collect_in(arena) + exposes.iter_tokens(arena) } } diff --git a/crates/packaging/src/tarball.rs b/crates/packaging/src/tarball.rs index 1792f0f2f1..d55be9ddbd 100644 --- a/crates/packaging/src/tarball.rs +++ b/crates/packaging/src/tarball.rs @@ -128,7 +128,7 @@ fn write_archive(path: &Path, writer: W) -> io::Result<()> { // TODO use this when finding .roc files by discovering them from the root module. // let other_modules: &[Module<'_>] = match read_header(&arena, &mut buf, path)?.header { - Header::Interface(_) => { + Header::Module(_) => { todo!(); // TODO report error } diff --git a/crates/reporting/src/error/parse.rs b/crates/reporting/src/error/parse.rs index 4430881550..eb3c211d7c 100644 --- a/crates/reporting/src/error/parse.rs +++ b/crates/reporting/src/error/parse.rs @@ -3621,7 +3621,7 @@ fn to_exposes_report<'a>( "I was expecting a type name, value name or function name next, like", )]), alloc - .parser_suggestion("exposes [Animal, default, tame]") + .parser_suggestion("[Animal, default, tame]") .indent(4), ]); @@ -3646,7 +3646,7 @@ fn to_exposes_report<'a>( alloc.reflow(" keyword next, like"), ]), alloc - .parser_suggestion("exposes [Animal, default, tame]") + .parser_suggestion("[Animal, default, tame]") .indent(4), ]); diff --git a/design/editor/editor-ideas.md b/design/editor/editor-ideas.md index 5b89e18506..ecfdf6dd49 100644 --- a/design/editor/editor-ideas.md +++ b/design/editor/editor-ideas.md @@ -102,7 +102,7 @@ e.g. you have a test `calculate_sum_test` that only uses the function `add`, whe - [Unisonweb](https://www.unisonweb.org), definition based [editor](https://twitter.com/shojberg/status/1364666092598288385) as opposed to file based. - [Utopia](https://utopia.app/) integrated design and development environment for React. Design and code update each other, in real time. - [Paredit](https://calva.io/paredit/) structural clojure editing, navigation and selection. [Another overview](http://danmidwood.com/content/2014/11/21/animated-paredit.html) -- [tylr](https://tylr.fun/) projectional editor UX that helps you make it easier to do edits that are typically difficult with projectional editors but are easy with classic editors. +- [tylr](https://tylr.fun/) projectional editor UX that helps you make it easier to do edits that are typically difficult with projectional editors but are easy with classic editors. ### Project exploration diff --git a/examples/Community.roc b/examples/Community.roc index 370d599a2c..f413f133e5 100644 --- a/examples/Community.roc +++ b/examples/Community.roc @@ -1,13 +1,11 @@ -interface Community - exposes [ - Community, - empty, - addPerson, - addFriend, - Person, - walkFriendNames, - ] - imports [] +module [ + Community, + empty, + addPerson, + addFriend, + Person, + walkFriendNames, +] ## Datatype representing a community for demonstration purposes in inspect-gui.roc and inspect-logging.roc diff --git a/examples/GuiFormatter.roc b/examples/GuiFormatter.roc index 801d7e0f39..146da44008 100644 --- a/examples/GuiFormatter.roc +++ b/examples/GuiFormatter.roc @@ -1,9 +1,7 @@ -interface GuiFormatter - exposes [ - GuiFormatter, - toGui, - ] - imports [] +module [ + GuiFormatter, + toGui, +] ## Creates GUI representations of Roc values, for use in inspect-gui.roc diff --git a/examples/cli/false-interpreter/Context.roc b/examples/cli/false-interpreter/Context.roc index 6a24f9d430..747124a334 100644 --- a/examples/cli/false-interpreter/Context.roc +++ b/examples/cli/false-interpreter/Context.roc @@ -1,6 +1,8 @@ -interface Context - exposes [Context, Data, with, getChar, Option, pushStack, popStack, toStr, inWhileScope] - imports [pf.File, pf.Task.{ Task }, Variable.{ Variable }] +module [Context, Data, with, getChar, Option, pushStack, popStack, toStr, inWhileScope] + +import pf.File +import pf.Task exposing [Task] +import Variable exposing [Variable] Option a : [Some a, None] diff --git a/examples/cli/false-interpreter/Variable.roc b/examples/cli/false-interpreter/Variable.roc index dbf9bc7880..9169963271 100644 --- a/examples/cli/false-interpreter/Variable.roc +++ b/examples/cli/false-interpreter/Variable.roc @@ -1,6 +1,4 @@ -interface Variable - exposes [Variable, fromUtf8, toIndex, totalCount, toStr] - imports [] +module [Variable, fromUtf8, toIndex, totalCount, toStr] # Variables in False can only be single letters. Thus, the valid variables are "a" to "z". # This opaque type deals with ensure we always have valid variables. diff --git a/examples/cli/false-interpreter/platform/File.roc b/examples/cli/false-interpreter/platform/File.roc index f112470a39..9d6e2e8677 100644 --- a/examples/cli/false-interpreter/platform/File.roc +++ b/examples/cli/false-interpreter/platform/File.roc @@ -1,6 +1,7 @@ -interface File - exposes [line, Handle, withOpen, chunk] - imports [pf.Effect, Task.{ Task }] +module [line, Handle, withOpen, chunk] + +import pf.Effect +import Task exposing [Task] Handle := U64 diff --git a/examples/cli/false-interpreter/platform/Stdin.roc b/examples/cli/false-interpreter/platform/Stdin.roc index d734dffc1f..0f03c1f946 100644 --- a/examples/cli/false-interpreter/platform/Stdin.roc +++ b/examples/cli/false-interpreter/platform/Stdin.roc @@ -1,6 +1,7 @@ -interface Stdin - exposes [char] - imports [pf.Effect, Task] +module [char] + +import pf.Effect +import Task # line : Task.Task Str * # line = Effect.after Effect.getLine Task.succeed # TODO FIXME Effect.getLine should suffice diff --git a/examples/cli/false-interpreter/platform/Stdout.roc b/examples/cli/false-interpreter/platform/Stdout.roc index 97b009b7ae..54b45834f5 100644 --- a/examples/cli/false-interpreter/platform/Stdout.roc +++ b/examples/cli/false-interpreter/platform/Stdout.roc @@ -1,6 +1,7 @@ -interface Stdout - exposes [line, raw] - imports [pf.Effect, Task.{ Task }] +module [line, raw] + +import pf.Effect +import Task exposing [Task] line : Str -> Task {} * line = \str -> Effect.map (Effect.putLine str) (\_ -> Ok {}) diff --git a/examples/cli/false-interpreter/platform/Task.roc b/examples/cli/false-interpreter/platform/Task.roc index c6bbb698c9..d5f212da47 100644 --- a/examples/cli/false-interpreter/platform/Task.roc +++ b/examples/cli/false-interpreter/platform/Task.roc @@ -1,6 +1,6 @@ -interface Task - exposes [Task, succeed, fail, await, map, onFail, attempt, fromResult, loop] - imports [pf.Effect] +module [Task, succeed, fail, await, map, onFail, attempt, fromResult, loop] + +import pf.Effect Task ok err : Effect.Effect (Result ok err) diff --git a/examples/cli/tui-platform/Program.roc b/examples/cli/tui-platform/Program.roc index 6e8bffb5aa..b95ec62eb7 100644 --- a/examples/cli/tui-platform/Program.roc +++ b/examples/cli/tui-platform/Program.roc @@ -1,6 +1,4 @@ -interface Program - exposes [Program] - imports [] +module [Program] Program model : { init : {} -> model, diff --git a/examples/gui/breakout/platform/Action.roc b/examples/gui/breakout/platform/Action.roc index 6a5e019c73..073c517f58 100644 --- a/examples/gui/breakout/platform/Action.roc +++ b/examples/gui/breakout/platform/Action.roc @@ -1,6 +1,4 @@ -interface Action - exposes [Action, none, update, map] - imports [] +module [Action, none, update, map] Action state : [None, Update state] diff --git a/examples/gui/breakout/platform/Elem.roc b/examples/gui/breakout/platform/Elem.roc index 64aef819d9..dbfb4c04d2 100644 --- a/examples/gui/breakout/platform/Elem.roc +++ b/examples/gui/breakout/platform/Elem.roc @@ -1,6 +1,6 @@ -interface Elem - exposes [Elem, PressEvent, row, col, text, button, none, translate, list] - imports [Action.{ Action }] +module [Elem, PressEvent, row, col, text, button, none, translate, list] + +import Action exposing [Action] Elem state : [ # PERFORMANCE NOTE: diff --git a/examples/gui/breakout/platform/Game.roc b/examples/gui/breakout/platform/Game.roc index 26b966bf8d..19f6fa31ca 100644 --- a/examples/gui/breakout/platform/Game.roc +++ b/examples/gui/breakout/platform/Game.roc @@ -1,6 +1,4 @@ -interface Game - exposes [Bounds, Elem, Event] - imports [] +module [Bounds, Elem, Event] Rgba : { r : F32, g : F32, b : F32, a : F32 } diff --git a/examples/gui/platform/Action.roc b/examples/gui/platform/Action.roc index 6a5e019c73..073c517f58 100644 --- a/examples/gui/platform/Action.roc +++ b/examples/gui/platform/Action.roc @@ -1,6 +1,4 @@ -interface Action - exposes [Action, none, update, map] - imports [] +module [Action, none, update, map] Action state : [None, Update state] diff --git a/examples/gui/platform/Elem.roc b/examples/gui/platform/Elem.roc index 64aef819d9..dbfb4c04d2 100644 --- a/examples/gui/platform/Elem.roc +++ b/examples/gui/platform/Elem.roc @@ -1,6 +1,6 @@ -interface Elem - exposes [Elem, PressEvent, row, col, text, button, none, translate, list] - imports [Action.{ Action }] +module [Elem, PressEvent, row, col, text, button, none, translate, list] + +import Action exposing [Action] Elem state : [ # PERFORMANCE NOTE: diff --git a/examples/static-site-gen/platform/Html.roc b/examples/static-site-gen/platform/Html.roc index 9052b957b5..a7a731f625 100644 --- a/examples/static-site-gen/platform/Html.roc +++ b/examples/static-site-gen/platform/Html.roc @@ -1,128 +1,128 @@ -interface Html - exposes [ - Node, - Attribute, - render, - renderWithoutDocType, - element, - unclosedElem, - text, - attribute, - html, - base, - head, - link, - meta, - style, - title, - body, - address, - article, - aside, - footer, - header, - h1, - h2, - h3, - h4, - h5, - h6, - main, - nav, - section, - blockquote, - dd, - div, - dl, - dt, - figcaption, - figure, - hr, - li, - menu, - ol, - p, - pre, - ul, - a, - abbr, - b, - bdi, - bdo, - br, - cite, - code, - data, - dfn, - em, - i, - kbd, - mark, - q, - rp, - rt, - ruby, - s, - samp, - small, - span, - strong, - sub, - sup, - time, - u, - var, - wbr, - area, - audio, - img, - map, - track, - video, - embed, - iframe, - object, - picture, - portal, - source, - svg, - math, - canvas, - noscript, - script, - del, - ins, - caption, - col, - colgroup, - table, - tbody, - td, - tfoot, - th, - thead, - tr, - button, - datalist, - fieldset, - form, - input, - label, - legend, - meter, - optgroup, - option, - output, - progress, - select, - textarea, - details, - dialog, - summary, - slot, - template, - ] - imports [Html.Attributes] +module [ + Node, + Attribute, + render, + renderWithoutDocType, + element, + unclosedElem, + text, + attribute, + html, + base, + head, + link, + meta, + style, + title, + body, + address, + article, + aside, + footer, + header, + h1, + h2, + h3, + h4, + h5, + h6, + main, + nav, + section, + blockquote, + dd, + div, + dl, + dt, + figcaption, + figure, + hr, + li, + menu, + ol, + p, + pre, + ul, + a, + abbr, + b, + bdi, + bdo, + br, + cite, + code, + data, + dfn, + em, + i, + kbd, + mark, + q, + rp, + rt, + ruby, + s, + samp, + small, + span, + strong, + sub, + sup, + time, + u, + var, + wbr, + area, + audio, + img, + map, + track, + video, + embed, + iframe, + object, + picture, + portal, + source, + svg, + math, + canvas, + noscript, + script, + del, + ins, + caption, + col, + colgroup, + table, + tbody, + td, + tfoot, + th, + thead, + tr, + button, + datalist, + fieldset, + form, + input, + label, + legend, + meter, + optgroup, + option, + output, + progress, + select, + textarea, + details, + dialog, + summary, + slot, + template, +] + +import Html.Attributes Node : [ Text Str, diff --git a/examples/static-site-gen/platform/Html/Attributes.roc b/examples/static-site-gen/platform/Html/Attributes.roc index 8e3e767269..6e9c5794cb 100644 --- a/examples/static-site-gen/platform/Html/Attributes.roc +++ b/examples/static-site-gen/platform/Html/Attributes.roc @@ -1,144 +1,142 @@ -interface Html.Attributes - exposes [ - Attribute, - attribute, - accept, - acceptCharset, - accesskey, - action, - align, - allow, - alt, - ariaLabel, - ariaLabelledBy, - ariaHidden, - async, - autocapitalize, - autocomplete, - autofocus, - autoplay, - background, - bgcolor, - border, - buffered, - capture, - challenge, - charset, - checked, - cite, - class, - code, - codebase, - color, - cols, - colspan, - content, - contenteditable, - contextmenu, - controls, - coords, - crossorigin, - csp, - data, - dataAttr, - datetime, - decoding, - default, - defer, - dir, - dirname, - disabled, - download, - draggable, - enctype, - enterkeyhint, - for, - form, - formaction, - formenctype, - formmethod, - formnovalidate, - formtarget, - headers, - height, - hidden, - high, - href, - hreflang, - httpEquiv, - icon, - id, - importance, - integrity, - intrinsicsize, - inputmode, - ismap, - itemprop, - keytype, - kind, - label, - lang, - language, - loading, - list, - loop, - low, - manifest, - max, - maxlength, - minlength, - media, - method, - min, - multiple, - muted, - name, - novalidate, - open, - optimum, - pattern, - ping, - placeholder, - poster, - preload, - radiogroup, - readonly, - referrerpolicy, - rel, - required, - reversed, - role, - rows, - rowspan, - sandbox, - scope, - scoped, - selected, - shape, - size, - sizes, - slot, - span, - spellcheck, - src, - srcdoc, - srclang, - srcset, - start, - step, - style, - summary, - tabindex, - target, - title, - translate, - type, - usemap, - value, - width, - wrap, - ] - imports [] +module [ + Attribute, + attribute, + accept, + acceptCharset, + accesskey, + action, + align, + allow, + alt, + ariaLabel, + ariaLabelledBy, + ariaHidden, + async, + autocapitalize, + autocomplete, + autofocus, + autoplay, + background, + bgcolor, + border, + buffered, + capture, + challenge, + charset, + checked, + cite, + class, + code, + codebase, + color, + cols, + colspan, + content, + contenteditable, + contextmenu, + controls, + coords, + crossorigin, + csp, + data, + dataAttr, + datetime, + decoding, + default, + defer, + dir, + dirname, + disabled, + download, + draggable, + enctype, + enterkeyhint, + for, + form, + formaction, + formenctype, + formmethod, + formnovalidate, + formtarget, + headers, + height, + hidden, + high, + href, + hreflang, + httpEquiv, + icon, + id, + importance, + integrity, + intrinsicsize, + inputmode, + ismap, + itemprop, + keytype, + kind, + label, + lang, + language, + loading, + list, + loop, + low, + manifest, + max, + maxlength, + minlength, + media, + method, + min, + multiple, + muted, + name, + novalidate, + open, + optimum, + pattern, + ping, + placeholder, + poster, + preload, + radiogroup, + readonly, + referrerpolicy, + rel, + required, + reversed, + role, + rows, + rowspan, + sandbox, + scope, + scoped, + selected, + shape, + size, + sizes, + slot, + span, + spellcheck, + src, + srcdoc, + srclang, + srcset, + start, + step, + style, + summary, + tabindex, + target, + title, + translate, + type, + usemap, + value, + width, + wrap, +] Attribute : [Attribute Str Str] diff --git a/examples/virtual-dom-wip/ExampleApp.roc b/examples/virtual-dom-wip/ExampleApp.roc index 66a81c613f..acfad07efa 100644 --- a/examples/virtual-dom-wip/ExampleApp.roc +++ b/examples/virtual-dom-wip/ExampleApp.roc @@ -1,8 +1,6 @@ -interface ExampleApp - exposes [exampleApp, State] - imports [ - pf.Html.{ App, Html, html, head, body, div, text, h1 }, - ] +module [exampleApp, State] + +import pf.Html exposing [App, Html, html, head, body, div, text, h1] State : { answer : U32, diff --git a/examples/virtual-dom-wip/platform/Action.roc b/examples/virtual-dom-wip/platform/Action.roc index 6a5e019c73..073c517f58 100644 --- a/examples/virtual-dom-wip/platform/Action.roc +++ b/examples/virtual-dom-wip/platform/Action.roc @@ -1,6 +1,4 @@ -interface Action - exposes [Action, none, update, map] - imports [] +module [Action, none, update, map] Action state : [None, Update state] diff --git a/examples/virtual-dom-wip/platform/Html.roc b/examples/virtual-dom-wip/platform/Html.roc index 4df219012c..f06da92d3b 100644 --- a/examples/virtual-dom-wip/platform/Html.roc +++ b/examples/virtual-dom-wip/platform/Html.roc @@ -1,129 +1,130 @@ -interface Html - exposes [ - App, - Html, - Attribute, - renderStatic, - renderStaticWithoutDocType, - translate, - translateStatic, - text, - none, - html, - base, - head, - link, - meta, - style, - title, - body, - address, - article, - aside, - footer, - header, - h1, - h2, - h3, - h4, - h5, - h6, - main, - nav, - section, - blockquote, - dd, - div, - dl, - dt, - figcaption, - figure, - hr, - li, - menu, - ol, - p, - pre, - ul, - a, - abbr, - b, - bdi, - bdo, - br, - cite, - code, - data, - dfn, - em, - i, - kbd, - mark, - q, - rp, - rt, - ruby, - s, - samp, - small, - span, - strong, - sub, - sup, - time, - u, - var, - wbr, - area, - audio, - img, - map, - track, - video, - embed, - iframe, - object, - picture, - portal, - source, - svg, - math, - canvas, - noscript, - script, - del, - ins, - caption, - col, - colgroup, - table, - tbody, - td, - tfoot, - th, - thead, - tr, - button, - datalist, - fieldset, - form, - input, - label, - legend, - meter, - optgroup, - option, - output, - progress, - select, - textarea, - details, - dialog, - summary, - slot, - template, - ] - imports [Html.Internal.Shared, Html.Internal.Server] +module [ + App, + Html, + Attribute, + renderStatic, + renderStaticWithoutDocType, + translate, + translateStatic, + text, + none, + html, + base, + head, + link, + meta, + style, + title, + body, + address, + article, + aside, + footer, + header, + h1, + h2, + h3, + h4, + h5, + h6, + main, + nav, + section, + blockquote, + dd, + div, + dl, + dt, + figcaption, + figure, + hr, + li, + menu, + ol, + p, + pre, + ul, + a, + abbr, + b, + bdi, + bdo, + br, + cite, + code, + data, + dfn, + em, + i, + kbd, + mark, + q, + rp, + rt, + ruby, + s, + samp, + small, + span, + strong, + sub, + sup, + time, + u, + var, + wbr, + area, + audio, + img, + map, + track, + video, + embed, + iframe, + object, + picture, + portal, + source, + svg, + math, + canvas, + noscript, + script, + del, + ins, + caption, + col, + colgroup, + table, + tbody, + td, + tfoot, + th, + thead, + tr, + button, + datalist, + fieldset, + form, + input, + label, + legend, + meter, + optgroup, + option, + output, + progress, + select, + textarea, + details, + dialog, + summary, + slot, + template, +] + +import Html.Internal.Shared +import Html.Internal.Server App state initData : Html.Internal.Shared.App state initData Html state : Html.Internal.Shared.Html state diff --git a/examples/virtual-dom-wip/platform/Html/Attributes.roc b/examples/virtual-dom-wip/platform/Html/Attributes.roc index 6d6f63d121..0d9cda74cb 100644 --- a/examples/virtual-dom-wip/platform/Html/Attributes.roc +++ b/examples/virtual-dom-wip/platform/Html/Attributes.roc @@ -1,140 +1,140 @@ -interface Html.Attributes - exposes [ - attribute, - accept, - acceptCharset, - accesskey, - action, - align, - allow, - alt, - async, - autocapitalize, - autocomplete, - autofocus, - autoplay, - background, - bgcolor, - border, - buffered, - capture, - challenge, - charset, - checked, - cite, - class, - code, - codebase, - color, - cols, - colspan, - content, - contenteditable, - contextmenu, - controls, - coords, - crossorigin, - csp, - data, - # dataAttr, TODO - datetime, - decoding, - default, - defer, - dir, - dirname, - disabled, - download, - draggable, - enctype, - enterkeyhint, - for, - form, - formaction, - formenctype, - formmethod, - formnovalidate, - formtarget, - headers, - height, - hidden, - high, - href, - hreflang, - httpEquiv, - icon, - id, - importance, - integrity, - intrinsicsize, - inputmode, - ismap, - itemprop, - keytype, - kind, - label, - lang, - language, - loading, - list, - loop, - low, - manifest, - max, - maxlength, - minlength, - media, - method, - min, - multiple, - muted, - name, - novalidate, - open, - optimum, - pattern, - ping, - placeholder, - poster, - preload, - radiogroup, - readonly, - referrerpolicy, - rel, - required, - reversed, - role, - rows, - rowspan, - sandbox, - scope, - scoped, - selected, - shape, - size, - sizes, - slot, - span, - spellcheck, - src, - srcdoc, - srclang, - srcset, - start, - step, - style, - summary, - tabindex, - target, - title, - translate, - type, - usemap, - value, - width, - wrap, - ] - imports [Html.Internal.Shared.{ Attribute }] +module [ + attribute, + accept, + acceptCharset, + accesskey, + action, + align, + allow, + alt, + async, + autocapitalize, + autocomplete, + autofocus, + autoplay, + background, + bgcolor, + border, + buffered, + capture, + challenge, + charset, + checked, + cite, + class, + code, + codebase, + color, + cols, + colspan, + content, + contenteditable, + contextmenu, + controls, + coords, + crossorigin, + csp, + data, + # dataAttr, TODO + datetime, + decoding, + default, + defer, + dir, + dirname, + disabled, + download, + draggable, + enctype, + enterkeyhint, + for, + form, + formaction, + formenctype, + formmethod, + formnovalidate, + formtarget, + headers, + height, + hidden, + high, + href, + hreflang, + httpEquiv, + icon, + id, + importance, + integrity, + intrinsicsize, + inputmode, + ismap, + itemprop, + keytype, + kind, + label, + lang, + language, + loading, + list, + loop, + low, + manifest, + max, + maxlength, + minlength, + media, + method, + min, + multiple, + muted, + name, + novalidate, + open, + optimum, + pattern, + ping, + placeholder, + poster, + preload, + radiogroup, + readonly, + referrerpolicy, + rel, + required, + reversed, + role, + rows, + rowspan, + sandbox, + scope, + scoped, + selected, + shape, + size, + sizes, + slot, + span, + spellcheck, + src, + srcdoc, + srclang, + srcset, + start, + step, + style, + summary, + tabindex, + target, + title, + translate, + type, + usemap, + value, + width, + wrap, +] + +import Html.Internal.Shared exposing [Attribute] attribute : Str -> (Str -> Attribute state) attribute = \attrType -> diff --git a/examples/virtual-dom-wip/platform/Html/Event.roc b/examples/virtual-dom-wip/platform/Html/Event.roc index 95a7a8056c..513e049934 100644 --- a/examples/virtual-dom-wip/platform/Html/Event.roc +++ b/examples/virtual-dom-wip/platform/Html/Event.roc @@ -1,27 +1,25 @@ -interface Html.Event - exposes [ - Handler, - CyclicStructureAccessor, - on, - custom, - onClick, - onDoubleClick, - onMouseDown, - onMouseUp, - onMouseEnter, - onMouseLeave, - onMouseOver, - onMouseOut, - onCheck, - onBlur, - onFocus, - onInput, - onSubmit, - ] - imports [ - Action.{ Action }, - Html.Internal.Shared.{ Attribute }, - ] +module [ + Handler, + CyclicStructureAccessor, + on, + custom, + onClick, + onDoubleClick, + onMouseDown, + onMouseUp, + onMouseEnter, + onMouseLeave, + onMouseOver, + onMouseOut, + onCheck, + onBlur, + onFocus, + onInput, + onSubmit, +] + +import Action exposing [Action] +import Html.Internal.Shared exposing [Attribute] Handler state : Html.Internal.Shared.Handler state CyclicStructureAccessor : Html.Internal.Shared.CyclicStructureAccessor diff --git a/examples/virtual-dom-wip/platform/Html/Internal/Client.roc b/examples/virtual-dom-wip/platform/Html/Internal/Client.roc index edc67905f4..51e8759fb1 100644 --- a/examples/virtual-dom-wip/platform/Html/Internal/Client.roc +++ b/examples/virtual-dom-wip/platform/Html/Internal/Client.roc @@ -1,29 +1,27 @@ -interface Html.Internal.Client - exposes [ - PlatformState, - initClientApp, - dispatchEvent, - ] - imports [ - Effect.{ - Effect, - NodeId, - HandlerId, - TagName, - AttrType, - EventType, - }, - Html.Internal.Shared.{ - App, - Html, - Attribute, - CyclicStructureAccessor, - Handler, - translateStatic, - }, - TotallyNotJson, - Action, - ] +module [ + PlatformState, + initClientApp, + dispatchEvent, +] + +import Effect exposing [ + Effect, + NodeId, + HandlerId, + TagName, + AttrType, + EventType, +] +import Html.Internal.Shared exposing [ + App, + Html, + Attribute, + CyclicStructureAccessor, + Handler, + translateStatic, +] +import TotallyNotJson +import Action PlatformState state initData : { app : App state initData, diff --git a/examples/virtual-dom-wip/platform/Html/Internal/Server.roc b/examples/virtual-dom-wip/platform/Html/Internal/Server.roc index e883e399c7..01d5291795 100644 --- a/examples/virtual-dom-wip/platform/Html/Internal/Server.roc +++ b/examples/virtual-dom-wip/platform/Html/Internal/Server.roc @@ -1,12 +1,10 @@ -interface Html.Internal.Server - exposes [ - appendRenderedStatic, - initServerApp, - ] - imports [ - Html.Internal.Shared.{ Html, Attribute, App, translateStatic, text, element }, - TotallyNotJson, - ] +module [ + appendRenderedStatic, + initServerApp, +] + +import Html.Internal.Shared exposing [Html, Attribute, App, translateStatic, text, element] +import TotallyNotJson # ------------------------------- # STATIC HTML diff --git a/examples/virtual-dom-wip/platform/Html/Internal/Shared.roc b/examples/virtual-dom-wip/platform/Html/Internal/Shared.roc index 68ebe2e720..a7f118f82f 100644 --- a/examples/virtual-dom-wip/platform/Html/Internal/Shared.roc +++ b/examples/virtual-dom-wip/platform/Html/Internal/Shared.roc @@ -1,21 +1,19 @@ -interface Html.Internal.Shared - exposes [ - App, - Html, - Attribute, - CyclicStructureAccessor, - Handler, - Size, - element, - text, - none, - translate, - translateStatic, - nodeSize, - ] - imports [ - Action.{ Action }, - ] +module [ + App, + Html, + Attribute, + CyclicStructureAccessor, + Handler, + Size, + element, + text, + none, + translate, + translateStatic, + nodeSize, +] + +import Action exposing [Action] App state initData : { init : DecodingResult initData -> state,