2016-02-25 21 views
9

Recentemente ho convertito la maggior parte del mio progetto in kotlin. Ora ho riscontrato diversi errori insoliti che sembrano tutti correlati alle librerie di annotazioni. Inutile dire che non è successo in Java.L'elaborazione dell'annotazione di Kotlin ignora elementi con nomi simili

Descriverò i casi: uno in Dagger e uno in Butterknife.

1. Se si dispone di 2 metodi @Provides in diversi modelli con lo stesso nome. Per esempio nel file "FooProvider.kt" avere un metodo "provideFooOrBar"

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

E avere un altro file "BarProvider.kt" con lo stesso nome del metodo

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

In questo caso, Pugnale fallisce per generare alcune librerie di fabbrica e ottengo il seguente errore di compilazione: Error:(27, 32) error: cannot find symbol class FooProvider_ProvideFooOrBarFactory

un progetto di esempio che riproduce il problema può essere trovato alla https://github.com/maxandron/DaggerIssue325

2. Questo è un problema quando si utilizza Butterknife. Quando si hanno due variabili annotate @Bind in due classi diverse - Una di queste non riesce a inizializzarsi in fase di esecuzione senza alcun errore di compilazione!

Per esempio se ho:

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

Poi uno di loro (? O entrambi) sarà solo riuscire inizializzare senza alcun errore. Causando un'eccezione kotlin.UninitializedPropertyAccessException: lateinit property mFoo has not been initialized da lanciare quando si accede al campo.


È qualcosa che sto facendo male nella configurazione di Kotlin o è un bug kotlin?

Grazie in anticipo! Ron

+0

Queste due domande sembrano estranei a me, per favore non chiedere due domande differenti in un singolo SO posto la prossima volta –

+0

li ho postato nel stessa domanda perché il do sembra correlato. Non penso che sia un pugnale o un insetto butterknife - penso che sia un insetto kotlin. Non sto cercando di trovare soluzioni per l'errore - li conosco, voglio capire la causa – maxandron

+0

Probabilmente sono due problemi diversi. Uno per i metodi e un altro per cui hai posizionato l'annotazione su una proprietà. Leggi l'annotazione Uso-Obiettivi del sito e verifica se questo aiuta a risolvere il secondo https://kotlinlang.org/docs/reference/annotations.html#annotation-use-site-targets insieme a renderlo un JvmField che doffing su cosa butterknife vuole https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html#instance-fields –

risposta

0

Quindi per rispondere in qualche modo al problema kotlin.UninitializedPropertyAccessException: lateinit, stavo correndo esattamente nella stessa cosa nel mio project. Quello che ho fatto per risolvere il problema è stato rimuovere Butterknife dalla classe che aveva commesso l'errore, in questo caso era solo una viewHolder per il mio nuovo Espansione di RecyclerView, quindi eseguire nuovamente l'app.

esecuzione l'applicazione, dopo il passaggio tutto il mio @Bind(R.id.my_view_id) alla "vecchia scuola" findViewById(R.id.my_view_id) as MyViewType funzionato, ma poi successivamente dopo ho acceso la stessa classe torna al Butterknife e la UninitializedPropertyAccessException è andato via, e sembra che non lo farà torna indietro a meno che qualcosa nella classe non cambi, quindi dovrai ripetere di nuovo questa procedura.

Il mio sospetto è che questo abbia qualcosa a che fare con Kotlin che non supporta la compilazione incrementale, e in qualche modo modificando il codice generato automaticamente che è stato costretto a ricompilare. Ma potrei essere lontano da qui, ho pensato di condividere la mia esperienza.

+0

Grazie per il tuo impegno, ovviamente ho sempre la possibilità di spegnere le librerie che usavo prima. Ma io non voglio. Il vantaggio di usare Kotlin è che sia completamente interoperabile con Java. In ogni caso, dopo averlo fatto, e aver postato un bug sul tracker. È sicuramente un bug con kapt. Aggiornerò qui quando sarà corretto. In questo momento ho acceso Butterknife al plugin 'kotlin android extensions' – maxandron

3

Stavo avendo questo problema, così ho iniziato a indagare ed è causato dal fatto che Kapt is only checking the method name durante il confronto, and they are added in a set, quindi duplicati non sono ammessi. Lo stesso accade per i campi annotati, quindi attualmente puoi avere un metodo/nome di campo per annotazione.

Ho aggiunto il nome classe al metodo equals e le annotazioni sono state gestite correttamente ora, ma i test si sono interrotti e non so come funzionano, quindi spero che qualcuno sappia come risolvere il problema.

+0

Bella scoperta! Vedo qui che i campi sono anche solo [controllati per nome] (https://github.com/JetBrains/kotlin/blob/master/libraries/tools/kotlin-annotation-processing/src/main/kotlin/org/jetbrains/ kotlin/annotation/AnnotationProcessorWrapper.kt # L49), che spiega Butterknife. In ogni caso, sono lontani dal problema e risolverlo - posterò qui quando è risolto – maxandron

+0

Significa anche che avevo ragione a postare questi due problemi nelle stesse domande (E avere ragione è sempre buono :)) – maxandron

+1

Ho appena trovato una richiesta pull già aperta https://github.com/JetBrains/kotlin/pull/822 – inorichi

Problemi correlati