April 14, 2019

Kotlin 1.3.30

Kotlin 1.3.30

Este artículo es una traducción del original: https://blog.jetbrains.com/kotlin/2019/04/kotlin-1-3-30-released/

Nos complace anunciar que acabamos de liberar Kotlin 1.3.30, una actualización de herramientas con correcciones para Kotlin 1.3. Las áreas en las que más nos hemos centrado han sido Kotlin/Native, rendimiento de KAPT, así como mejoras en IntelliJ IDEA.

Podéis encontrar la lista completa de cambios en el changelog. Y como siempre, nos gustaría agradecer a los contriyentes externos. ¡Y ahora, echemos un vistazo a los detalles!

Procesado incremental de anotaciones en KAPT

KAPT ahora soporta el procesado incremental de anotaciones de forma experimental. Para probarlo, añadid la siguiente opción a vuestro archivo gradle.properties.

Nótese que la implementación actual, usando cualquier anotación no incremental o un cambio en la compatibilidad binaria de las dependencias (incluyendo modificando declaraciones internal), hará que el procesado de las anotaciones ya no sea incremental.

Todavía está en desarrollo y se mejorará en las próximas versiones, ¡pero os animamos a probarlo y a compartir vuestras experiencias!

KAPT: otras mejoras de rendimiento

Ya en la 1.2.60, introdujimos dos opciones para mejorar el tiempo de compilación. La primera era usar los workers de Gradle:

kapt.use.worker.api=true

y se ha mejorado en esta versión.

La segunda opción introducida en la 1.3.20 llamada Compile Avoidance, permitía evitar el procesado en el caso de que únicamente se hubiesen cambiado los cuerpos de los métodos en las dependencias. Esta opción funciona únicamente cuando se han declarado todas las dependencias KAPT de forma explícita en el classpath del procesado de anotaciones. Para deshabilitar el descubrimiento de la ruta de compilación, y añadir esta opción:

kapt.include.compile.classpath=false

Estamos considerando añadir esta opción por defecto en un futuro no muy lejano, ¡así que nos encantaría que lo probáseis en vuestros proyectos y nos dieseis  vuestra opinión!

Nótese que la versión mínima soportada de gradle es ahora la 4.1. Y para el plugin gradle de android, es la 3.0.

Librería estándar: operaciones para arrays de números sin signo

Desde Kotlin 1.3, podéis usar tipos numéricos sin signo de forma experimental. Esta versión incluye operaciones de tipos sin signo y sus correspondientes arrays que ya estaban disponibles en sus versiones con signo.

fun main() {
    val u1 = 2_147_483_649u
    val u2 = 4_000_000_000u
    println(u1.toDouble())
    println(minOf(u1, u2))

    val array: UIntArray = uintArrayOf(u1, u2)
    println(array.max())
    println(array.all { it > Int.MAX_VALUE.toUInt() })
}

Nótese que ya era posible usar muchas de las operaciones funcionales como filter y map para arrays de tipos sin signo, porque las arrays de los números sin signo, implementan Collection (por ejemplo UIntArray implementa Collection<UInt>). Pero este tipo de operaciones tenían un coste de ejecución mayor, al tener que crear objetos intermedios y potencialmente boxing de los elementos.

Todos los métodos nuevos añadidos, incluyen los tipos de array sin signo como receptores, lo que elimina este coste adicional.

Ahora podéis trabajar con arrays de tipos sin signo y con signo sin miedo del rendimiento que van a tener.

Kotlin/Native

Nos alegra anunciar de que la lista de targets de Kotlin/Native ha crecido. Esta versión incluye soporte para versiones de Windows de 32 bits (mingw_x64). Y además de eso, los usuarios de Windows y macOS, pueden hacer compilación cruzada de Linux x86-64, arm32, así como de Android y Raspberry PI.

Por lo que respecta al compilador, hemos hecho algunos arreglos de comportamiento indefinido cuando se calculaba el resto de una fivisón por 0, que ahora lanza una excepción. También hemos arreglado problemas de alineación para las plataformas de ARM64 y MIPS.

