При разработке новой IDE платформы мы активно используем паттер Type-safe builders. Данный паттер подразумевает повсеместное использование lambda-выражений, особенно в UI коде. При этом нам постоянно приходится иметь дело с замыканиями во вложенных lambda-выражений. К сожалению, данные замыкания не всегда корректны. Рассмотрим следующий пример:
// should be called only from UI thread
val UIContext.theme(): Theme
get() = /*some implementation*/
fun UIContext.view() {
button("show theme", callback = {
showMessage(theme.name)
})
}
view
- некоторая функция, отвечающая за отрисовку кнопки "show theme", вызывающаяся на UI Thread.
callback
- ламбда, вызывающаяся при нажатии на кнопку на второстепенном потоке.
Ошибка в данном случае заключается в том, что лямбда переданная в качестве значения в callback неявно замкнулась на this
параметр функции view
, из-за чего произошло обращение к property theme не с UI потока. Такое обращение может привести либо к ошибки во время исполнения, либо к гонке по данным.
Корректная версия функции view выглядит следующим образом:
// should be called only from UI thread
val UIContext.theme(): Theme
get() = /*some implementation*/
fun UIContext.view() {
val name = theme.name
button("show theme", callback = {
showMessage(name)
})
}
Цель данный стажировки - разработка инспекции для поиска ошибок, связанных с некорректными замыканиями, возникающих при написании плагинов для новой IDE платформы.
Требование:
Плюсом будет: