Spec-Zone.ru › Kotlin 1.6

Руководство по совместимости для Kotlin 1.5

Сохранение актуальности языка и Комфортные обновления относятся к основным принципам проектирования языка Kotlin. Первый принцип гласит, что конструкции, препятствующие развитию языка, должны быть удалены, а второй — что такое удаление должно быть должным образом сообщено заранее, чтобы минимизировать трудности при миграции кода.

Хотя большинство изменений языка уже были объявлены другими каналами, такими как журналы обновлений или предупреждения компилятора, этот документ обобщает их все, предоставляя полную справку для миграции с Kotlin 1.4 на Kotlin 1.5.

Основные термины

В этом документе мы вводим несколько видов совместимости:

  • исходный код: изменение, несовместимое с исходным кодом, препятствует компиляции кода, который ранее компилировался без ошибок или предупреждений.

  • бинарный: два бинарных артефакта считаются бинарно-совместимыми, если их обмен не приводит к ошибкам загрузки или компоновки.

  • поведенческий: изменение считается поведенчески несовместимым, если один и тот же фрагмент программы демонстрирует разное поведение до и после применения изменения.

Обратите внимание, что эти определения приведены только для чистого Kotlin. Совместимость кода Kotlin с точки зрения других языков (например, Java) выходит за рамки этого документа.

Язык и стандартная библиотека

Запрет оператора spread в вызовах с сигнатурной полиморфией

Проблема: KT-35226

Компонент: Язык ядра

Тип несовместимого изменения: исходный код

Краткое описание: Kotlin 1.5 запретит использование оператора spread (*) в вызовах с сигнатурной полиморфией.

Цикл устаревания:

  • < 1.5: введение предупреждения для проблемного оператора в месте вызова

  • >= 1.5: это предупреждение станет ошибкой, -XXLanguage:-ProhibitSpreadOnSignaturePolymorphicCall можно использовать для временного возврата к поведению версии до 1.5

Запрет неабстрактных классов, содержащих абстрактные члены, невидимые из внутреннего пакета (internal/package-private)

Проблема: KT-27825

Компонент: Язык ядра

Тип несовместимого изменения: исходный код

Краткое описание: Kotlin 1.5 запретит неабстрактные классы, содержащие абстрактные члены, невидимые из внутреннего пакета (internal/package-private).

Цикл устаревания:

  • < 1.5: введение предупреждения для проблемных классов

  • >= 1.5: это предупреждение станет ошибкой, -XXLanguage:-ProhibitInvisibleAbstractMethodsInSuperclasses можно использовать для временного возврата к поведению версии до 1.5

Запрет использования массивов, основанных на нерефицированных параметрах типа, в качестве рефицированных аргументов типа на JVM

Проблема: KT-31227

Компонент: Язык ядра

Тип несовместимого изменения: исходный код

Краткое описание: Kotlin 1.5 запретит использование массивов, основанных на нерефицированных параметрах типа, в качестве рефицированных аргументов типа на JVM.

Цикл устаревания:

  • < 1.5: введение предупреждения для проблемных вызовов

  • >= 1.5: это предупреждение станет ошибкой, -XXLanguage:-ProhibitNonReifiedArraysAsReifiedTypeArguments можно использовать для временного возврата к поведению версии до 1.5

Запрет вторичных конструкторов перечислений, которые не делегируют первичному конструктору

Проблема: KT-35870

Компонент: Язык ядра

Тип несовместимого изменения: исходный код

Краткое описание: Kotlin 1.5 запретит вторичные конструкторы перечислений, которые не делегируют первичному конструктору.

Цикл устаревания:

  • < 1.5: введение предупреждения для проблемных конструкторов

  • >= 1.5: это предупреждение станет ошибкой, -XXLanguage:-RequiredPrimaryConstructorDelegationCallInEnums можно использовать для временного возврата к поведению версии до 1.5

Запрет экспонирования анонимных типов из закрытых inline-функций

Проблема: KT-33917

Компонент: Язык ядра

Тип несовместимого изменения: исходный код

Краткое описание: Kotlin 1.5 запретит экспонирование анонимных типов из закрытых inline-функций.

Цикл устаревания:

  • < 1.5: введение предупреждения для проблемных конструкторов

  • >= 1.5: это предупреждение станет ошибкой, -XXLanguage:-ApproximateAnonymousReturnTypesInPrivateInlineFunctions можно использовать для временного возврата к поведению версии до 1.5

Запрет передачи нераскротых массивов после аргументов с SAM-преобразованием

Проблема: KT-35224

Компонент: Язык ядра

Тип несовместимого изменения: исходный код

Краткое описание: Kotlin 1.5 запретит передачу нераскротых массивов после аргументов с SAM-преобразованием.

Цикл устаревания:

  • 1.3.70: введение предупреждения для проблемных вызовов

  • >= 1.5: это предупреждение станет ошибкой, -XXLanguage:-ProhibitVarargAsArrayAfterSamArgument можно использовать для временного возврата к поведению версии до 1.5

Поддержка специальной семантики для параметров блока catch с именем подчерк

Проблема: KT-31567

Компонент: Язык ядра

Тип несовместимого изменения: исходный код

Краткое описание: Kotlin 1.5 запретит ссылки на символ подчеркивания (_), используемый для пропуска имени параметра исключения в блоке catch.

Цикл устаревания:

  • 1.4.20: введение предупреждения для проблемных ссылок

  • >= 1.5: это предупреждение станет ошибкой, -XXLanguage:-ForbidReferencingToUnderscoreNamedParameterOfCatchBlock можно использовать для временного возврата к поведению версии до 1.5

Изменение стратегии реализации преобразования SAM из анонимного класса на invokedynamic

Проблема: KT-44912

Компонент: Kotlin/JVM

Тип несовместимого изменения: поведенческое

Краткое описание: Начиная с Kotlin 1.5, стратегия реализации преобразования SAM (single abstract method) будет изменена с генерации анонимного класса на использование инструкции JVM invokedynamic.

Цикл устаревания:

  • 1.5: изменение стратегии реализации преобразования SAM, -Xsam-conversions=class можно использовать для возврата к схеме реализации, которая использовалась ранее

Проблемы производительности с JVM IR-основанным бэкэндом

Проблема: KT-48233

Компонент: Kotlin/JVM

Тип несовместимого изменения: поведенческое

Краткое описание: Kotlin 1.5 по умолчанию использует IR-основанный бэкэнд для компилятора Kotlin/JVM. Старый бэкэнд по умолчанию используется для более ранних версий языка.

При использовании нового компилятора в Kotlin 1.5 могут возникнуть проблемы с производительностью. Мы работаем над исправлением таких случаев.

Цикл устаревания:

  • < 1.5: по умолчанию используется старый JVM бэкэнд

  • >= 1.5: по умолчанию используется IR-основанный бэкэнд. Если вам нужно использовать старый бэкэнд в Kotlin 1.5, добавьте следующие строки в файл конфигурации проекта, чтобы временно вернуться к поведению до версии 1.5:

В Gradle:

tasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompile> {
  kotlinOptions.useOldBackend = true
}
tasks.withType(org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompile) {
  kotlinOptions.useOldBackend = true
}

В Maven:

<configuration>
    <args>
        <arg>-Xuse-old-backend</arg>
    </args>
</configuration>

Поддержка этой опции будет удалена в одной из будущих версий.

Новая сортировка полей в JVM IR-основанном бэкэнде

Проблема: KT-46378

Компонент: Kotlin/JVM

Тип несовместимого изменения: поведенческое

Краткое описание: С версии 1.5 Kotlin использует IR-основанный бэкэнд, который сортирует JVM байткод по-другому: он генерирует поля, объявленные в конструкторе, перед полями, объявленными в теле, в то время как для старого бэкэнда порядок обратный. Новая сортировка может изменить поведение программ, использующих фреймворки сериализации, которые зависят от порядка полей, таких как Java сериализация.

