Slide 1

Slide 1 text

4XJGU4ZOUBYͰ
 ศརΛ࣮ݱ͢Δجૅ Kuniwak - DeNA Co.,Ltd. 2019.03.22 try! Swift Tokyo 2019

Slide 2

Slide 2 text

2 Some code will be presented in the slides,
 you can see the slides and the code here: ൃදதʹίʔυ͕ग़͖ͯ·͕͢ɺಡΈͮΒ͍৔߹͸
 ҎԼ͔ΒεϥΠυΛ͝ཡ͍ͩ͘͞ɿ speakerdeck.com/orgachem

Slide 3

Slide 3 text

"CPVUNF

Slide 4

Slide 4 text

,VOJXBL w ॴଐˠ • github.com/Kuniwak • qiita.com/Kuniwak w ߏจղੳ΍୯ମςετ͕޷෺ w "QQ$PEF࢖͍ 4

Slide 5

Slide 5 text

෼ؒͰ఻͍͑ͨ͜ͱ

Slide 6

Slide 6 text

4XJGU4ZOUBYΛ࢖͏ͱɺ4XJGUͷ
 ੩తݕࠪ΍ίʔυੜ੒Λ؆୯ʹͰ͖Δʂ 6

Slide 7

Slide 7 text

4XJGU4ZOUBYͱ͸

Slide 8

Slide 8 text

4XJGU4ZOUBY͸4XJGUͷެࣜϥΠϒϥϦ github.com/apple/swift-syntax 8

Slide 9

Slide 9 text

4XJGU4ZOUBYͰ
 Ͱ͖Δ͜ͱ

Slide 10

Slide 10 text

ಡΈॻ͖͠΍͍͢σʔλ ίʔυΛɺಡΈॻ͖͠΍͍͢σʔλʹ͢Δ ಡΈॻ͖͠΍͍͢σʔλΛɺίʔυʹ͢Δ 4XJGUͷίʔυ ಡΈॻ͖͠΍͍͢σʔλ 4XJGUͷίʔυ 10

Slide 11

Slide 11 text

ಡΈॻ͖͠΍͍͢σʔλ ίʔυΛɺಡΈॻ͖͠΍͍͢σʔλʹ͢Δ ಡΈॻ͖͠΍͍͢σʔλΛɺίʔυʹ͢Δ 4XJGUͷίʔυ ಡΈॻ͖͠΍͍͢σʔλ 4XJGUͷίʔυ 11

Slide 12

Slide 12 text

ίʔυΛɺಡΈॻ͖͠΍͍͢σʔλʹ͢Δ if let self = self {} 12 આ໌ʹ࢖͏αϯϓϧίʔυ

Slide 13

Slide 13 text

ίʔυΛɺಡΈॻ͖͠΍͍͢σʔλʹ͢Δ if let self = self {} JGจ 13 ͜Ε͸ʮJGจʯͱݺ͹ΕΔ

Slide 14

Slide 14 text

ίʔυΛɺಡΈॻ͖͠΍͍͢σʔλʹ͢Δ if let self = self {} if let self = self {} JGจ ෳจ ৚݅ 14 JGจ͸ʮ৚݅ʯͱʮෳจʯͰ
 ߏ੒͞Ε͍ͯΔ

Slide 15

Slide 15 text

ίʔυΛɺಡΈॻ͖͠΍͍͢σʔλʹ͢Δ if let self = self {} if let self = self {} JGจ ෳจ 0QUJPOଋറ৚݅ 15 ࠓճͷ৚݅෦෼ʹ͸ɺ
 ʮ0QUJPOଋറ৚݅ʯͱ
 ݺ͹Ε͍ͯΔ΋ͷ͕ೖΔ

Slide 16

Slide 16 text

ίʔυΛɺಡΈॻ͖͠΍͍͢σʔλʹ͢Δ if let self = self {} if let self = self {} JGจ ෳจ 0QUJPOଋറ৚݅ ม਺ࣜ ม਺ύλʔϯ if let self = self {} 16 0QUJPOଋറ৚݅͸ɺ୅ೖઌͷ
 ʮม਺ύλʔϯʯͱ୅ೖ͢Δ஋ͷ
 ʮม਺ࣜʯͰߏ੒͞Ε͍ͯΔ

Slide 17

Slide 17 text

