Publication de Kotlin 1.4.20

Read this post in other languages:

Kotlin 1.4.20 est disponibles avec de nouvelles fonctionnalités expérimentales. La prise en compte des retours d’expérience de la communauté est l’un des principes fondamentaux de l’équipe Kotlin et nous avons besoin de votre avis sur les prototypes de ces nouvelles fonctionnalités. Essayez-les et faites vos commentaires dans Slack (obtenez une invitation ici) ou via YouTrack.

Publication de Kotlin 1.4.20

Voici ses principales nouveautés :

  • Prise en charge de nouvelles fonctionnalités de la JVM, comme la concaténation de chaîne via invokedynamic.
  • Amélioration des performances et de la gestion des exceptions pour les projets KMM.
  • Extensions pour JDK Path : Path("dir") / "file.txt".

Nous avons également apporté de nombreux correctifs et améliorations aux fonctionnalités existantes, y compris celles qui ont été ajoutées dans la version 1.4.0. Donc si vous aviez rencontré des problèmes avec l’une de ces fonctionnalités, c’est le moment de retenter l’expérience.

Pour en savoir plus sur les fonctionnalités de Kotlin 1.4.20, lisez ce qui suit. Vous pouvez aussi consulter une présentation de cette nouvelle version sur la page Nouveautés de Kotlin 1.4.20 dans la documentation Kotlin. Vous trouverez la liste complète des modifications dans le journal des modifications.

Comme toujours, nous tenons à remercier les contributeurs externes qui nous ont apporté leur aide.

Et maintenant plongeons-nous dans les détails !

Kotlin/JVM

En ce qui concerne la JVM, nous avons ajouté la nouvelle cible JVM 15 et nous sommes principalement concentrés sur l’amélioration des fonctionnalités existantes et des performances, ainsi que sur la correction des bugs.

Concaténation de chaînes avec invokedynamic

Depuis Java 9, la concaténation de chaînes sur la JVM se fait par l’appel d’une méthode dynamique (l’instruction invokedynamic dans le bytecode). Cela fonctionne plus rapidement, réduit la consommation de mémoire par rapport à la précédente implémentation et laisse de la place pour la réalisation de futures optimisations sans modification du bytecode.

Nous avons commencé à implémenter ce mécanisme dans Kotlin pour améliorer les performances et il est à présent capable de compiler des concaténations de chaînes dans des appels dynamiques sur des cibles JVM 9+.

Cette fonctionnalité est actuellement expérimentale et s’applique aux cas suivants :

  • String.plus dans l’opérateur (a + b), formes explicites (a.plus(b)) et de référence ((a::plus)(b)).
  • toString pour les classes de données et inline.
  • Modèles de chaînes, à l’exception de ceux qui ont un seul argument non-constant (voir KT-42457).

Pour activer la concaténation de chaîne invokedynamic, ajoutez l’option de compilateur -Xstring-concat avec l’une des valeurs suivantes :

  • indy-with-constants pour effectuer une concaténation invokedynamic sur des chaînes avec StringConcatFactory.makeConcatWithConstants() (il est prévu que cela soit l’option par défaut pour les cibles JVM 9+ en 1.5).
  • indy pour lancer une concaténation invokedynamic sur des chaînes avec StringConcatFactory.makeConcat().
  • inline pour revenir à la concaténation classique via StringBuilder.append().

Kotlin/JS

Kotlin/JS poursuit son évolution rapide et cette version apporte de nombreuses améliorations, parmi lesquelles de nouveaux modèles pour son assistant de projet et un DSL amélioré pour renforcer le contrôle de la configuration de projet. Le nouveau compilateur IR est aussi doté d’un tout nouveau moyen de compiler des projets avec erreurs.

Modifications de Gradle DSL

Le DSL Kotlin/JS Gradle a bénéficié de plusieurs mises à jour qui simplifient la configuration et la personnalisation du projet, notamment des ajustements de la configuration du pack web, des modifications du fichier package.json généré automatiquement et un contrôle amélioré des dépendances transitives.

Un point unique pour la configuration de webpack

Kotlin 1.4.20 inaugure un nouveau bloc de configuration pour la cible browser appelé commonWebpackConfig. Dans ce bloc, vous pouvez ajuster des paramètres communs à partir d’un seul et même point au lieu de dupliquer les configurations pour webpackTask, runTask et testTask.

Pour activer la prise en charge de CSS par défaut pour l’ensemble des trois tâches, il vous suffit d’inclure le snippet suivant dans le build.gradle(.kts) de votre projet :

Personnalisation de package.json depuis Gradle

Le fichier package.json définit généralement le comportement d’un projet JavaScript, en identifiant les scripts pouvant être exécutés, les dépendances, etc. Il est généré automatiquement pour les projets Kotlin/JS pendant la période de build. Le contenu du package.json variant d’un cas à l’autre, nous avons reçu de nombreuses demandes pour faciliter la personnalisation de ce fichier.

À compter de Kotlin 1.4.20, vous pouvez ajouter des entrées au fichier du projet package.json à partir du script de build Gradle. Pour ajouter des champs personnalisés à votre package.json, utilisez la fonction customField dans le bloc packageJson de la compilation :

Lorsque vous générez le projet, cela ajoute le bloc suivant au fichier de configuration build/js/packages/projectName/package.json :

"hello": {
  "one": 1,
  "two": 2
}

Que vous souhaitiez ajouter un champ de scripts à la configuration pour faciliter l’exécution de votre projet à partir de la ligne de commande ou inclure des informations pour d’autres outils de post-traitement, nous espérons que vous apprécierez cette nouvelle façon de spécifier des champs personnalisés.

Résolutions des dépendance yarn sélective (expérimental)

Lorsque vous incluez des dépendances de npm, il y a des moments où vous voulez avoir un contrôle plus précis sur leurs dépendances (dépendances transitives). Il peut y avoir de nombreuses raisons à cela. Vous pouvez par exemple vouloir appliquer une mise à niveau importante à l’une des dépendances d’une bibliothèque que vous utilisez. Ou vouloir annuler l’application de la mise à jour d’une dépendance transitive qui affecte votre application. Les résolutions des dépendances sélectives de Yarn vous permettent de remplacer les dépendances spécifiées par l’auteur d’origine afin de pouvoir continuer à développer.

Kotlin 1.4.20 propose un moyen préliminaire (expérimental) de configurer cette fonctionnalité à partir du script de build Gradle d’un projet. Nous travaillons encore à rendre l’intégration API avec le reste des options Kotlin/JS harmonieuse, mais vous pouvez d’ores et déjà utiliser la fonctionnalité via YarnRootExtension dans le YarnPlugin. Pour influencer la version résolue d’un package pour votre projet, utilisez la fonction resolution. Dans ses arguments, spécifiez le sélecteur de nom de paquet (comme spécifié par Yarn) et la version souhaitée.

Voici un exemple de ce à quoi la configuration pour la résolution sélective des dépendances dans votre fichier build.gradle.kts pourrait ressembler :

Ici, toutes vos dépendances npm qui nécessitent react recevront la version 16.0.0, et processor recevra sa dépendance decamelize en tant que version 3.0.0. De plus, vous pouvez passer des appels include et exclude au bloc resolution, ce qui permet de spécifier des contraintes concernant les versions acceptables.

Désactivation des espaces de travail granulaires (expérimental)

Pour accélérer les temps de build, le plugin Kotlin/JS Gradle installe uniquement les dépendances requises pour une tâche Gradle particulière. Par exemple, le paquet webpack-dev-server n’est installé que lorsque vous exécutez l’une des tâches *Run et non lorsque vous exécutez la tâche assemble. Bien que cela permette d’éviter des téléchargements inutiles, des problèmes peuvent survenir lors de l’exécution de plusieurs processus Gradle en parallèle. Lorsque les exigences de dépendance ne coïncident pas, les deux installations depaquets npm peuvent causer des erreurs.

Pour résoudre ce problème, Kotlin 1.4.20 inclut une nouvelle option (expérimentale) permettant de désactiver ce que l’on appelle les espaces de travail granulaires. À l’instar de la prise en charge expérimentale des résolutions de dépendances sélectives, cette fonctionnalité est actuellement accessible via YarnRootExtension, mais elle sera probablement intégrée plus étroitement avec le reste du DSL Kotlin/JS Gradle. Pour l’utiliser, ajoutez le snippet suivant à votre fichier build.gradle.kts :

Avec cette configuration, le plugin Kotlin/JS Gradle installera toutes les dépendances npm pouvant être utilisées par votre projet, y compris celles utilisées par les tâches qui ne sont pas en cours d’exécution. Cela signifie que la première build de Gradle peut prendre un peu plus de temps, mais que les dépendances téléchargées seront à jour pour toutes les tâches que vous exécuterez. De cette façon, vous pouvez éviter les conflits lors de l’exécution en parallèle de plusieurs processus Gradle.

Nouveaux templates de l’assistant

Pour faciliter la personnalisation de votre projet lors de sa création, l’assistant de projet pour Kotlin est fourni avec de nouveaux templates ajustables pour les applications Kotlin/JS. Il s’agit de templates pour le navigateur et pour les environnements d’exécution Node.js. Ils constituent un bon point de départ pour votre projet et permettent d’ajuster la configuration initiale. Cela s’applique à des paramètres tels que l’activation du nouveau compilateur IR ou la configuration de la prise en charge de bibliothèques supplémentaires.

Avec Kotlin 1.4.20, trois templates sont disponibles :

  • Browser Application vous permet de configurer un projet Kotlin/JS Gradle basique qui s’exécute dans le navigateur.
  • React Application contient tout ce dont vous avez besoin pour commencer à créer une application React avec les kotlin-wrappers appropriés. Ce template fournit des options pour permettre des intégrations pour les feuilles de style, composants de navigation et conteneurs d’état.
  • Node.js Application préconfigure votre projet pour une exécution dans un environnement Node.js. Ce template permet d’inclure directement le paquet expérimental kotlinx-nodejs, que nous avons présenté dans un article précédent.

Ignorer les erreurs de compilation (expérimental)

Avec Kotlin 1.4.20, nous sommes également ravis de présenter une toute nouvelle fonctionnalité disponible dans le compilateur IR Kotlin/JS : ignoring compilation errors. Cette fonctionnalité vous permet d’essayer votre application même si elle est dans un état où elle ne se compilerait pas normalement. Par exemple, quand vous effectuez une refactorisation complexe ou travaillez sur une partie du système qui n’est absolument pas liée à une erreur de compilation. Avec ce nouveau mode de compilation, le compilateur ignore tout code erroné et le remplace par des exceptions d’exécution au lieu de refuser de compiler.

Kotlin 1.4.20 propose deux principes de tolérance pour ignorer les erreurs de compilation dans votre code :

  • En mode SEMANTIC, le compilateur acceptera du code qui est correct du point de vue de la syntaxe mais qui n’a pas de sens sémantiquement parlant. Un exemple de cela serait une instruction contenant une incompatibilité de type (comme val x: String = 3).
  • En mode SYNTAX, le compilateur acceptera absolument n’importe quel code, même s’il contient des erreurs de syntaxe. Indépendamment de ce que vous écrivez, le compilateur essaiera toujours de générer un exécutable fonctionnel.

Comme il s’agit d’une fonctionnalité expérimentale, ignorer les erreurs de compilation requiert un opt-in via une option du compilateur. Elle n’est disponible que pour le compilateur IR Kotlin/JS. Pour l’activer, ajoutez le snippet suivant à votre fichier build.gradle.kts :

