Add @RequireKotlin(1.2.40) on interface with @JvmDefaults and its subinterfaces
This commit is contained in:
+25
-13
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.protobuf.MessageLite
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils.isEnumEntry
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils.isInterface
|
||||
import org.jetbrains.kotlin.resolve.MemberComparator
|
||||
import org.jetbrains.kotlin.resolve.RequireKotlinNames
|
||||
import org.jetbrains.kotlin.resolve.annotations.hasJvmDefaultAnnotation
|
||||
@@ -142,6 +143,8 @@ class DescriptorSerializer private constructor(
|
||||
val requirement = serializeVersionRequirement(classDescriptor)
|
||||
if (requirement != null) {
|
||||
builder.versionRequirement = requirement
|
||||
} else {
|
||||
writeVersionRequirementForJvmDefaultIfNeeded(classDescriptor, builder)
|
||||
}
|
||||
|
||||
val versionRequirementTableProto = versionRequirementTable.serialize()
|
||||
@@ -239,8 +242,6 @@ class DescriptorSerializer private constructor(
|
||||
}
|
||||
else if (descriptor.isSuspendOrHasSuspendTypesInSignature()) {
|
||||
builder.versionRequirement = writeVersionRequirement(LanguageFeature.Coroutines)
|
||||
} else if (descriptor.hasJvmDefaultAnnotation()) {
|
||||
builder.versionRequirement = writeVersionRequirement(1, 2, 40)
|
||||
}
|
||||
|
||||
extension.serializeProperty(descriptor, builder)
|
||||
@@ -311,8 +312,6 @@ class DescriptorSerializer private constructor(
|
||||
builder.versionRequirement = requirement
|
||||
} else if (descriptor.isSuspendOrHasSuspendTypesInSignature()) {
|
||||
builder.versionRequirement = writeVersionRequirement(LanguageFeature.Coroutines)
|
||||
} else if (descriptor.hasJvmDefaultAnnotation()) {
|
||||
builder.versionRequirement = writeVersionRequirement(1, 2, 40)
|
||||
}
|
||||
|
||||
contractSerializer.serializeContractOfFunctionIfAny(descriptor, builder, this)
|
||||
@@ -619,23 +618,36 @@ class DescriptorSerializer private constructor(
|
||||
return builder
|
||||
}
|
||||
|
||||
private fun writeVersionRequirement(languageFeature: LanguageFeature): Int {
|
||||
val languageVersion = languageFeature.sinceVersion!!
|
||||
val requirement = ProtoBuf.VersionRequirement.newBuilder().apply {
|
||||
VersionRequirement.Version(languageVersion.major, languageVersion.minor).encode(
|
||||
writeVersion = { version = it },
|
||||
writeVersionFull = { versionFull = it }
|
||||
)
|
||||
// Interfaces which have @JvmDefault members somewhere in the hierarchy need the compiler 1.2.40+
|
||||
// so that the generated bridges in subclasses would call the super members correctly
|
||||
private fun writeVersionRequirementForJvmDefaultIfNeeded(classDescriptor: ClassDescriptor, builder: ProtoBuf.Class.Builder) {
|
||||
if (
|
||||
isInterface(classDescriptor) &&
|
||||
classDescriptor.unsubstitutedMemberScope.getContributedDescriptors().any {
|
||||
it is CallableMemberDescriptor && it.hasJvmDefaultAnnotation()
|
||||
}
|
||||
) {
|
||||
builder.versionRequirement = writeVersionRequirement(1, 2, 40, ProtoBuf.VersionRequirement.VersionKind.COMPILER_VERSION)
|
||||
}
|
||||
return versionRequirementTable[requirement]
|
||||
}
|
||||
|
||||
private fun writeVersionRequirement(major: Int, minor: Int, patch: Int): Int {
|
||||
private fun writeVersionRequirement(languageFeature: LanguageFeature): Int {
|
||||
val languageVersion = languageFeature.sinceVersion!!
|
||||
return writeVersionRequirement(
|
||||
languageVersion.major, languageVersion.minor, 0,
|
||||
ProtoBuf.VersionRequirement.VersionKind.LANGUAGE_VERSION
|
||||
)
|
||||
}
|
||||
|
||||
private fun writeVersionRequirement(major: Int, minor: Int, patch: Int, versionKind: ProtoBuf.VersionRequirement.VersionKind): Int {
|
||||
val requirement = ProtoBuf.VersionRequirement.newBuilder().apply {
|
||||
VersionRequirement.Version(major, minor, patch).encode(
|
||||
writeVersion = { version = it },
|
||||
writeVersionFull = { versionFull = it }
|
||||
)
|
||||
if (versionKind != defaultInstanceForType.versionKind) {
|
||||
this.versionKind = versionKind
|
||||
}
|
||||
}
|
||||
return versionRequirementTable[requirement]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package test
|
||||
|
||||
interface Base {
|
||||
@JvmDefault
|
||||
fun foo() {}
|
||||
}
|
||||
|
||||
interface Derived : Base
|
||||
@@ -18,12 +18,14 @@ package org.jetbrains.kotlin.serialization
|
||||
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.config.*
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PackageViewDescriptor
|
||||
import org.jetbrains.kotlin.jvm.compiler.LoadDescriptorUtil
|
||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||
import org.jetbrains.kotlin.metadata.ProtoBuf.VersionRequirement.VersionKind.*
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.lazy.JvmResolveUtil
|
||||
import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered
|
||||
@@ -46,8 +48,20 @@ class VersionRequirementTest : TestCaseWithTmpdir() {
|
||||
vararg fqNames: String
|
||||
) {
|
||||
LoadDescriptorUtil.compileKotlinToDirAndGetModule(
|
||||
listOf(File("compiler/testData/versionRequirement/${getTestName(true)}.kt")), tmpdir,
|
||||
KotlinTestUtils.createEnvironmentWithMockJdkAndIdeaAnnotations(testRootDisposable)
|
||||
listOf(File("compiler/testData/versionRequirement/${getTestName(true)}.kt")), tmpdir,
|
||||
KotlinCoreEnvironment.createForTests(
|
||||
testRootDisposable,
|
||||
KotlinTestUtils.newConfiguration(ConfigurationKind.ALL, TestJdkKind.MOCK_JDK, tmpdir).apply {
|
||||
put(JVMConfigurationKeys.JVM_TARGET, JvmTarget.JVM_1_8)
|
||||
languageVersionSettings = LanguageVersionSettingsImpl(
|
||||
LanguageVersionSettingsImpl.DEFAULT.languageVersion,
|
||||
LanguageVersionSettingsImpl.DEFAULT.apiVersion,
|
||||
mapOf(AnalysisFlag.enableJvmDefault to true),
|
||||
emptyMap()
|
||||
)
|
||||
},
|
||||
EnvironmentConfigFiles.JVM_CONFIG_FILES
|
||||
)
|
||||
)
|
||||
|
||||
val (_, module) = JvmResolveUtil.analyze(
|
||||
@@ -99,7 +113,7 @@ class VersionRequirementTest : TestCaseWithTmpdir() {
|
||||
}
|
||||
|
||||
fun testSuspendFun() {
|
||||
doTest(VersionRequirement.Version(1, 1), DeprecationLevel.ERROR, null, ProtoBuf.VersionRequirement.VersionKind.LANGUAGE_VERSION, null,
|
||||
doTest(VersionRequirement.Version(1, 1), DeprecationLevel.ERROR, null, LANGUAGE_VERSION, null,
|
||||
"test.topLevel",
|
||||
"test.Foo.member",
|
||||
"test.Foo.<init>",
|
||||
@@ -112,7 +126,7 @@ class VersionRequirementTest : TestCaseWithTmpdir() {
|
||||
}
|
||||
|
||||
fun testLanguageVersionViaAnnotation() {
|
||||
doTest(VersionRequirement.Version(1, 1), DeprecationLevel.WARNING, "message", ProtoBuf.VersionRequirement.VersionKind.LANGUAGE_VERSION, 42,
|
||||
doTest(VersionRequirement.Version(1, 1), DeprecationLevel.WARNING, "message", LANGUAGE_VERSION, 42,
|
||||
"test.Klass",
|
||||
"test.Konstructor.<init>",
|
||||
"test.Typealias",
|
||||
@@ -122,7 +136,7 @@ class VersionRequirementTest : TestCaseWithTmpdir() {
|
||||
}
|
||||
|
||||
fun testApiVersionViaAnnotation() {
|
||||
doTest(VersionRequirement.Version(1, 1), DeprecationLevel.WARNING, "message", ProtoBuf.VersionRequirement.VersionKind.API_VERSION, 42,
|
||||
doTest(VersionRequirement.Version(1, 1), DeprecationLevel.WARNING, "message", API_VERSION, 42,
|
||||
"test.Klass",
|
||||
"test.Konstructor.<init>",
|
||||
"test.Typealias",
|
||||
@@ -132,7 +146,7 @@ class VersionRequirementTest : TestCaseWithTmpdir() {
|
||||
}
|
||||
|
||||
fun testCompilerVersionViaAnnotation() {
|
||||
doTest(VersionRequirement.Version(1, 1), DeprecationLevel.WARNING, "message", ProtoBuf.VersionRequirement.VersionKind.COMPILER_VERSION, 42,
|
||||
doTest(VersionRequirement.Version(1, 1), DeprecationLevel.WARNING, "message", COMPILER_VERSION, 42,
|
||||
"test.Klass",
|
||||
"test.Konstructor.<init>",
|
||||
"test.Typealias",
|
||||
@@ -142,8 +156,16 @@ class VersionRequirementTest : TestCaseWithTmpdir() {
|
||||
}
|
||||
|
||||
fun testPatchVersion() {
|
||||
doTest(VersionRequirement.Version(1, 1, 50), DeprecationLevel.HIDDEN, null, ProtoBuf.VersionRequirement.VersionKind.LANGUAGE_VERSION, null,
|
||||
doTest(VersionRequirement.Version(1, 1, 50), DeprecationLevel.HIDDEN, null, LANGUAGE_VERSION, null,
|
||||
"test.Klass"
|
||||
)
|
||||
}
|
||||
|
||||
fun testJvmDefault() {
|
||||
doTest(
|
||||
VersionRequirement.Version(1, 2, 40), DeprecationLevel.ERROR, null, COMPILER_VERSION, null,
|
||||
"test.Base",
|
||||
"test.Derived"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user