Slide 1

Slide 1 text

CODE GENERATORS IN SWIFT BY PAUL TAYKALO, STANFY 1 — Code Generators in Swift, #se2016

Slide 2

Slide 2 text

CODE GENERATION 2 — Code Generators in Swift, #se2016

Slide 3

Slide 3 text

CODE GENERATION OR AUTOMATIC PROGRAMMING In computer science, the term automatic programming identifies a type of computer programming in which some mechanism generates a computer program to allow human programmers to write the code at a higher abstraction level — Wikipedia 3 — Code Generators in Swift, #se2016

Slide 4

Slide 4 text

SO DIFFERENT CODE GENERATORS > Snippets > GUI Tools > Wizards 4 — Code Generators in Swift, #se2016

Slide 5

Slide 5 text

GENERATORS IN GENERAL 5 — Code Generators in Swift, #se2016

Slide 6

Slide 6 text

OUR MAIN INTEREST TODAY 6 — Code Generators in Swift, #se2016

Slide 7

Slide 7 text

BUT BEFORE THAT WHY DO WE NEED CODE GENERATORS IN SWIFT? 7 — Code Generators in Swift, #se2016

Slide 8

Slide 8 text

Mostly this is because that we can't get access to types or objects structure in runtime There are languages, where still have Runtime, but still want to generate code WHY DO WE NEED CODE GENERATORS IN SWIFT? > No Runtime > Static Typing > No simple way to get types in runtime* > Hard to get metainformation at runtime* 8 — Code Generators in Swift, #se2016

Slide 9

Slide 9 text

What are our main goals when whe use Code Generators? OUR GOALS 9 — Code Generators in Swift, #se2016

Slide 10

Slide 10 text

WRITE LESS CODE 10 — Code Generators in Swift, #se2016

Slide 11

Slide 11 text

AUTOMATE REPETITIVE OPERATIONS 11 — Code Generators in Swift, #se2016

Slide 12

Slide 12 text

SAVE TIME MAKE EVERYONE HAPPY 12 — Code Generators in Swift, #se2016

Slide 13

Slide 13 text

Human error rate Update is just regeneration Good copy-pasting machine ERROR SCALABILITY 13 — Code Generators in Swift, #se2016

Slide 14

Slide 14 text

WHEN SHOULD WE WRITE ONE? 14 — Code Generators in Swift, #se2016

Slide 15

Slide 15 text

WHEN SHOULD WE WRITE ONE? ✅ Structure is well defined 15 — Code Generators in Swift, #se2016

Slide 16

Slide 16 text

WHEN SHOULD WE WRITE ONE? ✅ Structure is well defined ✅ Number of special cases is low ✅ Uniform structure 16 — Code Generators in Swift, #se2016

Slide 17

Slide 17 text

WHEN SHOULD WE WRITE ONE? ✅ Structure is well defined ✅ Number of special cases is low ✅ Uniform structure ✅ One Layer of Abstraction 17 — Code Generators in Swift, #se2016

Slide 18

Slide 18 text

WHEN SHOULD WE WRITE ONE? ✅ Structure is well defined ✅ Number of special cases is low ✅ Uniform structure ✅ One Layer of Abstraction ✅ It's time efficient 18 — Code Generators in Swift, #se2016

Slide 19

Slide 19 text

In case if we create one This is actually simplified formula It's doesnt count that we get experience TIME EFFICIENCY RULE* 19 — Code Generators in Swift, #se2016

Slide 20

Slide 20 text

TIME EFFICIENCY RULE* 20 — Code Generators in Swift, #se2016

Slide 21

Slide 21 text

21 — Code Generators in Swift, #se2016

Slide 22

Slide 22 text

SOURCE 22 — Code Generators in Swift, #se2016

Slide 23

Slide 23 text

It can be your own DSL in your own language Or DSL as valid structures in source language Dynamic languages like Ruby, Python, Groovy GENERATOR SOURCE DSL 23 — Code Generators in Swift, #se2016

Slide 24

Slide 24 text

It can be tranformed by Regex Regex SourceKitten GENERATOR SOURCE SWIFT CODE 24 — Code Generators in Swift, #se2016

Slide 25

Slide 25 text

EXAMPLES 25 — Code Generators in Swift, #se2016

Slide 26

Slide 26 text

LET'S START FROM EASY ONES... 26 — Code Generators in Swift, #se2016

Slide 27

Slide 27 text

CODE SNIPPETS 27 — Code Generators in Swift, #se2016

Slide 28

Slide 28 text

28 — Code Generators in Swift, #se2016

Slide 29

Slide 29 text

XCODE FILE TEMPLATES 29 — Code Generators in Swift, #se2016

Slide 30

Slide 30 text

PROJECT TEMPLATES 30 — Code Generators in Swift, #se2016

Slide 31

Slide 31 text

BIT MORE COMPLEX EXAMPLES 31 — Code Generators in Swift, #se2016

Slide 32

Slide 32 text

SWAGGER > Source Language: DSL in YAML / JSON > Written In: Java > Generates: Everything http://swagger.io/ 32 — Code Generators in Swift, #se2016

Slide 33

Slide 33 text

CUCKOO > Source Language: Swift Code > Written in: Swift > Generates: Swift (Mocks) https://github.com/SwiftKit/ Cuckoo 33 — Code Generators in Swift, #se2016

Slide 34

Slide 34 text

CUCKOO let mock = MockGreeter() stub(mock) { stub in when(stub.greetWithMessage("Hello world")).then { message in print(message) } } 34 — Code Generators in Swift, #se2016

Slide 35

Slide 35 text

VIPER MODULE GENERATOR > Source Language: String > Written in: Ruby > Generates: Swift, Objective-C https://github.com/teambox/ viper-module-generator 35 — Code Generators in Swift, #se2016

Slide 36

Slide 36 text

PROTOBUF Source: Protocol Buffers Language Written in: * Generates: Swift, Any Supported Language https://github.com/alexeyxo/protobuf- swift https://github.com/google/protobuf 36 — Code Generators in Swift, #se2016

Slide 37

Slide 37 text

SWIFTGEN Source: Xcode Files Written in : Swift Generates: Enums for resources https://github.com/AliSoftware/SwiftGen 37 — Code Generators in Swift, #se2016

Slide 38

Slide 38 text

SWIFTGEN // The Image type below is typealias'ed to UIImage on iOS and NSImage on OSX enum Asset: String { case Green_Apple = "Green-Apple" case Red_Apple = "Red apple" case _2_Pears = "2-pears" var image: Image { return Image(asset: self) } } extension Image { convenience init!(asset: Asset) { self.init(named: asset.rawValue) } } 38 — Code Generators in Swift, #se2016

Slide 39

Slide 39 text

R Source: Xcode Project Files Written in : Swift Generates: Enums for resources https://github.com/mac-cain13/R.swift 39 — Code Generators in Swift, #se2016

Slide 40

Slide 40 text

R 40 — Code Generators in Swift, #se2016

Slide 41

Slide 41 text

HELIUM Source : DSL in Groovy Written in : JVM Languages Java/Kotlin/Groovy Generates: Java Library, API Client, Swift, Objective-C https://github.com/stanfy/ helium 41 — Code Generators in Swift, #se2016

Slide 42

Slide 42 text

IF YOU DECIDED TO CREATE ON 42 — Code Generators in Swift, #se2016

Slide 43

Slide 43 text

TEMPLATES, DSL 43 — Code Generators in Swift, #se2016

Slide 44

Slide 44 text

SOURCEKITTEN 44 — Code Generators in Swift, #se2016

Slide 45

Slide 45 text