Nous espérons que la compilation avec erreurs vous aidera à resserrer les boucles de rétroaction et à accélérer vos itérations pour les projets Kotlin/JS. Faites-nous part de vos commentaires et des problèmes que vous aurez rencontrés en essayant cette fonctionnalité dans YouTrack.

Nous continuons à affiner l’implémentation de cette fonctionnalité et proposerons une intégration plus approfondie avec le DSL Kotlin/JS Gradle et ses tâches ultérieurement.

Kotlin/Native

La performance reste l’une des principales priorités de Kotlin/Native dans la version 1.4.20. Parmi les fonctionnalités essentielles à cet égard figure le prototype du nouveau mécanisme d’analyse d’échappement, que nous prévoyons de peaufiner et d’améliorer dans les prochaines versions. Nous avons également apporté d’autres améliorations de la performance, avec les vérifications de plages plus rapides notamment (in).

Autre aspect des améliorations apportées au développement Kotlin/Native dans la version 1.4.20 : la correction de bugs. Nous avons résolu un certain nombre de problèmes, y compris ceux trouvés dans les nouvelles fonctionnalités de la version 1.4, comme le mécanisme de partage de code. Un ensemble d’améliorations corrige les incohérences de comportement entre Kotlin/Native et Kotlin/JVM dans des cas particuliers, tels que l’initialisation de propriété ou l’application d’equals et de hashCode à des références fonctionnelles.

Enfin, nous avons étendu les capacités d’interopérabilité avec Objective-C grâce à une option permettant d’encapsuler les exceptions Objective-C dans des exceptions Kotlin afin de les gérer dans le code Kotlin.

Analyse d’échappement

L’analyse d’échappement est une technique utilisée par le compilateur pour décider si un objet peut être alloué sur la pile ou doit « s’échapper » vers le tas. L’allocation sur la pile est beaucoup plus rapide et ne nécessite pas de passage ultérieur du ramasse-miettes.

Bien que Kotlin/Native dispose déjà d’une analyse d’échappement locale, nous ajoutons un prototype d’implémentation d’une nouvelle analyse d’échappement globale plus efficace. Cette configuration s’effectue dans une phase de compilation séparée pour les builds de version finale (avec l’option de compilateur -opt).

Ce prototype a déjà donné des résultats prometteurs et nous avons notamment constaté une augmentation moyenne des performances de 10%. Nous recherchons des moyens d’optimiser l’algorithme afin qu’il trouve davantage d’objets pour l’allocation de pile et accélère encore plus le programme.

Pendant que nous continuons à travailler sur le prototype, vous pouvez nous apporter une aide considérable en l’essayant et en partageant les résultats obtenus sur vos projets réels.

Si vous souhaitez désactiver la phase d’analyse d’échappement, utilisez l’option du compilateur -Xdisable-phases=EscapeAnalysis.

Adhérer à l’encaspulation des exceptions Objective-C

Le but des exceptions dans Objective-C est dans Kotlin est assez différent. Leur utilisation est normalement limitée à la recherche d’erreurs pendant le développement. Mais techniquement, les bibliothèques Objective-C peuvent "lever" des exceptions lors de l’exécution. Auparavant, aucune option ne permettait de gérer de telles exceptions dans Kotlin/Native et une NSException lancée depuis une bibliothèque provoquait l’arrêt de tout le programme Kotlin/Native.

Dans la version 1.4.20, nous avons ajouté une option pour gérer ces exceptions au moment de l’exécution afin d’éviter les pannes de programme. Vous pouvez choisir d’encapsuler les NSException[s] dans les ForeignException[s] de Kotlin et de les gérer ultérieurement dans le code Kotlin. Une telle ForeignException contient la référence à la NSException d’origine, ce qui vous permet d’obtenir des informations sur la cause première.