Kotlin/Native en las plataformas de Apple

Para las plataformas de Apple, también hemos preparado varias mejoras. Las excepciones sin manejar en iOS ahora se logean en el crash log de iOS. Y las trazas de las excepciones (en debug), contienen información simbólica en iOS y macOS.

Ahora también se pueden generar frameworks estáticos, usad el parámetro de línea de comandos -Xstatic-framework o el siguiente script de gradle para los proyectos multiplataforma:

kotlin {
    macosX64 {
        binaries {
            framework {
                isStatic = true
            }
        }
    }
}

Cocoapods

Hemos añadido soporte experimental para integrar CocoaPods con un plugin de Gradle dedicado. Convierte un proyecto de Kotlin/Native en una dependencia .podfile que se puede incluir en un Podfile. Esto permite tener la misma experiencia cuando se importa y construye con Xcode, como tendrías con un pod de Swift o de Objective-C. También hemos hecho más fácil usar e importar dependencias de CocoaPods en proyectos de Kotlin/Native. El plugin hace todo lo necesario para importar un framework on un proyecto de Kotlin/Native. Nótese, que ahora se require un proyecto de Xcode para obtener y construir dichas dependencias.

// Apply plugins.
plugins {
    id("org.jetbrains.kotlin.multiplatform") version "1.3.30"
    /// the new plugin for CocoaPods support
    id("org.jetbrains.kotlin.native.cocoapods") version "1.3.30"
}

// CocoaPods requires the podspec to have a version.
version = "1.0"

kotlin {
    cocoapods {
        summary = "a Kotlin/Native module"
        homepage = "homepage"

        pod("AFNetworking", "~> 3.2.0")
    }
}

Ejecutando ./gradlew podspec se genera un archivo .podspec que se puede incluir en un archivo Podfile. Para importar un pod, podéis usar la función pod().

C Interop

Ahora soportamos devolver estructuras desde callbacks de funciones, lo que significa que staticCFunction ahora soporta valores de retorno CValue<T>! Por ejemplo, puedes llamar a una función de C, pasar un puntero de función de C a una función implementada en Kotlin que devuelva una estructura:

*typedef struct * { /*... */} result_value;
*void *functionWithCallback(result_value (*fun_pointer)() );

Además de eso, se han hecho los siguientes cambios:

  • El tipo de C-99 bool se mapea ahora de forma correcta
  • Las cadenas de C en UTF-32 se mapean a la clase String de Kotlin
  • Se han incluído intrínsecas del compilador de C en el paquete platform.builtin
  • Se ha dejado de usar libffi
  • Módulos de C
  • Se soportan módulos de Clang en la interoperabilidad de Objective-C
  • Los IDE soportan ahora los archivos de definición (.def) de interoperabilidad de C

Soporte de IDE de Kotlin/Native

Nos alegra anunciar los resultados del trabajo que hemos estado haciendo en nuestros IDEs en relación a Kotlin/Native.

Además de IntelliJ IDEA, vamos a ofrecer un plugin de Kotlin/Native para CLion 2019.1, y AppCode 2019.1. También vamos a soportar en todos nuestros IDEs, los archivos de interoperabilidad (.def), a pesar de que de momento no tienen completado de código.

Para CLion y AppCode, también hemos añadido navegación desde las trazas de las excepciones al código fuente así como mejoras en el depurador.

Soporte de IntelliJ IDEA

Mejoras de depuración

Hemos trabajado duro en hacer que la depuración de las corrutinas sea más fácil. Cuando depuras código de corrutinas, ahora veréis un Async stack trace mostrando las variables que se han almacenado en tiempo de suspensión. Echemos un vistazo a un pequeño ejemplo:

Cuando paramos en un punto de ruptura dentro de una función o lambda (en este ejemplo, en la línea 13), Async stack trace muestra adicionalmente el estado de las variables en el último punto de la suspensión (línea 12). Podéis mirar en todas las trazas de ejecución a partir del último punto de suspensión en la corrutina actual (líneas 12 y 4) y comprobar el valor almacenado de las variables:

Lo que debería ayudaros a entender cómo se ha llegado al punto actual de ejecución.

Cuando depuréis código Kotlin, ahora podéis elegir el modo "Kotlin" para observar los valores de las variables. Tras hacer click en el iono de Kotlin, veréis las variables con sus nombres de Kotlin, no con los nombres auxiliares de la JVM como anteriormente:

fun main() {
    1.foo()
}

fun Int.foo() {
    with("ab") {
        println(this + this@foo)  // breakpoint
    }
}

Nótese que siempre podéis añadir variables que falten mediante el uso de watches, y mezclar tant olas ventanas de "variables" como de "watches" en el screenshot o mantenerlas por separado, a vuestro gusto.

Modo interactivo para los archivos de scratch

Como y sabréis, en Kotlin se pueden hacer pequeños experimentos con vuestra base de código usando los scratch files. Ahora podéis usar el modo interactivo para mostrar los resultados al momento (tras un timeout especificado), sin tener que volver a ejecutarlo de forma explícita:

Otras cosas chulas

¿Echáis un vistazo de vez en cuando a la lista de TODOs de vuestro proyecto? IntelliJ ahora marca correctamente los comentarios TODO multilínea y los muestra en la lista:

En esta versión hemos añadido algunas inspecciones útiles como una corrección para introducir un alias de import para el nombre de clase importado, o un aviso al usar el método de interfaz de Java 8 forEach en vez del de la librería estándar de Kotlin.

Actualización del plugin de Eclipse

La nueva versión 0.8.14 del IDE de Eclipse trae: soporte para el compilador de Kotlin 1.3.30, diversas correcciones de errores y mejoras de estabilidad. Esta actualización también introduce soporte experimental para los proyectos de Gradle. Ahora podéis importar vuestros proyectis con Eclipse Buildship y podréis encontrarlo en el workspace de Eclipse con la configuración correcta del plugin de Kotlin.

Podéis instalar la integración experimental de Gradle mediante el sitio de actualización: https://dl.bintray.com/jetbrains/kotlin/eclipse-plugin/last/.
Para ello, abrid el diálogo Install new software del menú de ayuda de eclipse. Etnonces introducid el sitio de actualización y seleccionad Kotlin-gradle:

La nueva integración de Gradle funciona también en la suit de Spring Tools. Ya no estáis obligados a usar Maven cuando querráis desarrollar una aplicación de Spring en Kotlin.

Especificar targets de bytecode de la JVM 9 - 12

Si ejecutáis el código bajo las versiones 9, 10, 11 o 12, ahora podéis poner el correspondiente jvmTarget. Esta opción afectará a la versión de los archivos .class generados, y el bytecode resultante no se ejecutará en versiones inferiores de la JVM. Nótese que ahora mismo no se añaden optimizaciones de bytecode o características más allá de las ya incluídas en las versiones anteriores, pero eso es algo que cambiará en un futuro.

Cómo actualizar

Como siempre, podéis probar Kotlin online en play.kotl.in.

Como de costumbre, si os encontráis con cualquier problema con la nueva versión, podéis pedir ayuda en los foros, en Slack (invitación aquí, o informar sobre incidencias en nuestro tracker.

¡A Kotlinear!

Contribuyentes externos

Nos gustaría hacer un agradecimiento especial a nuestros colegas de Google, ¡por su trabajo soportando la compilación incremental en KAPT!

Nos gustaría también agradecer a los contribytentes de la comunidad de esta versión; agradecemos mucho vuestro trabajo. En particular:

  • Toshiaki Kameyama
  • Mads Ager
  • Ivan Gavrilovic
  • Ting-Yuan Huang
  • Dereck Bridie
  • denisgaebler
  • kenji tomita
  • Bernhard Posselt
  • Wil
  • Burak Eregar
  • Marcin Moskala
  • Felix Guo
  • shiraji
  • Tor Norbye
  • Yaroslav Ulanovych
  • goodsauce
  • hisaaki.sioiri
  • Pavel Nikitin
  • Mark Punzalan
  • Kevin Peek
  • Jim S
  • Timo Obereder