ίʔυΛɺಡΈॻ͖͠΍͍͢σʔλʹ͢Δ if let self = self {} if let self = self {} if let self = self {} 17 ͜ͷΑ͏ʹɺίʔυΛ෼ղͯ͠
 ߏ੒ཁૉΛḷ͍ͬͯ͘ͱɺ
 ίʔυΛʮ໦ߏ଄ʯͱͯ͠
 ѻ͍ͬͯΔ͜ͱʹؾͮ͘

Slide 18

Slide 18 text

ίʔυΛɺಡΈॻ͖͠΍͍͢σʔλʹ͢Δ if let self = self {} if let self = self {} if let self = self {} 18 ෳจ JGจ ෳจ ม਺ύλʔϯ ม਺ࣜ 0QUJPOଋറ৚݅

Slide 19

Slide 19 text

ίʔυΛɺಡΈॻ͖͠΍͍͢σʔλʹ͢Δ if let self = self {} if let self = self {} JGจ ෳจ 0QUJPOଋറ ม਺ࣜ ม਺ύλʔϯ if let self = self {} JGจ ෳจ ม਺ύλʔϯ ม਺ࣜ ͜ΕΛʮߏจ໦ʯͱΑͿ 19 0QUJPOଋറ৚݅

Slide 20

Slide 20 text

4XJGU4ZOUBYͰ
 ʮߏจ໦ʯΛಡΉ

Slide 21

Slide 21 text

4XJGU4ZUOBYͰߏจ໦ΛಡΉ if let self = self {} if let self = self {} JGจ ෳจ 0QUJPOଋറ ม਺ࣜ ม਺ύλʔϯ if let self = self {} ม਺໊ΛಡΜͰΈΑ͏ 21

Slide 22

Slide 22 text

import SwiftSyntax let url = URL(fileURLWithPath: "example.swift") let source = try String(contentsOf: url) let syntax = try SyntaxParser.parse(source: source) 4XJGU4ZOUBYͰ ಡΈॻ͖͠΍͍͢σʔλʢߏจ໦ʣʹ͢Δ 4XJGUͷίʔυΛ 22

Slide 23

Slide 23 text

if let self = self {} if let self = self {} JGจ ෳจ 0QUJPOଋറ ม਺ࣜ ม਺ύλʔϯ if let self = self {} ifStmt 4XJGU4ZUOBYͰߏจ໦ΛಡΉ JGจ·ͰͷऔΓํ͸
 গ͠໘౗ͳͷͰޙड़ 23

Slide 24

Slide 24 text

if let self = self {} if let self = self {} JGจ ෳจ 0QUJPOଋറ ม਺ࣜ ม਺ύλʔϯ if let self = self {} ifStmt .conditions[0] .condition 
 4XJGU4ZUOBYͰߏจ໦ΛಡΉ 24

Slide 25

Slide 25 text

if let self = self {} if let self = self {} JGจ ෳจ 0QUJPOଋറ ม਺ࣜ ม਺ύλʔϯ if let self = self {} "self" ifStmt .conditions[0] .condition .pattern
 .identifier .text 4XJGU4ZUOBYͰߏจ໦ΛಡΉ 25

Slide 26

Slide 26 text

let name = ifStmt .conditions[0] .condition .pattern
 .identifier .text if name == "this" { print("Oops!") } ྫ͑͹ɺif let self = ͷม਺໊͕
 ౷Ұ͞Ε͍ͯͳ͍৔߹ʹܯࠂͰ͖Δ ߏจ໦ΛಡΊΕ͹ɺΦϨΦϨ4XJGU-JOU͕ॻ͚Δ 26

Slide 27

Slide 27 text

import SwiftSyntax let url = URL(fileURLWithPath: "example.swift") let source = try String(contentsOf: url) let syntax = try SyntaxParser.parse(source: source)
 let stmts = Array(syntax.statements)
 guard let ifStmt = stmts.first?.item as? IfStmtSyntax else { print("If statement not found at the position.") return } JGจ͸গ͠ख͕ؒͩ͜ͷΑ͏ʹऔΕΔɻ࣮ࡍͷߏจ໦ΛEVNQ͢ΔͱΘ͔Δ JGจ·ͰͷऔΓํ 27 ൃ ද Ͱ ͸ ল ུ

Slide 28

Slide 28 text

ಡΈॻ͖͠΍͍͢ߏจ໦ ίʔυΛɺಡΈॻ͖͠΍͍͢ߏจ໦ʹ͢Δ ಡΈॻ͖͠΍͍͢ߏจ໦Λɺίʔυʹ͢Δ 4XJGUͷίʔυ ಡΈॻ͖͠΍͍͢σʔλ 4XJGUͷίʔυ DONE 28