Pour permettre l’encapsulation des exceptions Objective-C, spécifiez l’option -Xforeign-exception-mode objc-wrap dans l’appel cinterop ou ajoutez la propriété foreignExceptionMode = objc-wrap au fichier .def. Si vous utilisez l’intégration CocoaPods, spécifiez l’option dans le bloc de script de build pod {} d’une dépendance, comme ceci :

Le comportement par défaut reste identique : le programme se termine lorsqu’une exception est levée à partir du code Objective-C.

Améliorations du plugin CocoaPods

Amélioration de l’exécution des tâches

Dans cette version, nous avons considérablement amélioré le flux d’exécution des tâches. Par exemple, si vous ajoutez une nouvelle dépendance CocoaPods, les dépendances existantes ne sont pas reconstruites. L’ajout d’une cible supplémentaire ne déclenche pas non plus la reconstruction des dépendances pour les cibles existantes.

DSL étendu

Dans la version 1.4.20, nous avons étendu le DSL pour ajouter des dépendances CocoaPods à votre projet Kotlin.

En plus des Pods locaux et des Pods du référentiel CocoaPods, vous pouvez ajouter des dépendances aux types de bibliothèques suivants :

  • Une bibliothèque d’un référentiel de spécifications personnalisées.
  • Une bibliothèque distante d’un référentiel Git.
  • Une bibliothèque d’archive (également disponible par adresse HTTP arbitraire).
  • Une bibliothèque statique.
  • Une bibliothèque avec des options cinterop personnalisées.

La syntaxe DSL précédente est toujours prise en charge.

Examinons quelques-unes des modifications du DSL dans les exemples suivants :

  • Une dépendance à une bibliothèque distante d’un référentiel Git. Vous pouvez spécifier une balise, un commit ou une branche en utilisant les mots clés correspondants, par exemple :

    Vous pouvez également combiner ces mots-clés pour obtenir la version requise d’un Pod.

  • Une dépendance à une bibliothèque d’un référentiel de spécifications personnalisées. Utilisez le paramètre spécial specRepos pour cela :

Vous trouverez d’autres exemples dans l’extrait de code Kotlin avec CocoaPods.

Mise à jour de l’intégration avec Xcode

Pour fonctionner correctement avec Xcode, Kotlin nécessite quelques modifications du Podfile :

  • Si votre Kotlin Pod a des dépendances de pod Git, HTTP ou specRepo, vous devez également les spécifier dans le Podfile. Par exemple, si vous ajoutez une dépendance à AFNetworking à partir du référentiel CocoaPods, déclarez-la également dans le Podfile :

    pod 'AFNetworking'
  • Lorsque vous ajoutez une bibliothèque à partir de la spécification personnalisée, vous devez également spécifier l’emplacement (location) des spécifications au début de votre Podfile :

    source 'https://github.com/Kotlin/kotlin-cocoapods-spec.git'
    
    target 'kotlin-cocoapods-xcproj' do
      // ... other Pods ...
      pod 'example'
    end

Des descriptions détaillées des erreurs d’intégration figurent maintenant dans IntelliJ IDEA, donc pour tout problème avec votre Podfile, vous obtiendrez immédiatement des informations sur sa résolution.

Jetez un œil à la branche withXcproject de l’exemple de code Kotlin avec CocoaPods. Vous y trouverez un exemple d’intégration Xcode avec le projet Xcode existant nommé kotlin-cocoapods-xcproj.

Prise en charge des bibliothèques Xcode 12

Nous avons ajouté la prise en charge des nouvelles bibliothèques livrées avec Xcode 12. N’hésitez pas à les utiliser dans votre code Kotlin !

Mise à jour de la structure des publications de la bibliothèque multiplateforme

Avant Kotlin 1.4.20, les publications de bibliothèques multiplateformes incluaient les publications spécifiques à la plateforme et une publication de métadonnées. Toutefois, la publication des métadonnées avait été faite en interne mais jamais été utilisée dans des projets externes.

