2016-02-25 3 views
9

Недавно я преобразовал большую часть своего проекта в kotlin. Теперь я сталкиваюсь с несколькими необычными ошибками, которые, как представляется, связаны с библиотеками аннотаций. Излишне говорить, что этого не произошло на Java.Обработка аннотации Kotlin игнорирует элементы с похожими именами

Я опишу случаи - один в кинжале и один в Butterknife.

1. При использовании 2 @Provides методов в различных моделей с одноименными идентификаторами. Например, в файле «FooProvider.kt», имеющий метод «provideFooOrBar»

@Module 
class FooProvider(private val view: FooActivity) { 
    ... 
    @Provides @FooScope fun provideView() = view 
    @Provides @FooScope fun provideFooOrBar() = Foo() 
} 

И имея другой файл «BarProvider.kt» с тем же именем метода

@Module 
class BarProvider(private val view: BarActivity) { 
    ... 
    @Provides @BarScope fun provideView() = view 
    @Provides @BarScope fun provideFooOrBar() = Bar() 
} 

В этом случае Dagger терпит неудачу для создания некоторых заводских библиотек, и я получаю следующее сообщение об ошибке компиляции: Error:(27, 32) error: cannot find symbol class FooProvider_ProvideFooOrBarFactory

пример проекта воспроизведения проблемы можно найти на https://github.com/maxandron/DaggerIssue325

2. Это проблема при использовании Butterknife. При наличии двух аннотированных переменных @Bind в двух разных классах - один из них просто не инициализируется во время выполнения без какой-либо ошибки компиляции!

Например, если у меня есть:

class FooActivity { 
    @Bind(R.id.foo) lateinit var mFoo: View 
} 
class NotFooActivity { 
    @Bind(R.id.not_foo) lateinit var mFoo: View 
} 

Тогда один из них (? Или оба) просто не будет инициализировать без каких-либо ошибок. Причинение исключения kotlin.UninitializedPropertyAccessException: lateinit property mFoo has not been initialized, которое будет выбрано при доступе к полю.

Это что-то я делаю неправильно в настройке Kotlin или это ошибка kotlin?

Спасибо заранее! Ron

+0

Эти два вопроса выглядят не связаны со мной, пожалуйста, не спрашивайте два разных вопроса в одном SO пост в следующий раз –

+0

я отправил их в тот же вопрос, потому что это похоже. Я не думаю, что это ошибка кинжала или масляного ножа - я думаю, что это ошибка kotlin. Я не пытаюсь найти решения для ошибки - я их знаю, я хочу понять причину. – maxandron

+0

Они, вероятно, две разные проблемы. Один для методов, а другой для того, где вы разместили аннотацию на свойстве. Читайте об объектах целевого использования Anotation Use-Site и посмотрите, поможет ли это решить 2-й https://kotlinlang.org/docs/reference/annotations.html#annotation-use-site-targets, а также, возможно, сделать JvmField доступным для чего butterknife хочет https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html#instance-fields –

ответ

1

Это оказалось ошибкой с kapt. I posted an issue на отслежке ошибок Kotlin, и проблема теперь отмечена как фиксированная.

This solution was merged

должны быть решены в Котлин версии 1.0.2

0

Чтобы ответить на вопрос kotlin.UninitializedPropertyAccessException: lateinit, я столкнулся с тем же самым в моем project. То, что я сделал, «решило проблему» для меня, было удалить Butterknife из класса-нарушителя, в этом случае это был просто viewHolder для моего нового расширяемого RecyclerView, а затем снова запустить приложение.

Запуск приложения, после переключения все мои @Bind(R.id.my_view_id) к «старой школе» findViewById(R.id.my_view_id) as MyViewType работал, но впоследствии после этого я переключился тот же класс назад к Butterknife и UninitializedPropertyAccessException ушел, и это, кажется, что это не будет вернитесь, если что-то в классе не изменится, вам придется снова повторить этот процесс.

Мое подозрение здесь в том, что это имеет какое-то отношение к Kotlin, не поддерживающему инкрементную компиляцию, и каким-то образом путем изменения автоматически сгенерированного кода он был вынужден перекомпилировать. Но я мог бы быть здесь, просто подумал, что поделюсь своим опытом.

+0

Спасибо за ваши усилия, очевидно, что у меня всегда есть возможность отключать библиотеки, которые я использовал раньше. Но я не хочу. Порция использования Kotlin заключается в том, что она полностью совместима с Java. В любом случае, после изучения и публикации ошибки на трекере. Это определенно ошибка с kapt. Я буду обновлять здесь, когда он будет исправлен. Прямо сейчас я переключаю butterknife на плагин 'kotlin android extensions' – maxandron

3

У меня возникла эта проблема, поэтому я начал расследование, и это вызвано тем, что Kapt is only checking the method name при их сравнении and they are added in a set, при этом дубликаты не допускаются. То же самое происходит для аннотированных полей, поэтому в настоящее время вы можете иметь одно имя метода/поля для каждой аннотации.

Я добавил имя класса в метод equals, и аннотации были правильно обработаны сейчас, но тесты сломались, и я не знаю, как они работают, поэтому я надеюсь, что кто-то знает, как это исправить.

+0

Nice find! Я вижу здесь, что поля также доступны только [проверено по имени] (https://github.com/JetBrains/kotlin/blob/master/libraries/tools/kotlin-annotation-processing/src/main/kotlin/org/jetbrains/ kotlin/аннотация/AnnotationProcessorWrapper.kt # L49), который объясняет butterknife. В любом случае, они находятся вдали от проблемы и фиксируют ее - я отправлю сюда, когда это будет разрешено. – maxandron

+0

Также означает, что я был прав, чтобы опубликовать эти две проблемы в тех же вопросах (и быть правильным всегда хорошо :)) – maxandron

+1

Я только что нашел запрос на растяжение, который уже открыт https://github.com/JetBrains/kotlin/pull/822 – inorichi

Смежные вопросы