Skip to content

Commit

Permalink
Merge pull request #92 from MercuryTechnologies/kb/swift-inits
Browse files Browse the repository at this point in the history
Generate public initializers for Swift
  • Loading branch information
kylebshr authored Nov 21, 2024
2 parents 34aaacd + c2e7a2f commit 2eda1d2
Show file tree
Hide file tree
Showing 24 changed files with 132 additions and 8 deletions.
4 changes: 2 additions & 2 deletions .golden/kotlinDeprecatedFieldSpec/golden
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
data class Data(
val field0: Int,
// Deprecated since build 500
// val field1: Int? = null,
// Deprecated since build 500
// val field1: Int? = null,
)
4 changes: 4 additions & 0 deletions .golden/swiftAdvancedNewtypeWithEnumFieldSpec/golden
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
public struct Newtype {
public var newtypeField: Enum

public init(newtypeField: Enum) {
self.newtypeField = newtypeField
}
}
5 changes: 5 additions & 0 deletions .golden/swiftAdvancedRecordSpec/golden
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
public struct Data: CaseIterable, Hashable, Codable {
public var field0: Int
public var field1: Int?

public init(field0: Int, field1: Int? = nil) {
self.field0 = field0
self.field1 = field1
}
}
5 changes: 5 additions & 0 deletions .golden/swiftBasicDocSpec/golden
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,9 @@ public struct Data {
public var first: Int
/// Second field, it's maybe an Int
public var second: Int?

public init(first: Int, second: Int? = nil) {
self.first = first
self.second = second
}
}
4 changes: 4 additions & 0 deletions .golden/swiftBasicNewtypeWithConcreteFieldSpec/golden
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
public struct Newtype {
public var newtypeField: String

public init(newtypeField: String) {
self.newtypeField = newtypeField
}
}
4 changes: 4 additions & 0 deletions .golden/swiftBasicNewtypeWithEitherFieldSpec/golden
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
public struct Newtype {
public var newtypeField: Result<Int, String>

public init(newtypeField: Result<Int, String>) {
self.newtypeField = newtypeField
}
}
5 changes: 5 additions & 0 deletions .golden/swiftBasicRecordSpec/golden
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
public struct Data {
public var field0: Int
public var field1: Int?

public init(field0: Int, field1: Int? = nil) {
self.field0 = field0
self.field1 = field1
}
}
4 changes: 4 additions & 0 deletions .golden/swiftDeprecatedFieldSpec/golden
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,8 @@ public struct Data {
public var field0: Int
// Deprecated since build 500
// public var field1: Int?

public init(field0: Int) {
self.field0 = field0
}
}
5 changes: 5 additions & 0 deletions .golden/swiftGenericStructSpec/golden
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
public struct Tree<A: Hashable & Codable>: Hashable, Codable {
public var rootLabel: A
public var subForest: [Tree<A>]

public init(rootLabel: A, subForest: [Tree<A>]) {
self.rootLabel = rootLabel
self.subForest = subForest
}
}
5 changes: 5 additions & 0 deletions .golden/swiftMultipleTypeVariableSpec/golden
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
public struct Data<A: Hashable & Codable, B: Hashable & Codable>: CaseIterable, Hashable, Codable {
public var field0: A
public var field1: B

public init(field0: A, field1: B) {
self.field0 = field0
self.field1 = field1
}
}
5 changes: 5 additions & 0 deletions .golden/swiftRecord0DuplicateRecordFieldSpec/golden
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,9 @@ public struct Data0 {
public var field0: Int
/// not a duplicate
public var field1: Int?

public init(field0: Int, field1: Int? = nil) {
self.field0 = field0
self.field1 = field1
}
}
5 changes: 5 additions & 0 deletions .golden/swiftRecord0SumOfProductDocSpec/golden
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,9 @@ public struct Record0: CaseIterable, Hashable, Codable {
public var record0Field0: Int
/// The first field of record 0
public var record0Field1: Int

public init(record0Field0: Int, record0Field1: Int) {
self.record0Field0 = record0Field0
self.record0Field1 = record0Field1
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
public struct Record0: Codable {
public var record0Field0: Int
public var record0Field1: Int

public init(record0Field0: Int, record0Field1: Int) {
self.record0Field0 = record0Field0
self.record0Field1 = record0Field1
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
public struct Record0: Codable {
public var record0Field0: Int
public var record0Field1: Int

public init(record0Field0: Int, record0Field1: Int) {
self.record0Field0 = record0Field0
self.record0Field1 = record0Field1
}
}
5 changes: 5 additions & 0 deletions .golden/swiftRecord1DuplicateRecordFieldSpec/golden
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,9 @@ public struct Data1 {
public var field0: String
/// not a duplicate
public var field2: String?

public init(field0: String, field2: String? = nil) {
self.field0 = field0
self.field2 = field2
}
}
5 changes: 5 additions & 0 deletions .golden/swiftRecord1SumOfProductDocSpec/golden
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,9 @@ public struct Record1: CaseIterable, Hashable, Codable {
public var record1Field0: Int
/// The first field of record 1
public var record1Field1: Int

public init(record1Field0: Int, record1Field1: Int) {
self.record1Field0 = record1Field0
self.record1Field1 = record1Field1
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
public struct Record1: Codable {
public var record1Field0: Int
public var record1Field1: Int

public init(record1Field0: Int, record1Field1: Int) {
self.record1Field0 = record1Field0
self.record1Field1 = record1Field1
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
public struct Record1: Codable {
public var record1Field0: Int
public var record1Field1: Int

public init(record1Field0: Int, record1Field1: Int) {
self.record1Field0 = record1Field0
self.record1Field1 = record1Field1
}
}
4 changes: 4 additions & 0 deletions .golden/swiftStrictFieldsCheck-RecordA/golden
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
public struct RecordA {
public var fieldA: String

public init(fieldA: String) {
self.fieldA = fieldA
}
}
4 changes: 4 additions & 0 deletions .golden/swiftStrictFieldsCheck-RecordB/golden
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
public struct RecordB {
public var c: String

public init(c: String) {
self.c = c
}
}
4 changes: 4 additions & 0 deletions .golden/swiftTypeVariableSpec/golden
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
public struct Data<A: Hashable & Codable>: CaseIterable, Hashable, Codable {
public var field0: A

public init(field0: A) {
self.field0 = field0
}
}
11 changes: 6 additions & 5 deletions src/Moat/Pretty/Kotlin.hs
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,7 @@ prettyStructFields indents fields deprecatedFields = go fields
where
deprecatedFieldsMap = Map.fromList deprecatedFields
prettyField (Field fieldName ty _) =
indents
++ "val "
"val "
++ fieldName
++ ": "
++ prettyMoatType ty
Expand All @@ -84,11 +83,13 @@ prettyStructFields indents fields deprecatedFields = go fields
go (field@(Field fieldName _ _) : fs) =
case Map.lookup fieldName deprecatedFieldsMap of
Just mComment ->
maybe "" (\comment -> "// " ++ comment ++ "\n") mComment
++ "//"
indents
++ maybe "" (\comment -> "// " ++ comment ++ "\n") mComment
++ indents
++ "// "
++ prettyField field
++ go fs
Nothing -> prettyField field ++ go fs
Nothing -> indents ++ prettyField field ++ go fs

prettyEnumCases :: String -> [EnumCase] -> String
prettyEnumCases indents = go
Expand Down
30 changes: 30 additions & 0 deletions src/Moat/Pretty/Swift.hs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ prettySwiftDataWith indent = \case
++ " {"
++ newlineNonEmpty structFields
++ prettyStructFields indents structFields structDeprecatedFields
++ prettyStructInitializer indents structFields structDeprecatedFields
++ newlineNonEmpty structPrivateTypes
++ prettyPrivateTypes indents structPrivateTypes
++ prettyTags indents structTags
Expand Down Expand Up @@ -287,6 +288,35 @@ prettyStructFields indents fields deprecatedFields = go fields
++ prettyField field
++ go fs

prettyStructInitializer :: String -> [Field] -> [(String, Maybe String)] -> String
prettyStructInitializer indents fields deprecatedFields =
case activeFields of
[] -> "" -- No initializer needed if there are no active fields
_ ->
"\n"
++ indents
++ "public init("
++ intercalate ", " (map prettyParam activeFields)
++ ") {\n"
++ concatMap (prettyAssignment indents) activeFields
++ indents
++ "}\n"
where
deprecatedFieldNames = map fst deprecatedFields
activeFields = filter (\(Field name _ _) -> name `notElem` deprecatedFieldNames) fields

isOptional :: MoatType -> Bool
isOptional (Optional _) = True
isOptional _ = False

prettyParam :: Field -> String
prettyParam (Field fieldName fieldType _) =
fieldName ++ ": " ++ prettyMoatType fieldType ++ (if isOptional fieldType then " = nil" else "")

prettyAssignment :: String -> Field -> String
prettyAssignment indentStr (Field fieldName _ _) =
indentStr ++ " self." ++ fieldName ++ " = " ++ fieldName ++ "\n"

prettyNewtypeField :: String -> Field -> String -> String
prettyNewtypeField indents (Field alias fieldType _) fieldName =
indents
Expand Down
2 changes: 1 addition & 1 deletion test/DeprecatedFieldSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ mobileGenWith

spec :: Spec
spec =
fdescribe "stays golden" $ do
describe "stays golden" $ do
let moduleName = "DeprecatedFieldSpec"
it "swift" $
defaultGolden ("swift" <> moduleName) (showSwift @Data)
Expand Down

0 comments on commit 2eda1d2

Please sign in to comment.