À partir de Kotlin 1.4.20, il n’y a plus de publication de métadonnées séparée. Les artefacts de métadonnées sont désormais inclus dans la publication racine, qui représente la bibliothèque entière et est automatiquement résolue en artefacts spécifiques à la plateforme appropriés lorsqu’elle est ajoutée en tant que dépendance à l’ensemble de sources commun.

N’ajoutez pas un artefact vide sans classificateur au module racine de votre bibliothèque pour répondre aux exigences des référentiels tels que Maven Central, car cela entraînerait un conflit avec les artefacts de métadonnées qui sont désormais inclus dans ce module.

Compatibilité avec les bibliothèques publiées en 1.4.20

Si vous avez activé la prise en charge des structures de projets hiérarchiques et que vous souhaitez utiliser une bibliothèque multiplateforme publiée avec cette prise en charge dans Kotlin 1.4.20 ou une version supérieure, vous devrez également mettre à niveau Kotlin vers la version 1.4.20 ou une version supérieure dans votre projet.

Si vous créez des bibliothèques et que vous publiez votre bibliothèque multiplateforme dans Kotlin 1.4.20+ avec la prise en charge des structures de projets hiérarchiques, n’oubliez pas que les utilisateurs disposant de versions antérieures de Kotlin et ayant activé la prise en charge des structures de projets hiérarchiques ne pourront pas utiliser votre bibliothèque. Ils devront mettre à niveau Kotlin vers la version 1.4.20 ou une version supérieure.

Toutefois, si vous ou les utilisateurs de votre bibliothèque n’activez pas la prise en charge des structures de projets hiérarchiques, toute personne disposant d’une version antérieure de Kotlin pourra utiliser votre bibliothèque.

Apprenez-en plus sur la publication d’une bibliothèque multiplateforme.

Modifications de la bibliothèque standard

Extensions pour java.nio.file.Path

A partir de la version 1.4.20, la bibliothèque standard propose des extensions expérimentales pour java.nio.file.Path.

Travailler avec l’API de fichier de la JVM moderne d’une manière "Kotlin idiomatique" revient désormais à travailler avec les extensions java.io.File du paquet kotlin.io. Il n’est plus nécessaire d’appeler des méthodes statiques de Files car la plupart d’entre elles sont désormais disponibles en tant qu’extensions sur le type Path.

Les extensions se trouvent dans le paquet kotlin.io.path. Path étant disponible dans le JDK 7 et versions supérieures, les extensions sont placées dans le module kotlin-stdlib-jdk7. Pour les utiliser, vous devez activer l’annotation expérimentale ExperimentalPathApi.

Nous tenons à remercier tout particulièrement notre contributeur AJ Alt d’avoir fait la requête pull initiale avec ces extensions.

Amélioration des performances de la fonction String.replace

Nous sommes toujours ravis lorsque la communauté Kotlin suggère des améliorations, et ce fut le cas sur ce point. Dans cette version, nous avons modifié l’implémentation de la fonction String.replace().

La variante sensible à la casse utilise une boucle de remplacement manuelle basée sur indexOf, tandis que la variante insensible à la casse utilise une correspondance d’expression régulière.

Cette amélioration accélère l’exécution de la fonction dans certains cas.

Abandon des extensions Kotlin Android

Depuis leur création, les extensions Kotlin Android ont joué un rôle majeur dans la popularité croissante de Kotlin au sein de l’écosystème Android. Avec ces extensions, nous avons fourni aux développeurs des outils pratiques et efficaces pour réduire le code standard :

  • Vues synthétiques (kotlinx.android.synthetics) pour l’interaction avec l’interface utilisateur.
  • Générateur d’implémentation parcelable (@Parcelize) pour faire passer des objets en tant que Parcel[s].

Au départ, nous avons pensé ajouter d’autres composants à kotlin-android-extensions. Mais nous ne l’avons pas fait et nous avons même reçu des demandes d’utilisateurs pour diviser le plugin en parties indépendantes.

