「コードを書く量が多すぎる!1ヶ月に240時間も働いてしまった!半分にしたい!」
というわけでメタプロ入門しました。
利用するライブラリの候補としては、SourceKitten
と Sourcery
を検討しましたが、SourceKitten
は構文解析用のライブラリで自作クラスをいっぱい作らなければいけなくて大変なので、メタプロ用には Sourcery
の方を使いました。
しかし、APIが割と分かりにくいので、利用例を随時追加していきます。
Sourcery
https://github.com/krzysztofzablocki/Sourcery
Sourceryで使うメタプロ言語(stencil)
https://github.com/stencilproject/Stencil
API使用例
入力ファイルの型を全て取得する
{{ types.all }}
for文でクラス取得
{% class type in types.classes %}
for文でプロトコル取得
{% protocol type in protocols %}
変数をfor文で取得する
{%% for variable in type.variables %}
type
の部分には、取得したタイプを入れる。
変数名の一文字目を大文字にして、関数生成に使う
{% for variable in type.variables %}
func setup{{ variable.name|upperFirstLetter }}() {
// do something
}
{% endfor %}
(生成例)
func setupMyView() {
// do something
}
変数のジェネリクスの中身を取得して、別の変数の生成に使う
元が Binder<String>
みたいな場合も、中身の型だけ取れる。
{% for variable in type.variables %}
var {{ variable.name }}: Observable<{{ variable.typeName.generic.typeParameters.first.typeName }}> {
return Observable.just("hoge")
}
(生成例)
var formTitle: Observable<String> {
return Observable.just("hoge")
}
テストコード生成
internalのメソッドを拾ってきて、 testHoge~()
というテスト関数のガワを生成してくれるのでちょっと楽ができます。
{% for class in types.classes %}
//
// {{ class.name }}Tests.swift
// TestAppTests
// created by code-generator.
import XCTest
@testable import TestApp
class {{ class.name }}Tests: XCTestCase {
override func setUp() {
super.setUp()
// Put setup code here. This method is called before the invocation of each test method in the class.
}
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown()
}
{% for method in class.methods %}
{% if method.accessLevel == "internal" %}
func test{{ method.name|upperFirstLetter }}() {
}
{% endif %}
{% endfor %}
func testPerformanceExample() {
// This is an example of a performance test case.
self.measure {
// Put the code you want to measure the time of here.
}
}
}
{% endfor %}