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

"Кодогенерация без kapt", Михаил Розумянский, Joom

5d08ba0cd07942f2ddbf82e5b21ba5e7?s=47 FunCorp
August 03, 2019

"Кодогенерация без kapt", Михаил Розумянский, Joom

5d08ba0cd07942f2ddbf82e5b21ba5e7?s=128

FunCorp

August 03, 2019
Tweet

Transcript

  1. Кодогенерация без kapt Кодогенерация без kapt Михаил Розумянский, Joom Михаил

    Розумянский, Joom 1
  2. Начало Начало 2

  3. Начало Начало 2014 год 2

  4. Начало Начало 2014 год Новый проект 2

  5. Начало Начало 2014 год Новый проект Kotlin M8 2

  6. Выбор DI Выбор DI 3

  7. Выбор DI Выбор DI Есть два стула Есть два стула

    3
  8. Lightsaber Lightsaber 4

  9. Lightsaber Lightsaber Вдохновлён Guice 4

  10. Lightsaber Lightsaber Вдохновлён Guice Compile time 4

  11. Lightsaber Lightsaber Вдохновлён Guice Compile time Меняет байткод 4

  12. Lightsaber Lightsaber Компонент Компонент 5

  13. Lightsaber Lightsaber Компонент Компонент @Module private class MainModule { }

    5
  14. Lightsaber Lightsaber Компонент Компонент @Module private class MainModule { @Provides

    private fun provideMainRepository(impl: MainRepositoryImpl): MainRepository = impl } 5
  15. Lightsaber Lightsaber Компонент Компонент @Component private class MainComponent { @Module

    private class MainModule { @Provides private fun provideMainRepository(impl: MainRepositoryImpl): MainRepository = impl } } 5
  16. Lightsaber Lightsaber Компонент Компонент @Component private class MainComponent { @Provides

    private fun provideMainModule() = MainModule() @Module private class MainModule { @Provides private fun provideMainRepository(impl: MainRepositoryImpl): MainRepository = impl } } 5
  17. Lightsaber Lightsaber Использование Использование class MainActivity : BaseActivity() { override

    fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) } } 6
  18. Lightsaber Lightsaber Использование Использование @Inject private val repository: MainRepository =

    notNull() class MainActivity : BaseActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) } } 6
  19. Lightsaber Lightsaber Использование Использование @Inject private val repository: MainRepository =

    notNull() val injector = lightsaber.createInjector(MainComponent()) class MainActivity : BaseActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) } } 6
  20. Lightsaber Lightsaber Использование Использование @Inject private val repository: MainRepository =

    notNull() val injector = lightsaber.createInjector(MainComponent()) injector.injectMembers(this) class MainActivity : BaseActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) } } 6
  21. Lightsaber Lightsaber Изнутри Изнутри 7

  22. Lightsaber Lightsaber Изнутри Изнутри ObjectWeb ASM 7

  23. Lightsaber Lightsaber Изнутри Изнутри ObjectWeb ASM Transform API 7

  24. ASM ASM 8

  25. Transform API Transform API 9

  26. 10

  27. kapt kapt Kotlin ❤ APT 11

  28. kapt kapt Возможные реализации Возможные реализации 12

  29. kapt kapt Возможные реализации Возможные реализации Своя реализация JSR 269

    kapt kapt2 2 12
  30. kapt kapt Возможные реализации Возможные реализации Своя реализация JSR 269

    kapt kapt2 2 Компиляция в .java стабы kapt kapt3 3 12
  31. kapt kapt Возможные реализации Возможные реализации Своя реализация JSR 269

    kapt kapt2 2 Компиляция в .java стабы kapt kapt3 3 Компиляция в .class стабы kapt kapt1 1 12
  32. kapt kapt Изнутри Изнутри 13

  33. ¯\_( ツ)_/¯ ¯\_( ツ)_/¯ 14

  34. Sento Sento 15

  35. Sento Sento Как ButterKnife 15

  36. Sento Sento Как ButterKnife Только без APT 15

  37. Sento Sento Как ButterKnife Только без APT Больше не используется

    15
  38. Sento Sento Использование Использование class MainActivity : BaseActivity() { override

    fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.main_activity) } } 16
  39. Sento Sento Использование Использование @Bind(R.id.label) private val label: TextView =

    notNull() class MainActivity : BaseActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.main_activity) } } 16
  40. Sento Sento Использование Использование @Bind(R.id.label) private val label: TextView =

    notNull() @OnTextChanged(R.id.input) private fun onInputChanged(text: CharSequence) { label.text = getValidationMessage(text) } class MainActivity : BaseActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.main_activity) } } 16
  41. Sento Sento Использование Использование @Bind(R.id.label) private val label: TextView =

    notNull() Sento.bind(this, this) @OnTextChanged(R.id.input) private fun onInputChanged(text: CharSequence) { label.text = getValidationMessage(text) } class MainActivity : BaseActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.main_activity) } } 16
  42. Спустя некоторое время Спустя некоторое время 17

  43. DataBinding DataBinding Ожидание Ожидание 18

  44. DataBinding DataBinding Ожидание Ожидание Удобство 18

  45. DataBinding DataBinding Ожидание Ожидание Удобство Надёжность 18

  46. DataBinding DataBinding Ожидание Ожидание Удобство Надёжность Стабильность 18

  47. 19

  48. 20

  49. VectorDrawableCompat VectorDrawableCompat ViewDataBinding.java ViewDataBinding.java protected static Drawable getDrawableFromResource(View view, int

    resourceId) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { return view.getContext().getDrawable(resourceId); } else { return view.getResources().getDrawable(resourceId); } } 21
  50. 22

  51. DataBindingCompat DataBindingCompat ViewDataBinding.java ViewDataBinding.java protected static Drawable getDrawableFromResource(View view, int

    resourceId) { return AppCompatResources.getDrawable(view.getContext(), resourceId)); } 23
  52. Smuggler Smuggler 24

  53. Smuggler Smuggler Генерация Parcelable 24

  54. Smuggler Smuggler Генерация Parcelable Для Kotlin 24

  55. Smuggler Smuggler Генерация Parcelable Для Kotlin Опять без APT 24

  56. Smuggler Smuggler Использование Использование AutoParcelable sealed class Selection : {

    data class Item(val id: String) : Selection() object None : Selection() } 25
  57. Много схожего кода Много схожего кода 26

  58. Grip Grip 27

  59. Grip Grip Часть Lightsaber 27

  60. Grip Grip Часть Lightsaber DOM для классов 27

  61. Grip Grip Часть Lightsaber DOM для классов Поисковые запросы 27

  62. Grip Grip Использование Использование 28

  63. Grip Grip Использование Использование grip 28

  64. Grip Grip Использование Использование grip select methods 28

  65. Grip Grip Использование Использование grip select methods from inputs 28

  66. Grip Grip Использование Использование grip select methods from inputs where

    ( ) 28
  67. Grip Grip Использование Использование grip select methods from inputs where

    (isConstructor() and annotatedWith(Types.INJECT_TYPE)) 28
  68. Grip Grip Использование Использование или или grip select methods from

    inputs where (isConstructor() and annotatedWith(Types.INJECT_TYPE)) 28
  69. Grip Grip Использование Использование или или grip select methods from

    inputs where (isConstructor() and annotatedWith(Types.INJECT_TYPE)) grip 28
  70. Grip Grip Использование Использование или или grip select methods from

    inputs where (isConstructor() and annotatedWith(Types.INJECT_TYPE)) grip .select(methods) 28
  71. Grip Grip Использование Использование или или grip select methods from

    inputs where (isConstructor() and annotatedWith(Types.INJECT_TYPE)) grip .select(methods) .from(inputs) 28
  72. Grip Grip Использование Использование или или grip select methods from

    inputs where (isConstructor() and annotatedWith(Types.INJECT_TYPE)) grip .select(methods) .from(inputs) .where( ) 28
  73. Grip Grip Использование Использование или или grip select methods from

    inputs where (isConstructor() and annotatedWith(Types.INJECT_TYPE)) grip .select(methods) .from(inputs) .where(isConstructor() and annotatedWith(Types.INJECT_TYPE)) 28
  74. Paranoid Paranoid 29

  75. Paranoid Paranoid Обфускатор строк 29

  76. Paranoid Paranoid Обфускатор строк Демо проект 29

  77. Paranoid Paranoid Использование Использование @Obfuscate object TopSecretStrings { const val

    TOP_SECRET_STRING = "42" } 30
  78. А тем временем А тем временем 31

  79. kapt2 kapt2 32

  80. kapt2 kapt2 (спешит на помощь) (спешит на помощь) 32

  81. kapt2 kapt2 Что случилось? Что случилось? 33

  82. kapt2 kapt2 Что случилось? Что случилось? Обёртки для PSI 33

  83. kapt2 kapt2 Что случилось? Что случилось? Обёртки для PSI Медленно

    и тяжело 33
  84. kapt2 kapt2 Что случилось? Что случилось? Обёртки для PSI Медленно

    и тяжело Что с Java? 33
  85. kapt3 kapt3 Как kapt1, но лучше 34

  86. kapt3 kapt3 Изнутри Изнутри 35

  87. 36

  88. Colonist Colonist 37

  89. Colonist Colonist Регистрация плагинов 37

  90. Colonist Colonist Регистрация плагинов Compile time 37

  91. Colonist Colonist Регистрация плагинов Compile time Слабая связность 37

  92. Colonist Colonist 38

  93. Colonist Colonist Пример API Пример API 39

  94. Colonist Colonist Пример API Пример API annotation class FeatureColony 39

  95. Colonist Colonist Пример API Пример API @Colony annotation class FeatureColony

    39
  96. Colonist Colonist Пример API Пример API @Colony @SelectSettlersBySuperType(Feature::class) annotation class

    FeatureColony 39
  97. Colonist Colonist Пример API Пример API @Colony @SelectSettlersBySuperType(Feature::class) @ProduceSettlersAsClasses annotation

    class FeatureColony 39
  98. Colonist Colonist Пример API Пример API @Colony @SelectSettlersBySuperType(Feature::class) @ProduceSettlersAsClasses @AcceptSettlersViaCallback

    annotation class FeatureColony 39
  99. Colonist Colonist Использование Использование 40

  100. Colonist Colonist Использование Использование class MyFeature : Feature { /*

    ... */ } 40
  101. Colonist Colonist Использование Использование class MyFeature : Feature { /*

    ... */ } private class FeatureManager { } 40
  102. Colonist Colonist Использование Использование class MyFeature : Feature { /*

    ... */ } @FeatureColony private class FeatureManager { } 40
  103. Colonist Colonist Использование Использование class MyFeature : Feature { /*

    ... */ } @FeatureColony private class FeatureManager { @OnAcceptSettler(colonyAnnotation = FeatureColony::class) fun onAcceptFeature(featureClass: Class<out Feature>) { // ... } } 40
  104. Colonist Colonist Использование Использование class MyFeature : Feature { /*

    ... */ } @FeatureColony private class FeatureManager { init { Colonist.settle(this) } @OnAcceptSettler(colonyAnnotation = FeatureColony::class) fun onAcceptFeature(featureClass: Class<out Feature>) { // ... } } 40
  105. Leak Detector Leak Detector Проверяет, что Проверяет, что 41

  106. Leak Detector Leak Detector Проверяет, что Проверяет, что Closeable объекты

    41
  107. Leak Detector Leak Detector Проверяет, что Проверяет, что Closeable объекты

    были закрыты 41
  108. Leak Detector Leak Detector Проверяет, что Проверяет, что Closeable объекты

    были закрыты до сборки мусора 41
  109. Leak Detector Leak Detector Изнутри Изнутри 42

  110. Прощай, kapt Прощай, kapt Предпосылки Предпосылки 43

  111. Прощай, kapt Прощай, kapt Предпосылки Предпосылки Только DataBinding 43

  112. Прощай, kapt Прощай, kapt Предпосылки Предпосылки Только DataBinding BR не

    используется 43
  113. Прощай, kapt Прощай, kapt Предпосылки Предпосылки Только DataBinding BR не

    используется Медленная сборка 43
  114. DataBinding DataBinding Изнутри Изнутри 44

  115. DataBinding DataBinding Изнутри Изнутри В коде используются *Binding 44

  116. DataBinding DataBinding Изнутри Изнутри В коде используются *Binding *Binding.java генерируются

    до компиляции 44
  117. DataBinding DataBinding Изнутри Изнутри В коде используются *Binding *Binding.java генерируются

    до компиляции *BindingImpl.java генерируются APT А также BR и DataBindingComponent 44
  118. DataBinding DataBinding Идея Идея 45

  119. DataBinding DataBinding Идея Идея Отключить процессор DataBinding 45

  120. DataBinding DataBinding Идея Идея Отключить процессор DataBinding Собрать проект 45

  121. DataBinding DataBinding Идея Идея Отключить процессор DataBinding Собрать проект Запустить

    процессор DataBinding 45
  122. DataBinding DataBinding Итоги Итоги 46

  123. DataBinding DataBinding Итоги Итоги -20% от времени сборки 46

  124. DataBinding DataBinding Итоги Итоги -20% от времени сборки Нет неожиданных

    деградаций 46
  125. DataBinding DataBinding Итоги Итоги -20% от времени сборки Нет неожиданных

    деградаций Решение не универсальное 46
  126. Что дальше? Что дальше? 47

  127. Compose вытеснит DataBinding И многое изменит 48

  128. kapt не будет first-class citizen А Kotlin будет 49

  129. Kotlin-плагины заменят Transform API И, возможно, kapt 50

  130. Планы Планы 51

  131. Планы Планы Объединение трансформаций 51

  132. Планы Планы Объединение трансформаций Сетевой клиент 51

  133. Планы Планы Объединение трансформаций Парсинг диплинков Сетевой клиент 51

  134. Планы Планы Объединение трансформаций Парсинг диплинков Сетевой клиент Патчи в

    проекте 51
  135. Планы Планы Объединение трансформаций Парсинг диплинков Отправка аналитики Сетевой клиент

    Патчи в проекте 51
  136. Полезные ссылки Полезные ссылки ASM Transform API kapt: Annotation Processing

    for Kotlin Implement Annotation Processing API (JSR 269) natively in Kotlin Pushing the limits of Kotlin annotation processing https://asm.ow2.io http://google.github.io/android-gradle-dsl/javadoc/current https://blog.jetbrains.com/kotlin/2015/05/kapt-annotation-processing-for-kotlin https://youtrack.jetbrains.com/issue/KT-13499 https://medium.com/@workingkills/pushing-the-limits-of-kotlin-annotation-processing- 8611027b6711 52
  137. Не очень полезные ссылки Не очень полезные ссылки Презентация —

    Lightsaber — Sento — Smuggler — DataBindingCompat — Grip — Paranoid — Colonist — kapt bugs — https://michaelrocks.github.io/codegen-without-kapt https://github.com/MichaelRocks/lightsaber https://github.com/nsk-mironov/sento https://github.com/joomcode/smuggler https://github.com/MichaelRocks/DataBindingCompat https://github.com/MichaelRocks/grip https://github.com/MichaelRocks/paranoid https://github.com/MichaelRocks/colonist https://github.com/nsk-mironov/kotlin-kapt-bugs/branches/all 53
  138. 54

  139. Спасибо за внимание! Спасибо за внимание! MichaelRocks @michaelrocks 55

  140. 56