D’un autre côté, l’écosystème Android est en constante évolution et les développeurs disposent de nouveaux outils qui simplifient leur travail. Certaines lacunes que comblaient les extensions Kotlin Android ont été comblées par les mécanismes natifs de Google. Par exemple, en ce qui concerne la syntaxe concise pour l’interaction avec l’interface utilisateur, il existe maintenant Android Jetpack, qui comporte une liaison de vue qui remplace findViewById, tout comme les synthétiques Kotlin.

Compte tenu de ces deux facteurs, nous avons décidé de remplacer les synthétiques par la liaison de vue et de déplacer le générateur d’implémentation Parcelable vers un plugin séparé.

Dans la version 1.4.20, nous avons extrait le générateur d’implémentations Parcelable de kotlin-android-extensions et avons commencé le cycle d’obsolescence pour le reste, qui se limite actuellement aux synthétiques. Pour le moment, ils continuent de fonctionner avec un avertissement d’obsolescence. À l’avenir, vous devrez basculer votre projet vers une autre solution. Voici la marche à suivre pour la migration de projets Android à partir des synthétiques vers les liaisons de vues.

Le générateur d’implémentation Parcelable est maintenant disponible dans le nouveau plugin

kotlin-parcelize. Appliquez ce plugin au lieu de kotlin-android-extensions ou en plus de ce dernier si vous souhaitez continuer à utiliser des synthétiques. L’annotation @Parcelize est déplacée vers le paquet kotlinx.parcelize.

Comment faire la mise à jour

Avant de mettre à jour vos projets vers la dernière version de Kotlin, vous pouvez essayer les nouvelles fonctionnalités des bibliothèques standards et du langage en ligne sur play.kotl.in.

Dans IntelliJ IDEA et Android Studio, vous pouvez mettre à jour le plugin Kotlin vers la version 1.4.20 –découvrez comment faire ici.

Si vous souhaitez travailler sur des projets créés avec des versions précédentes de Kotlin, utilisez la version Kotlin 1.4.20 dans la configuration de votre projet. Pour en savoir plus, consultez la documentation pour Gradle et pour Maven.

Vous pouvez télécharger le compilateur de ligne de commande à partir de la page de la version sur Github.

Avec cette version, vous pouvez utiliser les bibliothèque suivantes :

Les versions des bibliothèques de kotlin-wrappers (kotlin-react etc.) se trouvent dans le référentiel correspondant.

Les détails de la version et la liste des bibliothèques compatibles sont également disponibles ici.

Si vous rencontrez des problèmes avec la nouvelle version, vous pouvez trouver de l’aide sur Slack (obtenez une invitation ici) et les signaler via YouTrack.

Contributeurs externes

Nous remercions tous nos contributeurs externes dont les requêtes pull ont été incluses dans cette version :

Jinseong Jeon Toshiaki Kameyama Steven Schäfer Mads Ager Mark Punzalan Ivan Gavrilovic pyos Jim Sproch Kristoffer Andersen Aleksandrina Streltsova cketti Konstantin Virolainen AJ Alt Henrik Tunedal Juan Chen KotlinIsland, Valeriy Vyrva Alex Chmyr Alexey Kudravtsev Andrey Matveev Aurimas Liutikas Dat Trieu Dereck Bridie Efeturi Money Elijah Verdoorn Enteerman fee1-dead Francesco Vasco Gia Thuan Lam Guillaume Darmont Jake Wharton Julian Kotrba Kevin Bierhoff Matthew Gharrity Matts966 Raluca Sauciuc Ryan Nett Sebastian Kaspari Vladimir Krivosheev n-p-s Pavlos-Petros Tournaris Robert Bares Yoshinori Isogai Kris Derek Bodin Dominik Wuttke Sam Wang Uzi Landsmann Yuya Urano Norbert Nogacki Alexandre Juca

Auteur de l’article original en anglais : Pavel Semyonov

image description

Discover more