Цикл устаревания:

  • < 1.5: по умолчанию используется старый JVM бэкэнд. Поля, объявленные в теле, генерируются перед полями, объявленными в конструкторе.

  • >= 1.5: по умолчанию используется новый IR-основанный бэкэнд. Поля, объявленные в конструкторе, генерируются перед полями, объявленными в теле. В качестве обходного решения можно временно переключиться на старый бэкэнд в Kotlin 1.5. Для этого добавьте следующие строки в файл конфигурации проекта:

В Gradle:

tasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompile> {
  kotlinOptions.useOldBackend = true
}
tasks.withType(org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompile) {
  kotlinOptions.useOldBackend = true
}

В Maven:

<configuration>
    <args>
        <arg>-Xuse-old-backend</arg>
    </args>
</configuration>

Поддержка этой опции будет удалена в одной из будущих версий.

Генерация проверок на null для делегированных свойств с универсальным вызовом в выражении делегата

Проблема: KT-44304

Компонент: Kotlin/JVM

Тип несовместимого изменения: поведенческое

Краткое описание: С Kotlin 1.5 компилятор Kotlin будет генерировать проверки на null для делегированных свойств с универсальным вызовом в выражении делегата.

Цикл устаревания:

  • 1.5: генерировать проверку на null для делегированных свойств (подробнее в проблеме), -Xuse-old-backend или -language-version 1.4 можно использовать для временного возврата к поведению до версии 1.5

Преобразование предупреждений в ошибки для вызовов с параметрами типа, помеченными аннотацией @OnlyInputTypes

Проблема: KT-45861

Компонент: Язык ядра

Тип несовместимого изменения: исходный код

Краткое описание: Kotlin 1.5 запретит вызовы, такие как contains, indexOf, и assertEquals с бессмысленными аргументами для повышения безопасности типов.

Цикл устаревания:

  • 1.4.0: введение предупреждения для проблемных конструкторов

  • >= 1.5: повышение этого предупреждения до ошибки, -XXLanguage:-StrictOnlyInputTypesChecks можно использовать для временного возврата к поведению до версии 1.5

Использование правильного порядка выполнения аргументов в вызовах с именованным vararg

Проблема: KT-17691

Компонент: Kotlin/JVM

Тип несовместимого изменения: поведенческое

Краткое описание: Kotlin 1.5 изменит порядок выполнения аргументов в вызовах с именованным vararg

Цикл устаревания:

  • < 1.5: введение предупреждения для проблемных конструкторов

  • >= 1.5: повышение этого предупреждения до ошибки, -XXLanguage:-UseCorrectExecutionOrderForVarargArguments можно использовать для временного возврата к поведению до версии 1.5

Использование значения по умолчанию параметра в операторных функциональных вызовах

Проблема: KT-42064

Компонент: Kotlin/JVM

Тип несовместимого изменения: поведенческое

Краткое описание: Kotlin 1.5 будет использовать значение по умолчанию параметра в операторных вызовах

Цикл устаревания:

  • < 1.5: старое поведение (см. подробности в проблеме)

  • >= 1.5: поведение изменено, -XXLanguage:-JvmIrEnabledByDefault можно использовать для временного возврата к поведению до версии 1.5

Генерация пустых обратных прогрессий в циклах for, если обычная прогрессия также пуста

Проблема: KT-42533

Компонент: Kotlin/JVM

Тип несовместимого изменения: поведенческое

Краткое описание: Kotlin 1.5 будет генерировать пустые обратные прогрессии в циклах for, если обычная прогрессия также пуста.

Цикл устаревания:

  • < 1.5: старое поведение (см. подробности в проблеме)

  • >= 1.5: поведение изменено, -XXLanguage:-JvmIrEnabledByDefault можно использовать для временного возврата к поведению до версии 1.5

Прямые преобразования Char в код и Char в цифры выведены

Проблема: KT-23451

Компонент: kotlin-stdlib

Тип несовместимого изменения: исходный код

Краткое описание: С Kotlin 1.5 преобразования Char в числовые типы будут устаревшими

Цикл устаревания:

  • 1.5: устаревают Char.toInt()/toShort()/toLong()/toByte()/toDouble()/toFloat() и обратные функции, такие как Long.toChar(), и предлагается замена

Несогласованное сравнение символов без учета регистра в функциях kotlin.text

