Skip to content

Commit

Permalink
swift: Propagate all protos with synthesized impls
Browse files Browse the repository at this point in the history
  • Loading branch information
tadfisher committed Jan 30, 2024
1 parent 10b09dd commit 87c52ed
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 16 deletions.
2 changes: 1 addition & 1 deletion .golden/swiftGenericNewtypeSpec/golden
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
struct LTree<A: Codable>: CaseIterable, Hashable, Codable {
struct LTree<A: Hashable & Codable>: Hashable, Codable {
typealias LTreeTag = Tagged<LTree, [A]>
let value: LTreeTag
}
2 changes: 1 addition & 1 deletion .golden/swiftGenericStructSpec/golden
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
struct Tree<A: Codable>: Codable {
struct Tree<A: Hashable & Codable>: Hashable, Codable {
var rootLabel: A
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: Codable, B: Codable>: CaseIterable, Hashable, Codable {
struct Data<A: Hashable & Codable, B: Hashable & 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: Codable>: CaseIterable, Hashable, Codable {
struct Data<A: Hashable & Codable>: CaseIterable, Hashable, Codable {
var field0: A
}
40 changes: 30 additions & 10 deletions src/Moat/Pretty/Swift.hs
Original file line number Diff line number Diff line change
Expand Up @@ -109,17 +109,17 @@ prettyRawValueAndProtocols Nothing ps = ": " ++ prettyProtocols ps
prettyRawValueAndProtocols (Just ty) [] = ": " ++ prettyMoatType ty
prettyRawValueAndProtocols (Just ty) ps = ": " ++ prettyMoatType ty ++ ", " ++ prettyProtocols ps

prettyProtocol :: Protocol -> String
prettyProtocol = \case
Hashable -> "Hashable"
Codable -> "Codable"
Equatable -> "Equatable"
OtherProtocol s -> s

prettyProtocols :: [Protocol] -> String
prettyProtocols = \case
[] -> ""
ps -> intercalate ", " (prettyProtocol <$> ps)
where
prettyProtocol :: Protocol -> String
prettyProtocol = \case
Hashable -> "Hashable"
Codable -> "Codable"
Equatable -> "Equatable"
OtherProtocol s -> s

-- TODO: Need a plan to avoid @error@ in these pure functions
{-# ANN prettyTags "HLint: ignore" #-}
Expand Down Expand Up @@ -269,7 +269,27 @@ onLast :: (a -> a) -> [a] -> [a]
onLast _ [] = []
onLast f (x : xs) = x : map f xs

-- | Copy protocols from the parent type to upper bounds of generic type
-- parameters.
--
-- This is needed for protocols with compiler-synthesized implementations
-- (similar to 'deriving stock'), of which there are currently three:
--
-- - 'Equatable'
-- - 'Hashable'
-- - 'Codable'
--
-- See the [Swift documentation](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/protocols#Adopting-a-Protocol-Using-a-Synthesized-Implementation).
addTyVarBounds :: [String] -> [Protocol] -> [String]
addTyVarBounds tyVars protos
| Codable `elem` protos = map (++ ": Codable") tyVars
| otherwise = tyVars
addTyVarBounds tyVars protos =
let isSynthesized :: Protocol -> Bool
isSynthesized = \case
Hashable -> True
Codable -> True
Equatable -> True
OtherProtocol _ -> False
synthesizedProtos = filter isSynthesized protos
bounds = ": " ++ intercalate " & " (map prettyProtocol synthesizedProtos)
in case synthesizedProtos of
[] -> tyVars
_ -> map (++ bounds) tyVars
2 changes: 1 addition & 1 deletion test/GenericNewtypeSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ mobileGenWith
( defaultOptions
{ dataAnnotations = [Parcelize, Serializable]
, dataInterfaces = [Parcelable]
, dataProtocols = [OtherProtocol "CaseIterable", Hashable, Codable]
, dataProtocols = [Hashable, Codable]
, dataRawValue = Just Str
, generateDocComments = False
}
Expand Down
2 changes: 1 addition & 1 deletion test/GenericStructSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import Prelude
mobileGenWith
( defaultOptions
{ dataInterfaces = [Parcelable]
, dataProtocols = [Codable]
, dataProtocols = [Hashable, Codable]
, generateDocComments = False
}
)
Expand Down

0 comments on commit 87c52ed

Please sign in to comment.