Upgrade to Pro — share decks privately, control downloads, hide ads and more …

機械的なコーディングの自動化

Yosuke Imairi
October 06, 2021

 機械的なコーディングの自動化

After iOSDC Japan 2021 での登壇資料となります。

発表概要
https://zozotech-inc.connpass.com/event/222423/

以下、スライド内に登場するリンク一覧です。

大規模リファクタリングの極意
https://speakerdeck.com/imairi/da-gui-mo-rihuakutaringufalseji-yi

SourceKitten
https://github.com/jpsim/SourceKitten

RIBsCodeGen
https://github.com/imairi/RIBsCodeGen

Source Editor ExtensionとSwiftSyntaxでコード自動生成ツールを作る
https://fortee.jp/iosdc-japan-2021/proposal/734e9f50-1662-4aea-acc3-da4140a47dbd

タクシーアプリ GO の iOS エンジニア採用ページ
https://hrmos.co/pages/mo-t/jobs/2100002

Yosuke Imairi

October 06, 2021
Tweet

More Decks by Yosuke Imairi

Other Decks in Technology

Transcript

  1. Mobility Technologies Co., Ltd.
    機械的なコーディングの⾃動化
    Yosuke Imairi

    View Slide

  2. Mobility Technologies Co., Ltd.
    2
    Yosuke Imairi
    ⾃⼰紹介
    - JapanTaxi (2017.05 - 2020.4)
    - 全国タクシー
    - 相乗りタクシー
    - JapanTaxi
    - Mobility Technologies (2020.4 - )
    - MOV
    - GO

    View Slide

  3. Mobility Technologies Co., Ltd.
    3
    iOSDC Japan 2021 で登壇させていただきました
    https://speakerdeck.com/imairi/da-gui-mo-rihuakutaringufalseji-yi

    View Slide

  4. Mobility Technologies Co., Ltd.
    4
    iOSDC Japan 2021 で登壇させていただきました
    https://speakerdeck.com/imairi/da-gui-mo-rihuakutaringufalseji-yi

    View Slide

  5. Mobility Technologies Co., Ltd.
    5
    設計から実装をはじめるまで
    設計
    実装
    ❏ 要求をどう実現していくかを検討する
    ❏ 既存の実装の影響範囲を模索
    ❏ 新しく必要なコンポーネントの役割は何か
    ❏ どういう段取りで作業を進めるのか
    ❏ ルーティング
    ❏ ビジネスロジックの実装
    ❏ UI の作成

    View Slide

  6. Mobility Technologies Co., Ltd.
    6
    設計から実装をはじめるまで
    設計
    実装
    実装の準備
    ❏ 要求をどう実現していくかを検討する
    ❏ 既存の実装の影響範囲を模索
    ❏ 新しく必要なコンポーネントの役割は何か
    ❏ どういう段取りで作業を進めるのか
    ❏ ルーティング
    ❏ ビジネスロジックの実装
    ❏ UI の作成

    View Slide

  7. Mobility Technologies Co., Ltd.
    7
    設計から実装をはじめるまで(タクシーアプリ『GO』の場合)
    設計
    実装
    実装の準備
    ❏ 親 Interactable に⼦ Listener の追加
    ❏ 親 Router に⼦ Builder の定義を追加
    ❏ 親 Router のイニシャライズに⼦ Builder を追加
    ❏ 必要であればイニシャライズの override を削除
    ❏ 親 Router が保持する⼦ Builder の初期化
    既存のRouter 既存のBuilder
    ❏ 親 Dependency に⼦ Dependency を追加
    ❏ 親 Builder の build メソッド内で⼦ Builder を初期化
    ❏ 親 Router ⽣成時に引数として⼦ Builder を追加
    既存コードの改変(初期化, Protocol 追加などの単純作業)
    Router Builder
    Interactor ViewController Component
    Extension
    RIBs アーキテクチャで必要なボイラープレートの作成

    View Slide

  8. Mobility Technologies Co., Ltd.
    8
    設計から実装をはじめるまで(タクシーアプリ『GO』の場合)
    設計
    実装
    実装の準備
    ❏ 親 Interactable に⼦ Listener の追加
    ❏ 親 Router に⼦ Builder の定義を追加
    ❏ 親 Router のイニシャライズに⼦ Builder を追加
    ❏ 必要であればイニシャライズの override を削除
    ❏ 親 Router が保持する⼦ Builder の初期化
    既存のRouter 既存のBuilder
    ❏ 親 Dependency に⼦ Dependency を追加
    ❏ 親 Builder の build メソッド内で⼦ Builder を初期化
    ❏ 親 Router ⽣成時に引数として⼦ Builder を追加
    既存コードの改変(初期化, Protocol 追加などの単純作業)
    Router Builder
    Interactor ViewController Component
    Extension
    RIBs アーキテクチャで必要なボイラープレートの作成
    ある程度決まりきった
    単純な作業の繰り返し
    🤔

    View Slide

  9. Mobility Technologies Co., Ltd.
    9
    設計から実装をはじめるまで(タクシーアプリ『GO』の場合)
    設計
    実装
    実装の準備
    ❏ 親 Interactable に⼦ Listener の追加
    ❏ 親 Router に⼦ Builder の定義を追加
    ❏ 親 Router のイニシャライズに⼦ Builder を追加
    ❏ 必要であればイニシャライズの override を削除
    ❏ 親 Router が保持する⼦ Builder の初期化
    既存のRouter 既存のBuilder
    ❏ 親 Dependency に⼦ Dependency を追加
    ❏ 親 Builder の build メソッド内で⼦ Builder を初期化
    ❏ 親 Router ⽣成時に引数として⼦ Builder を追加
    既存コードの改変(初期化, Protocol 追加などの単純作業)
    Router Builder
    Interactor ViewController Component
    Extension
    RIBs アーキテクチャで必要なボイラープレートの作成
    機械的なコーディングは
    なるべく⾃動化したい
    😲
    💡

    View Slide

  10. Mobility Technologies Co., Ltd.
    10
    設計から実装をはじめるまで(タクシーアプリ『GO』の場合)
    設計
    実装
    実装の準備
    ❏ 親 Interactable に⼦ Listener の追加
    ❏ 親 Router に⼦ Builder の定義を追加
    ❏ 親 Router のイニシャライズに⼦ Builder を追加
    ❏ 必要であればイニシャライズの override を削除
    ❏ 親 Router が保持する⼦ Builder の初期化
    既存のRouter 既存のBuilder
    ❏ 親 Dependency に⼦ Dependency を追加
    ❏ 親 Builder の build メソッド内で⼦ Builder を初期化
    ❏ 親 Router ⽣成時に引数として⼦ Builder を追加
    既存コードの改変(初期化, Protocol 追加などの単純作業)
    Router Builder
    Interactor ViewController Component
    Extension
    RIBs アーキテクチャで必要なボイラープレートの作成

    View Slide

  11. Mobility Technologies Co., Ltd.
    11
    ボイラープレートへの対応策
    ❏ Xcode Template
    ❏ ~/Library/Developer/Xcode/Templates/File¥ Templates/ 内で管理

    View Slide

  12. Mobility Technologies Co., Ltd.
    12
    ボイラープレートへの対応策
    ❏ Xcode Template
    ❏ テンプレートにしたがって新規ファイルが作成される

    View Slide

  13. Mobility Technologies Co., Ltd.
    13
    設計から実装をはじめるまで(タクシーアプリ『GO』の場合)
    設計
    実装
    実装の準備
    Router Builder
    Interactor ViewController Component
    Extension
    RIBs アーキテクチャで必要なボイラープレートの作成
    ❏ 親 Interactable に⼦ Listener の追加
    ❏ 親 Router に⼦ Builder の定義を追加
    ❏ 親 Router のイニシャライズに⼦ Builder を追加
    ❏ 必要であればイニシャライズの override を削除
    ❏ 親 Router が保持する⼦ Builder の初期化
    既存のRouter 既存のBuilder
    ❏ 親 Dependency に⼦ Dependency を追加
    ❏ 親 Builder の build メソッド内で⼦ Builder を初期化
    ❏ 親 Router ⽣成時に引数として⼦ Builder を追加
    既存コードの改変(初期化, Protocol 追加などの単純作業)

    View Slide

  14. Mobility Technologies Co., Ltd.
    ❏ RIBs における Router の場合
    14
    既存コードをどう改変したいのか
    特定の Protocol に準拠させる
    もし override があれば削除
    新しいプロパティの追加
    新しく追加したプロパティの初期化

    View Slide

  15. Mobility Technologies Co., Ltd.
    15
    既存コードの改変への対応策
    ❏ 追加したいコードは決まっている
    ❏ 挿⼊箇所が特定できるとよさそう
    ❏ ファイルの⽂頭からの offset など
    ❏ コードの静的解析を活⽤
    ❏ SourceKitten (SourceKit)
    ❏ SwiftSyntax (swiftc -frontend -emit-syntax)

    View Slide

  16. Mobility Technologies Co., Ltd.
    16
    既存コードの改変への対応策
    ❏ SourceKitten によるコードの解析
    ❏ https://github.com/jpsim/SourceKitten

    View Slide

  17. Mobility Technologies Co., Ltd.
    17
    SourceKitten によるコードの解析

    View Slide

  18. Mobility Technologies Co., Ltd.
    18
    SourceKitten によるコードの解析

    View Slide

  19. Mobility Technologies Co., Ltd.
    19
    SourceKitten によるコードの解析

    View Slide

  20. Mobility Technologies Co., Ltd.
    20
    SourceKitten によるコードの解析
    key.kind key.name key.inheritedtypes
    key.substructure

    View Slide

  21. Mobility Technologies Co., Ltd.
    21
    SourceKitten によるコードの解析

    View Slide

  22. Mobility Technologies Co., Ltd.
    22
    SourceKitten によるコードの解析
    key.offset
    key.length

    View Slide

  23. Mobility Technologies Co., Ltd.
    23
    SourceKitten によるコードの解析
    key.bodyOffset
    key.bodyLeng
    th

    View Slide

  24. Mobility Technologies Co., Ltd.
    24
    SourceKitten によるコードの解析
    key.nameOffset
    key.nameLength

    View Slide

  25. Mobility Technologies Co., Ltd.
    25
    SourceKitten によるコードの解析
    key.offset
    key.length
    key.elements 内の

    View Slide

  26. Mobility Technologies Co., Ltd.
    特定の Protocol に準拠させる
    もし override があれば削除
    新しいプロパティの追加
    ❏ offset, length を組み合わせることで任意の場所にコードを挿⼊できる
    26
    既存コードを改変する
    新しく追加したプロパティの初期化

    View Slide

  27. Mobility Technologies Co., Ltd.
    特定の Protocol に準拠させる
    もし override があれば削除
    新しいプロパティの追加
    ❏ offset, length を組み合わせることで任意の場所にコードを挿⼊できる
    27
    既存コードを改変する
    Interactable の offset + length のあとに
    「,」 追加 ⇒ 改⾏ ⇒ 特定の Protocol を挿⼊
    init の offset の前に
    改⾏ ⇒ プロパティを追加
    init に override 修飾⼦がある場合は削除
    新しく追加したプロパティの初期化
    init の bodyOffset などから計算して
    必要なプロパティの追加、初期化

    View Slide

  28. Mobility Technologies Co., Ltd.
    28
    SourceKitten でハマったところ 😅
    ❏ offset, length で表現される数値は UTF-8 のバイト数
    ❏ 改⾏コードもカウントされる

    View Slide

  29. Mobility Technologies Co., Ltd.
    29
    既存コードの改変を⼿助けするツールの作成
    ❏ RIBsCodeGen
    ❏ https://github.com/imairi/RIBsCodeGen
    ❏ SourceKitten を利⽤したボイラープレート⾃動⽣成 + 依存解決ツール
    ❏ RIBs アーキテクチャにおける「実装準備」に必要な作業をすべて⾃動化
    ❏ RIBs 利⽤者が⼿軽に利⽤できるよう Swift Package Manager として公開
    ❏ Markdown 形式で設計を読み込ませることで⼀括処理が可能

    View Slide

  30. Mobility Technologies Co., Ltd.
    30
    必要なボイラープレートの作成
    特定の Protocol への準拠、初期化の追加 etc..
    状態に応じて不要な処理はスキップ

    View Slide

  31. Mobility Technologies Co., Ltd.
    31
    ❏ コードを解析して地道に書き換えていく
    ❏ コマンドラインからの⼊⼒を受け付ける
    ❏ 該当のディレクトリ・ファイルの存在有無の確認
    ❏ なければ作成しそのファイルパスを取得
    ❏ ファイルパスから Swift コードを読み込み解析
    ❏ 状態に応じて必要な処理を追加(書き込み)
    ❏ 特定のProtocol への準拠
    ❏ 初期化の引数に特定のプロパティを追加
    ❏ override 削除
    ❏ コードの整形
    CommandLine
    PathKit
    SourceKitten
    PathKit
    … etc.
    SourceKitten

    View Slide

  32. Mobility Technologies Co., Ltd.
    32
    設計から実装をはじめるまで(タクシーアプリ『GO』の場合)
    設計
    実装
    実装の準備
    ❏ 親 Interactable に⼦ Listener の追加
    ❏ 親 Router に⼦ Builder の定義を追加
    ❏ 親 Router のイニシャライズに⼦ Builder を追加
    ❏ 必要であればイニシャライズの override を削除
    ❏ 親 Router が保持する⼦ Builder の初期化
    既存のRouter 既存のBuilder
    ❏ 親 Dependency に⼦ Dependency を追加
    ❏ 親 Builder の build メソッド内で⼦ Builder を初期化
    ❏ 親 Router ⽣成時に引数として⼦ Builder を追加
    既存コードの改変(初期化, Protocol 追加などの単純作業)
    Router Builder
    Interactor ViewController Component
    Extension
    RIBs アーキテクチャで必要なボイラープレートの作成

    View Slide

  33. Mobility Technologies Co., Ltd.
    33
    設計から実装をはじめるまで(タクシーアプリ『GO』の場合)
    設計
    実装
    実装の準備
    ❏ 親 Interactable に⼦ Listener の追加
    ❏ 親 Router に⼦ Builder の定義を追加
    ❏ 親 Router のイニシャライズに⼦ Builder を追加
    ❏ 必要であればイニシャライズの override を削除
    ❏ 親 Router が保持する⼦ Builder の初期化
    既存のRouter 既存のBuilder
    ❏ 親 Dependency に⼦ Dependency を追加
    ❏ 親 Builder の build メソッド内で⼦ Builder を初期化
    ❏ 親 Router ⽣成時に引数として⼦ Builder を追加
    既存コードの改変(初期化, Protocol 追加などの単純作業)
    Router Builder
    Interactor ViewController Component
    Extension
    RIBs アーキテクチャで必要なボイラープレートの作成

    View Slide

  34. Mobility Technologies Co., Ltd.
    34
    設計から実装をはじめるまで(タクシーアプリ『GO』の場合)
    設計
    実装
    実装の準備
    ❏ 親 Interactable に⼦ Listener の追加
    ❏ 親 Router に⼦ Builder の定義を追加
    ❏ 親 Router のイニシャライズに⼦ Builder を追加
    ❏ 必要であればイニシャライズの override を削除
    ❏ 親 Router が保持する⼦ Builder の初期化
    既存のRouter 既存のBuilder
    ❏ 親 Dependency に⼦ Dependency を追加
    ❏ 親 Builder の build メソッド内で⼦ Builder を初期化
    ❏ 親 Router ⽣成時に引数として⼦ Builder を追加
    既存コードの改変(初期化, Protocol 追加などの単純作業)
    Router Builder
    Interactor ViewController Component
    Extension
    RIBs アーキテクチャで必要なボイラープレートの作成
    設計が終わったら
    すぐに実装が開始できる
    😊

    View Slide

  35. Mobility Technologies Co., Ltd.
    35
    まとめ
    ❏ 設計から実装開始までの作業は意外と多い
    ❏ ボイラープレートの作成
    ❏ 繰り返される機械的なコーディング
    ❏ 静的解析はツールを使えば難しくない
    ❏ SourceKitten / SwiftSyntax を利⽤してみる
    ❏ なるべく実装⾃体に時間を使えるように⼯夫したい
    ❏ 単純な作業は⾃動化して開発効率をあげよう
    ❏ iOSDC Japan 2021 にも関連トークがあるのでぜひ
    ❏ https://fortee.jp/iosdc-japan-2021/proposal/734e9f50-1662-
    4aea-acc3-da4140a47dbd

    View Slide

  36. Mobility Technologies Co., Ltd.
    36
    🚖
    お知らせ

    View Slide

  37. Mobility Technologies Co., Ltd.
    37
    タクシーアプリ「GO」の開発を⼀緒にしませんか
    https://hrmos.co/page
    s/mo-t/jobs/2100002

    View Slide

  38. 文章·画像等の内容の無断転載及び複製等の行為はご遠慮ください。
    Mobility Technologies Co., Ltd.

    View Slide