Проблема: KT-45496

Компонент: kotlin-stdlib

Тип несовместимого изменения: поведенческий

Краткое описание: С Kotlin 1.5 Char.equals будет улучшен в сравнении без учета регистра, сначала сравнивая, равны ли заглавные варианты символов, а затем, равны ли строчные варианты этих заглавных вариантов (в отличие от самих символов).

Цикл устаревания:

  • < 1.5: старое поведение (см. подробности в проблеме)

  • 1.5: изменение поведения для функции Char.equals

Удаление API преобразования регистра с учетом локалей по умолчанию

Проблема: KT-43023

Компонент: kotlin-stdlib

Тип несовместимого изменения: исходный код

Краткое описание: С Kotlin 1.5 функции преобразования регистра с учетом локалей по умолчанию, такие как String.toUpperCase(), будут устаревшими

Цикл устаревания:

  • 1.5: устаревают функции преобразования регистра с локалью по умолчанию (см. подробности в проблеме), и предлагается замена

Постепенное изменение типа возврата функций min и max коллекций на не-nullable

Проблема: KT-38854

Компонент: kotlin-stdlib (JVM)

Тип несовместимого изменения: исходный код

Краткое описание: тип возврата функций коллекции min и max в 1.6 будет изменён на не-nullable

Цикл устаревания:

  • 1.4: вводятся функции ...OrNull как синонимы и устаревает затронутый API (см. подробности в проблеме)

  • 1.5.0: уровень устаревания затронутого API повышен до ошибки

  • >=1.6: затронутый API снова доступен, но с не-nullable типом возврата

Повышение уровня устаревания преобразований чисел с плавающей запятой в Short и Byte

Проблема: KT-30360

Компонент: kotlin-stdlib (JVM)

Тип несовместимого изменения: исходный код

Краткое описание: преобразования чисел с плавающей запятой в Short и Byte устарели в Kotlin 1.4 с уровнем WARNING, что приведёт к ошибкам с Kotlin 1.5.0.

Цикл устаревания:

  • 1.4: устаревают Double.toShort()/toByte() и Float.toShort()/toByte() и предлагается замена

  • 1.5.0: уровень устаревания повышен до ошибки

Инструменты

Не смешивайте несколько JVM-вариантов kotlin-test в одном проекте

Проблема: KT-40225

Компонент: Gradle

Тип несовместимого изменения: поведенческий

Краткое описание: в проекте могли быть несколько взаимоисключающих kotlin-test вариантов для разных фреймворков тестирования, если один из них был принесён транзитивной зависимостью. С 1.5.0 Gradle не позволит иметь взаимоисключающие kotlin-test варианты для разных фреймворков тестирования.

Цикл устаревания:

  • < 1.5: разрешено иметь несколько взаимоисключающих kotlin-test вариантов для разных фреймворков тестирования

  • >= 1.5: поведение изменено,
    Gradle выдаст исключение, подобное "Невозможно выбрать модуль с конфликтом по возможности...". Возможные решения:

    • используйте тот же kotlin-test вариант и соответствующий фреймворк тестирования, что и транзитивная зависимость.

    • найдите другую вариацию зависимости, которая не приносит kotlin-test вариант транзитивно, чтобы вы могли использовать фреймворк тестирования, который вы хотите использовать.

    • найдите другую вариацию зависимости, которая приносит другой kotlin-test вариант транзитивно, который использует тот же фреймворк тестирования, который вы хотите использовать.

    • исключите фреймворк тестирования, который приносится транзитивно. Следующий пример для исключения JUnit 4:

      configurations { 
          testImplementation.get().exclude("org.jetbrains.kotlin", "kotlin-test-junit")
      }
      

      После исключения фреймворка тестирования протестируйте своё приложение. Если оно перестало работать, верните исключение изменений, используйте тот же фреймворк тестирования, что и библиотека, и исключите свой фреймворк тестирования.

Последнее изменение: 07 апреля 2022
Руководство по совместимости для Kotlin 1.6 Руководство по совместимости для Kotlin 1.4

© 2010–2022 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/compatibility-guide-15.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API