Save 37% off PRO during our Black Friday Sale! »

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

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

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

63bf22db8ab8da3851da34d2e0cb0c69?s=128

Yosuke Imairi

October 06, 2021
Tweet

Transcript

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

  2. Mobility Technologies Co., Ltd. 2 Yosuke Imairi ⾃⼰紹介 - JapanTaxi

    (2017.05 - 2020.4) - 全国タクシー - 相乗りタクシー - JapanTaxi - Mobility Technologies (2020.4 - ) - MOV - GO
  3. Mobility Technologies Co., Ltd. 3 iOSDC Japan 2021 で登壇させていただきました https://speakerdeck.com/imairi/da-gui-mo-rihuakutaringufalseji-yi

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

  5. Mobility Technologies Co., Ltd. 5 設計から実装をはじめるまで 設計 実装 ❏ 要求をどう実現していくかを検討する

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

    要求をどう実現していくかを検討する ❏ 既存の実装の影響範囲を模索 ❏ 新しく必要なコンポーネントの役割は何か ❏ どういう段取りで作業を進めるのか ❏ ルーティング ❏ ビジネスロジックの実装 ❏ UI の作成
  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 アーキテクチャで必要なボイラープレートの作成
  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 アーキテクチャで必要なボイラープレートの作成 ある程度決まりきった 単純な作業の繰り返し 🤔
  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 アーキテクチャで必要なボイラープレートの作成 機械的なコーディングは なるべく⾃動化したい 😲 💡
  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 アーキテクチャで必要なボイラープレートの作成
  11. Mobility Technologies Co., Ltd. 11 ボイラープレートへの対応策 ❏ Xcode Template ❏

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

    テンプレートにしたがって新規ファイルが作成される
  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 追加などの単純作業)
  14. Mobility Technologies Co., Ltd. ❏ RIBs における Router の場合 14

    既存コードをどう改変したいのか 特定の Protocol に準拠させる もし override があれば削除 新しいプロパティの追加 新しく追加したプロパティの初期化
  15. Mobility Technologies Co., Ltd. 15 既存コードの改変への対応策 ❏ 追加したいコードは決まっている ❏ 挿⼊箇所が特定できるとよさそう

    ❏ ファイルの⽂頭からの offset など ❏ コードの静的解析を活⽤ ❏ SourceKitten (SourceKit) ❏ SwiftSyntax (swiftc -frontend -emit-syntax)
  16. Mobility Technologies Co., Ltd. 16 既存コードの改変への対応策 ❏ SourceKitten によるコードの解析 ❏

    https://github.com/jpsim/SourceKitten
  17. Mobility Technologies Co., Ltd. 17 SourceKitten によるコードの解析

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

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

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

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

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

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

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

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

    内の
  26. Mobility Technologies Co., Ltd. 特定の Protocol に準拠させる もし override があれば削除

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

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

    length で表現される数値は UTF-8 のバイト数 ❏ 改⾏コードもカウントされる
  29. Mobility Technologies Co., Ltd. 29 既存コードの改変を⼿助けするツールの作成 ❏ RIBsCodeGen ❏ https://github.com/imairi/RIBsCodeGen

    ❏ SourceKitten を利⽤したボイラープレート⾃動⽣成 + 依存解決ツール ❏ RIBs アーキテクチャにおける「実装準備」に必要な作業をすべて⾃動化 ❏ RIBs 利⽤者が⼿軽に利⽤できるよう Swift Package Manager として公開 ❏ Markdown 形式で設計を読み込ませることで⼀括処理が可能
  30. Mobility Technologies Co., Ltd. 30 必要なボイラープレートの作成 特定の Protocol への準拠、初期化の追加 etc..

    状態に応じて不要な処理はスキップ
  31. Mobility Technologies Co., Ltd. 31 ❏ コードを解析して地道に書き換えていく ❏ コマンドラインからの⼊⼒を受け付ける ❏

    該当のディレクトリ・ファイルの存在有無の確認 ❏ なければ作成しそのファイルパスを取得 ❏ ファイルパスから Swift コードを読み込み解析 ❏ 状態に応じて必要な処理を追加(書き込み) ❏ 特定のProtocol への準拠 ❏ 初期化の引数に特定のプロパティを追加 ❏ override 削除 ❏ コードの整形 CommandLine PathKit SourceKitten PathKit … etc. SourceKitten
  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 アーキテクチャで必要なボイラープレートの作成
  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 アーキテクチャで必要なボイラープレートの作成
  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 アーキテクチャで必要なボイラープレートの作成 設計が終わったら すぐに実装が開始できる 😊
  35. Mobility Technologies Co., Ltd. 35 まとめ ❏ 設計から実装開始までの作業は意外と多い ❏ ボイラープレートの作成

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

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

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