Skip to content

Commit

Permalink
Propagate 'Codable' bounds through MoatData tyvars
Browse files Browse the repository at this point in the history
  • Loading branch information
tadfisher committed Jan 29, 2024
1 parent 16dfdc9 commit a7cb12f
Show file tree
Hide file tree
Showing 10 changed files with 96 additions and 6 deletions.
3 changes: 3 additions & 0 deletions .golden/kotlinGenericNewtypeSpec/golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@Parcelize
@Serializable
value class LTree<A : Parcelable>(val value: List<A>) : Parcelable
10 changes: 10 additions & 0 deletions .golden/kotlinGenericStructSpec/golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* Non-empty, possibly infinite, multi-way trees; also known as *rose trees*.
*
* @param rootLabel label value
* @param subForest zero or more child trees
*/
data class Tree<A : Parcelable>(
val rootLabel: A,
val subForest: List<Tree<A>>,
) : Parcelable
4 changes: 4 additions & 0 deletions .golden/swiftGenericNewtypeSpec/golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
struct LTree<A: Codable>: CaseIterable, Hashable, Codable {
typealias LTreeTag = Tagged<LTree, [A]>
let value: LTreeTag
}
7 changes: 7 additions & 0 deletions .golden/swiftGenericStructSpec/golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/// Non-empty, possibly infinite, multi-way trees; also known as *rose trees*.
struct Tree<A: Codable>: Codable {
/// label value
var rootLabel: A
/// zero or more child trees
var subForest: [Tree<A>]
}
2 changes: 1 addition & 1 deletion .golden/swiftMultipleTypeVariableSpec/golden
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
struct Data<A, B>: CaseIterable, Hashable, Codable {
struct Data<A: Codable, B: Codable>: CaseIterable, Hashable, Codable {
var field0: A
var field1: B
}
2 changes: 1 addition & 1 deletion .golden/swiftTypeVariableSpec/golden
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
struct Data<A>: CaseIterable, Hashable, Codable {
struct Data<A: Codable>: CaseIterable, Hashable, Codable {
var field0: A
}
2 changes: 2 additions & 0 deletions moat.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ test-suite spec
DuplicateRecordFieldSpec
EnumValueClassDocSpec
EnumValueClassSpec
GenericNewtypeSpec
GenericStructSpec
MultipleTypeVariableSpec
StrictEnumsSpec
StrictFieldsSpec
Expand Down
13 changes: 9 additions & 4 deletions src/Moat/Pretty/Swift.hs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ prettySwiftDataWith indent = \case
MoatEnum {..} ->
prettyTypeDoc "" enumDoc []
++ "enum "
++ prettyMoatTypeHeader enumName enumTyVars
++ prettyMoatTypeHeader enumName (addTyVarBounds enumTyVars enumProtocols)
++ prettyRawValueAndProtocols enumRawValue enumProtocols
++ " {"
++ newlineNonEmpty enumCases
Expand All @@ -41,7 +41,7 @@ prettySwiftDataWith indent = \case
MoatStruct {..} ->
prettyTypeDoc "" structDoc []
++ "struct "
++ prettyMoatTypeHeader structName structTyVars
++ prettyMoatTypeHeader structName (addTyVarBounds structTyVars structProtocols)
++ prettyRawValueAndProtocols Nothing structProtocols
++ " {"
++ newlineNonEmpty structFields
Expand All @@ -54,13 +54,13 @@ prettySwiftDataWith indent = \case
MoatAlias {..} ->
prettyTypeDoc "" aliasDoc []
++ "typealias "
++ prettyMoatTypeHeader aliasName aliasTyVars
++ prettyMoatTypeHeader aliasName (addTyVarBounds aliasTyVars [])
++ " = "
++ prettyMoatType aliasTyp
MoatNewtype {..} ->
prettyTypeDoc "" newtypeDoc []
++ "struct "
++ prettyMoatTypeHeader newtypeName newtypeTyVars
++ prettyMoatTypeHeader newtypeName (addTyVarBounds newtypeTyVars newtypeProtocols)
++ prettyRawValueAndProtocols Nothing newtypeProtocols
++ " {\n"
++ indents
Expand Down Expand Up @@ -268,3 +268,8 @@ prettyPrivateTypes indents = go
onLast :: (a -> a) -> [a] -> [a]
onLast _ [] = []
onLast f (x : xs) = x : map f xs

addTyVarBounds :: [String] -> [Protocol] -> [String]
addTyVarBounds tyVars protos
| Codable `elem` protos = map (++ ": Codable") tyVars
| otherwise = tyVars
32 changes: 32 additions & 0 deletions test/GenericNewtypeSpec.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{-# LANGUAGE DerivingStrategies #-}

module GenericNewtypeSpec where

import Common
import Data.List.NonEmpty (NonEmpty)
import Moat
import Test.Hspec
import Test.Hspec.Golden
import Prelude

newtype LTree a = LTree (NonEmpty a)
deriving stock (Show, Eq)

mobileGenWith
( defaultOptions
{ dataAnnotations = [Parcelize, Serializable]
, dataInterfaces = [Parcelable]
, dataProtocols = [OtherProtocol "CaseIterable", Hashable, Codable]
, dataRawValue = Just Str
}
)
''LTree

spec :: Spec
spec =
describe "stays golden" $ do
let moduleName = "GenericNewtypeSpec"
it "swift" $
defaultGolden ("swift" <> moduleName) (showSwift @(LTree _))
it "kotlin" $
defaultGolden ("kotlin" <> moduleName) (showKotlin @(LTree _))
27 changes: 27 additions & 0 deletions test/GenericStructSpec.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{-# OPTIONS_GHC -Wno-orphans #-}

module GenericStructSpec where

import Common
import Data.Tree (Tree)
import Moat
import Test.Hspec
import Test.Hspec.Golden
import Prelude

mobileGenWith
( defaultOptions
{ dataInterfaces = [Parcelable]
, dataProtocols = [Codable]
}
)
''Tree

spec :: Spec
spec =
describe "stays golden" $ do
let moduleName = "GenericStructSpec"
it "swift" $
defaultGolden ("swift" <> moduleName) (showSwift @(Tree _))
it "kotlin" $
defaultGolden ("kotlin" <> moduleName) (showKotlin @(Tree _))

0 comments on commit a7cb12f

Please sign in to comment.