From 940eab5aa2adda0b748a2d9d8fe42a7fd783da6b Mon Sep 17 00:00:00 2001 From: Tad Fisher Date: Thu, 1 Feb 2024 10:25:52 -0800 Subject: [PATCH 1/2] Add tests for generic sum-of-product --- .../golden | 11 ++++++ .../golden | 4 ++ moat.cabal | 1 + test/SumOfProductWithTypeParameterSpec.hs | 38 +++++++++++++++++++ 4 files changed, 54 insertions(+) create mode 100644 .golden/kotlinSumOfProductWithTypeParameterSpec/golden create mode 100644 .golden/swiftSumOfProductWithTypeParameterSpec/golden create mode 100644 test/SumOfProductWithTypeParameterSpec.hs diff --git a/.golden/kotlinSumOfProductWithTypeParameterSpec/golden b/.golden/kotlinSumOfProductWithTypeParameterSpec/golden new file mode 100644 index 0000000..fd0ba02 --- /dev/null +++ b/.golden/kotlinSumOfProductWithTypeParameterSpec/golden @@ -0,0 +1,11 @@ +@JsonClassDiscriminator("direction") +@Serializable +sealed class CursorInput { + @Serializable + @SerialName("nextPage") + data class NextPage(val key: A?) : CursorInput() + + @Serializable + @SerialName("previousPage") + data class PreviousPage(val key: A) : CursorInput() +} \ No newline at end of file diff --git a/.golden/swiftSumOfProductWithTypeParameterSpec/golden b/.golden/swiftSumOfProductWithTypeParameterSpec/golden new file mode 100644 index 0000000..31a552c --- /dev/null +++ b/.golden/swiftSumOfProductWithTypeParameterSpec/golden @@ -0,0 +1,4 @@ +enum CursorInput: CaseIterable, Hashable, Codable { + case nextPage(A?) + case previousPage(A) +} \ No newline at end of file diff --git a/moat.cabal b/moat.cabal index 95ef219..1e064a8 100644 --- a/moat.cabal +++ b/moat.cabal @@ -94,6 +94,7 @@ test-suite spec SumOfProductWithTaggedObjectAndNonConcreteCasesSpec SumOfProductWithTaggedObjectAndSingleNullarySpec SumOfProductWithTaggedObjectStyleSpec + SumOfProductWithTypeParameterSpec TypeVariableSpec Moat Moat.Class diff --git a/test/SumOfProductWithTypeParameterSpec.hs b/test/SumOfProductWithTypeParameterSpec.hs new file mode 100644 index 0000000..18b19ae --- /dev/null +++ b/test/SumOfProductWithTypeParameterSpec.hs @@ -0,0 +1,38 @@ +module SumOfProductWithTypeParameterSpec where + +import Common +import Data.List (stripPrefix) +import Data.Maybe +import Moat +import Test.Hspec +import Test.Hspec.Golden +import Prelude hiding (Enum) + +data CursorInput a + = CursorInputNextPage (Maybe a) + | CursorInputPreviousPage a + +mobileGenWith + ( defaultOptions + { constructorModifier = \body -> fromMaybe body (stripPrefix "CursorInput" body) + , dataAnnotations = [Serializable, SerialName] + , dataProtocols = [OtherProtocol "CaseIterable", Hashable, Codable] + , sumOfProductEncodingOptions = + SumOfProductEncodingOptions + { encodingStyle = TaggedObjectStyle + , sumAnnotations = [RawAnnotation "JsonClassDiscriminator(\"direction\")"] + , contentsFieldName = "key" + , tagFieldName = "direction" + } + } + ) + ''CursorInput + +spec :: Spec +spec = + describe "stays golden" $ do + let moduleName = "SumOfProductWithTypeParameterSpec" + it "kotlin" $ + defaultGolden ("kotlin" <> moduleName) (showKotlin @(CursorInput _)) + it "swift" $ + defaultGolden ("swift" <> moduleName) (showSwift @(CursorInput _)) From d2a88d76c77f4618a51bfe1e6efc0dcdd3f943b9 Mon Sep 17 00:00:00 2001 From: Tad Fisher Date: Thu, 1 Feb 2024 11:03:52 -0800 Subject: [PATCH 2/2] kotlin: add parent type parameters to sum-of-product cases --- .../golden | 4 ++-- src/Moat/Pretty/Kotlin.hs | 20 +++++++++++++------ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/.golden/kotlinSumOfProductWithTypeParameterSpec/golden b/.golden/kotlinSumOfProductWithTypeParameterSpec/golden index fd0ba02..c041f65 100644 --- a/.golden/kotlinSumOfProductWithTypeParameterSpec/golden +++ b/.golden/kotlinSumOfProductWithTypeParameterSpec/golden @@ -3,9 +3,9 @@ sealed class CursorInput { @Serializable @SerialName("nextPage") - data class NextPage(val key: A?) : CursorInput() + data class NextPage(val key: A?) : CursorInput() @Serializable @SerialName("previousPage") - data class PreviousPage(val key: A) : CursorInput() + data class PreviousPage(val key: A) : CursorInput() } \ No newline at end of file diff --git a/src/Moat/Pretty/Kotlin.hs b/src/Moat/Pretty/Kotlin.hs index 85e6a3a..f889491 100644 --- a/src/Moat/Pretty/Kotlin.hs +++ b/src/Moat/Pretty/Kotlin.hs @@ -224,12 +224,14 @@ prettyApp t1 t2 = -- error is restricted prettyTaggedObject :: String -> + [String] -> [Annotation] -> + [Interface] -> [EnumCase] -> String -> SumOfProductEncodingOptions -> String -prettyTaggedObject parentName anns cases indents SumOfProductEncodingOptions {..} = +prettyTaggedObject parentName tyVars anns ifaces cases indents SumOfProductEncodingOptions {..} = intercalate "\n\n" ( cases <&> \case @@ -238,22 +240,22 @@ prettyTaggedObject parentName anns cases indents SumOfProductEncodingOptions {.. ++ prettyAnnotations (Just caseNm) indents anns ++ indents ++ "data class " - ++ toUpperFirst caseNm + ++ caseTypeHeader caseNm ++ "(val " ++ contentsFieldName ++ ": " ++ prettyMoatType caseTy ++ ") : " - ++ parentName + ++ parentTypeHeader ++ "()" EnumCase caseNm caseDoc [] -> prettyTypeDoc indents caseDoc [] ++ prettyAnnotations (Just caseNm) indents anns ++ indents ++ "data object " - ++ toUpperFirst caseNm + ++ caseTypeHeader caseNm ++ " : " - ++ parentName + ++ parentTypeHeader ++ "()" EnumCase caseNm _ _ -> error $ @@ -261,6 +263,12 @@ prettyTaggedObject parentName anns cases indents SumOfProductEncodingOptions {.. <> caseNm <> " can have zero or one concrete type constructor!" ) + where + caseTypeHeader :: String -> String + caseTypeHeader name = prettyMoatTypeHeader (toUpperFirst name) (addTyVarBounds tyVars ifaces) + + parentTypeHeader :: String + parentTypeHeader = prettyMoatTypeHeader parentName tyVars prettyEnum :: () => @@ -325,7 +333,7 @@ prettyEnum doc anns ifaces name tyVars cases sop@SumOfProductEncodingOptions {.. ++ classTyp ++ prettyInterfaces ifaces ++ " {\n" - ++ prettyTaggedObject name anns cases indents sop + ++ prettyTaggedObject name tyVars anns ifaces cases indents sop ++ "\n}" where isCEnum :: [EnumCase] -> Bool