Slide 29

Slide 29 text

ίʔυΛɺಡΈॻ͖͠΍͍͢σʔλʹ͢Δ ಡΈॻ͖͠΍͍͢ߏจ໦Λɺίʔυʹ͢Δ 4XJGUͷίʔυ 4XJGUͷίʔυ ಡΈॻ͖͠΍͍͢ߏจ໦ ಡΈॻ͖͠΍͍͢ߏจ໦ DONE 29

Slide 30

Slide 30 text

if let this = self {} 4XJGU4ZUOBYͰमਖ਼ͨ͠ίʔυΛੜ੒͢Δ if let self = self {} 30

Slide 31

Slide 31 text

import SwiftSyntax class RenameRewriter: SyntaxRewriter { override func visit(_ node: IdentifierPatternSyntax) -> PatternSyntax { if node.identifier.text == "this" { var modifiedNode = node modifiedNode.identifier = SyntaxFactory .makeIdentifier("self") return modifiedNode } return node } } let syntax = try SyntaxParser.parse(source: String(contentsOf: url)) print(RenameRewriter().visit(syntax)) 31

Slide 32

Slide 32 text

import SwiftSyntax class RenameRewriter: SyntaxRewriter { override func visit(_ node: IdentifierPatternSyntax) -> PatternSyntax { if node.identifier.text == "this" { var modifiedNode = node modifiedNode.identifier = SyntaxFactory .makeIdentifier("self") return modifiedNode } return node } } let syntax = try SyntaxParser.parse(source: String(contentsOf: url)) print(RenameRewriter().visit(syntax)) 4XJGU4ZOUBYΛ࢖͏ 32

Slide 33

Slide 33 text

import SwiftSyntax class RenameRewriter: SyntaxRewriter { override func visit(_ node: IdentifierPatternSyntax) -> PatternSyntax { if node.identifier.text == "this" { var modifiedNode = node modifiedNode.identifier = SyntaxFactory .makeIdentifier("self") return modifiedNode } return node } } let syntax = try SyntaxParser.parse(source: String(contentsOf: url)) print(RenameRewriter().visit(syntax)) 4XJGU4ZOUBYͰಡΈॻ͖͠΍͍͢ߏจ໦ʹ͢Δ 33

Slide 34

Slide 34 text

import SwiftSyntax class RenameRewriter: SyntaxRewriter { override func visit(_ node: IdentifierPatternSyntax) -> PatternSyntax { if node.identifier.text == "this" { var modifiedNode = node modifiedNode.identifier = SyntaxFactory .makeIdentifier("self") return modifiedNode } return node } } let syntax = try SyntaxParser.parse(source: String(contentsOf: url)) print(RenameRewriter().visit(syntax)) ߏจ໦Λॻ͖׵͑ͯɺ݁ՌΛදࣔ͢Δ 34

Slide 35

Slide 35 text

import SwiftSyntax class RenameRewriter: SyntaxRewriter { override func visit(_ node: IdentifierPatternSyntax) -> PatternSyntax { if node.identifier.text == "this" { var modifiedNode = node modifiedNode.identifier = SyntaxFactory .makeIdentifier("self") return modifiedNode } return node } } let syntax = try SyntaxParser.parse(source: String(contentsOf: url)) print(RenameRewriter().visit(syntax)) ߏจ໦Λॻ͖׵͑ΔͨΊͷΫϥε 35

Slide 36

Slide 36 text

import SwiftSyntax class RenameRewriter: SyntaxRewriter { override func visit(_ node: IdentifierPatternSyntax) -> PatternSyntax { if node.identifier.text == "this" { var modifiedNode = node modifiedNode.identifier = SyntaxFactory .makeIdentifier("self") return modifiedNode } return node } } let syntax = try SyntaxParser.parse(source: String(contentsOf: url)) print(RenameRewriter().visit(syntax)) ॻ͖׵͍͑ͨߏจ໦ͷWJTJUؔ਺ΛPWFSSJEF͢Δ ࠓճ͸JGMFU9ͷ9෦෼͕ର৅
 ʢܕͷ໊લ͸EVNQͰௐ΂ΔͱΘ͔Δʣ 36

Slide 37

Slide 37 text