SOURCEKITTEN [{ "descriptionKey" : "advancedBy(n: Distance)", "associatedUSRs" : "s:FSi10advancedByFSiFSiSi ", "kind" : "source.lang.swift.decl.function.method.instance", "sourcetext" : "advancedBy(<#T##n: Distance##Distance#>)", "context" : "source.codecompletion.context.thisclass", "typeName" : "Int", "moduleName" : "Swift", "name" : "advancedBy(n: Distance)" }, 45 — Code Generators in Swift, #se2016

Slide 46

Slide 46 text

SOURCEKITTEN sourcekitten structure --text "struct A { func b() {} } { "key.substructure" : [ { "key.kind" : "source.lang.swift.decl.struct", "key.offset" : 0, "key.nameoffset" : 7, "key.namelength" : 1, "key.bodyoffset" : 10, "key.bodylength" : 13, "key.length" : 24, "key.substructure" : [ ... } ], "key.offset" : 0, "key.diagnostic_stage" : "source.diagnostic.stage.swift.parse", "key.length" : 24 } 46 — Code Generators in Swift, #se2016

Slide 47

Slide 47 text

TIPS AND TRICKS 47 — Code Generators in Swift, #se2016

Slide 48

Slide 48 text

TIPS AND TRICKS > Don't go too deep > Use template > Don't overdo > Check reality > Document > Open Source 48 — Code Generators in Swift, #se2016

Slide 49

Slide 49 text

OUR RESULTS 49 — Code Generators in Swift, #se2016

Slide 50

Slide 50 text

SOURCE type 'Shop' message { shop_id 'string' image 'string' name 'string' description 'string' currency 'string' optional service_charge 'AdditionalCharges' optional payment_methods(type:'PaymentMethod') { sequence true required false } } 50 — Code Generators in Swift, #se2016

Slide 51

Slide 51 text

SOURCE type "dayOfWeek" spec { constraints("string") { enumeration 'sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat' } } 51 — Code Generators in Swift, #se2016

Slide 52

Slide 52 text

ENTITIES GENERATION public enum DayOfWeek: String { case Sun = "sun" case Mon = "mon" case Tue = "tue" case Wed = "wed" case Thu = "thu" case Fri = "fri" case Sat = "sat" } 52 — Code Generators in Swift, #se2016

Slide 53

Slide 53 text

ENTITIES GENERATION public struct Shop { public let shopId: String public let image: String public let name: String public let description: String public let currency: String? public let serviceCharge: AdditionalCharges? public let paymentMethods: [PaymentMethod]? } 53 — Code Generators in Swift, #se2016

Slide 54

Slide 54 text

EQUATABLE // MARK: - Shop Equatable public func == (lhs: Shop, rhs: Shop) -> Bool { return lhs.shopId == rhs.shopId && lhs.image == rhs.image && lhs.name == rhs.name && lhs.description == rhs.description && lhs.currency == rhs.currency && lhs.serviceCharge == rhs.serviceCharge && lhs.paymentMethods == rhs.paymentMethods } 54 — Code Generators in Swift, #se2016

Slide 55

Slide 55 text

MAPPINGS GENERATION extension DayOfWeek: Decodable {} extension Shop: Decodable { public static func decode(json: AnyObject) throws -> Shop { return try Shop( internalId: json =>? "internal_id" , shopId: json => "shop_id" , image: json => "image" , name: json => "name" , description: json => "description" , currency: json =>? "currency" , deliveryCharge: json =>? "delivery_charge" , paymentMethods: json =>? "payment_methods" ) } } 55 — Code Generators in Swift, #se2016

Slide 56

Slide 56 text

RANDOM STRUCTURES GENERATION extension Shop: Random { static func random() -> Shop { return restrictedRandom() } } 56 — Code Generators in Swift, #se2016

Slide 57

Slide 57 text

RANDOM STRUCTURES GENERATION extension Shop: Random { static func restrictedRandom( shopId: String = .random(), image: String = .random(), name: String = .random() ... ) -> Shop { return Shop( shopId: shopId, image: image, name: name ... ) } } 57 — Code Generators in Swift, #se2016

Slide 58

Slide 58 text

STRUCTURES UPDATES extension Shop { func updated( shopId: Optional = nil, image: Optional = nil, name: Optional = nil ... ) -> Shop { return Shop( shopId:shopId ?? self.shopId, image:image ?? self.image, name:name ?? self.name ... ) } } 58 — Code Generators in Swift, #se2016

Slide 59

Slide 59 text

GENERATED CODE IN ACTION // Only shipId will be set up let validShop = Shop.restrictedRandom( shopId: "SE2016", currency: "UAH" ) // Everything will be copied but 'shopID' property let anotherShop = validShop.updated(shopId:"123") // If we want to set up nil value let notSavedYet = validShop.updated(internalId: Optional(nil)) let notSavedYet2 = validShop.updated(internalId: .Some(nil)) 59 — Code Generators in Swift, #se2016

Slide 60

Slide 60 text

FROM ONE SOURCE type 'Shop' message { shop_id 'string' image 'string' name 'string' description 'string' currency 'string' optional service_charge 'AdditionalCharges' optional payment_methods(type:'PaymentMethod') { sequence true required false } } 60 — Code Generators in Swift, #se2016

Slide 61

Slide 61 text

SUMMARIZE > Code generators are here 61 — Code Generators in Swift, #se2016

Slide 62

Slide 62 text

SUMMARIZE > Engineering approach > Art 62 — Code Generators in Swift, #se2016

Slide 63

Slide 63 text

SUMMARIZE > There're always things to automate > Code generation is one of the multiple options 63 — Code Generators in Swift, #se2016

Slide 64

Slide 64 text

SUMMARIZE > Write your own if it worth it > Please don't write another one-time-complex generator > Document well 64 — Code Generators in Swift, #se2016

Slide 65

Slide 65 text

THANK YOU 65 — Code Generators in Swift, #se2016

Slide 66

Slide 66 text

CODE GENERATORS IN SWIFT BY PAUL TAYKALO, STANFY @TT_KILEW 66 — Code Generators in Swift, #se2016

Slide 67

Slide 67 text

Which one to create? https://habrahabr.ru/post/141477/ The general idea of what will we be talking about here and today Generatros why do we need them Why genertaors? What other options can we have? What we're tryin to achive? How we can do that? Next steps The ide of the all programmers is to not writing code less code - is better But it doesn't mean that this means than you need to write less code in the final language Right? No matter how many real code will be generated - if you have original code - less - is better Reperetive operations We dont' want to perform repetetive opertins. It's really easy for a brain to perform repetetive tasks. Really. But it's also really boring, and really time consuming So in case if we can automate - we should Small task size | Big task size | Fast to automate | Takes long time to automate If it takes less time to automate... What other problems we have here? Repetetive tasks tend to have copy-paste errors. Yep. Let's say, that Programmer will make a stupid mistake once per 1K lines of code (removed and deleted) Few More Facts Generated code is easier to remove Example with tests book Other examples of transformations Code Generation as Transformation -> One Form -> map -> AnotherForm XML + XSLT - ... Xib + Compielr - UI SwiftCode + CLANGCompiler -> ARM instructions A Bit of History - we have an API - mapped to the JAva groovy + APi spec (Java + RetroFit) - then we need to use that api on both Android and Other systems - we also need to have API tests, since most of our subcontractors weren't doing testing right - so we decided to write "Spec" which will describe everything and we'll use it to generate clients - And original Spec was a THE END 67 — Code Generators in Swift, #se2016