import SwiftSyntax class RenameRewriter: SyntaxRewriter { override func visit(_ node: IdentifierPatternSyntax) -> PatternSyntax { if node.identifier.text == "this" { var modifiedNode = node modifiedNode.identifier = SyntaxFactory .makeIdentifier("self") return modifiedNode } return node } } let syntax = try SyntaxParser.parse(source: String(contentsOf: url)) print(RenameRewriter().visit(syntax)) JGMFU9ͷ9෦෼͕UIJTͳΒॻ͖׵͑Δ 37

Slide 38

Slide 38 text

import SwiftSyntax class RenameRewriter: SyntaxRewriter { override func visit(_ node: IdentifierPatternSyntax) -> PatternSyntax { if node.identifier.text == "this" { var modifiedNode = node modifiedNode.identifier = SyntaxFactory .makeIdentifier("self") return modifiedNode } return node } } let syntax = try SyntaxParser.parse(source: String(contentsOf: url)) print(RenameRewriter().visit(syntax)) 9෦෼ΛTFMGʹॻ͖׵͑Δ 38

Slide 39

Slide 39 text

import SwiftSyntax class RenameRewriter: SyntaxRewriter { override func visit(_ node: IdentifierPatternSyntax) -> PatternSyntax { if node.identifier.text == "this" { var modifiedNode = node modifiedNode.identifier = SyntaxFactory .makeIdentifier("self") return modifiedNode } return node } } let syntax = try SyntaxParser.parse(source: String(contentsOf: url)) print(RenameRewriter().visit(syntax)) 39

Slide 40

Slide 40 text

import SwiftSyntax class RenameRewriter: SyntaxRewriter { override func visit(_ node: IdentifierPatternSyntax) -> PatternSyntax { if node.identifier.text == "this" { var modifiedNode = node modifiedNode.identifier = SyntaxFactory .makeIdentifier("self") return modifiedNode } return node } } let syntax = try SyntaxParser.parse(source: String(contentsOf: url)) print(RenameRewriter().visit(syntax)) "if let self= self {}" 40 ίʔυΛੜ੒Ͱ͖ͨʂ

Slide 41

Slide 41 text

import SwiftSyntax class RenameRewriter: SyntaxRewriter { override func visit(_ node: IdentifierPatternSyntax) -> PatternSyntax { if node.identifier.text == "this" { var modifiedNode = node modifiedNode.identifier = SyntaxFactory .makeIdentifier("self") return modifiedNode } return node } } let syntax = try SyntaxParser.parse(source: String(contentsOf: url)) print(RenameRewriter().visit(syntax)) "if let self= self {}" 41 Α͘ݟΔͱۭന͕
 ফ͑ͯ͠·͍ͬͯΔ

Slide 42

Slide 42 text

import SwiftSyntax class RenameRewriter: SyntaxRewriter { override func visit(_ node: IdentifierPatternSyntax) -> PatternSyntax { if node.identifier.text == "this" { var modifiedNode = node let originalIdentifier = node.identifier modifiedNode.identifier = SyntaxFactory .makeIdentifier("self") .withTrailingTrivia(originalIdentifier.trailingTrivia) return modifiedNode } return node } } let syntax = try SyntaxParser.parse(source: String(contentsOf: url)) print(RenameRewriter().visit(syntax)) TFMGޙͷۭന͕ͳ͘ͳΔ໰୊͸5SJWJBͰௐ੔Ͱ͖Δ ൃ ද Ͱ ͸ ল ུ 42

Slide 43

Slide 43 text

if let this = self {} 4XJGU4ZUOBYͰमਖ਼ͨ͠ίʔυΛੜ੒͢Δ if let self = self {} 43 DONE

Slide 44

Slide 44 text

ίʔυΛɺಡΈॻ͖͠΍͍͢ߏจ໦ʹ͢Δ ಡΈॻ͖͠΍͍͢ߏจ໦Λɺίʔυʹ͢Δ 4XJGUͷίʔυ 4XJGUͷίʔυ ಡΈॻ͖͠΍͍͢ߏจ໦ ಡΈॻ͖͠΍͍͢ߏจ໦ DONE 44 DONE

Slide 45

Slide 45 text

4XJGU4ZOUBYΛ࢖͏ͱɺ
 4XJGUͷߏจ໦ͷݕࠪ΍
 मਖ਼ͨ͠ίʔυΛੜ੒Ͱ͖ͨʂ ·ͱΊ 45