Fix requirements
This commit is contained in:
+14
-8
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.codegen.createFreeFakeLocalPropertyDescriptor
|
||||
import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.*
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapperBase
|
||||
import org.jetbrains.kotlin.config.JvmDefaultMode
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
@@ -30,6 +31,7 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils.isInterface
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyPrivateApi
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.nonSourceAnnotations
|
||||
import org.jetbrains.kotlin.resolve.jvm.annotations.hasJvmDefaultAnnotation
|
||||
import org.jetbrains.kotlin.resolve.jvm.annotations.isCompiledToJvmDefaultIfNoAbstract
|
||||
import org.jetbrains.kotlin.serialization.DescriptorSerializer
|
||||
import org.jetbrains.kotlin.serialization.DescriptorSerializer.Companion.writeVersionRequirement
|
||||
@@ -102,15 +104,19 @@ class JvmSerializerExtension @JvmOverloads constructor(
|
||||
builder: ProtoBuf.Class.Builder,
|
||||
versionRequirementTable: MutableVersionRequirementTable
|
||||
) {
|
||||
if (
|
||||
isInterface(classDescriptor) &&
|
||||
classDescriptor.unsubstitutedMemberScope.getContributedDescriptors().any {
|
||||
it is CallableMemberDescriptor && it.isCompiledToJvmDefaultIfNoAbstract(jvmDefaultMode) //TODO: new requirements for new option
|
||||
if (isInterface(classDescriptor)) {
|
||||
if (jvmDefaultMode == JvmDefaultMode.ENABLE && classDescriptor.unsubstitutedMemberScope.getContributedDescriptors().any {
|
||||
it is CallableMemberDescriptor && it.hasJvmDefaultAnnotation()
|
||||
}) {
|
||||
builder.addVersionRequirement(
|
||||
writeVersionRequirement(1, 2, 40, ProtoBuf.VersionRequirement.VersionKind.COMPILER_VERSION, versionRequirementTable)
|
||||
)
|
||||
}
|
||||
if (jvmDefaultMode == JvmDefaultMode.ALL_INCOMPATIBLE) {
|
||||
builder.addVersionRequirement(
|
||||
writeVersionRequirement(1, 4, 0, ProtoBuf.VersionRequirement.VersionKind.COMPILER_VERSION, versionRequirementTable)
|
||||
)
|
||||
}
|
||||
) {
|
||||
builder.addVersionRequirement(
|
||||
writeVersionRequirement(1, 2, 40, ProtoBuf.VersionRequirement.VersionKind.COMPILER_VERSION, versionRequirementTable)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package test
|
||||
|
||||
interface Base {
|
||||
fun foo() {}
|
||||
}
|
||||
|
||||
interface Derived : Base
|
||||
|
||||
interface BaseWithProperty {
|
||||
val prop: String
|
||||
get() = "123"
|
||||
}
|
||||
|
||||
interface DerivedWithProperty : BaseWithProperty
|
||||
|
||||
interface Empty
|
||||
|
||||
interface EmptyWithNested {
|
||||
interface Nested
|
||||
}
|
||||
|
||||
interface WithAbstractDeclaration {
|
||||
fun foo()
|
||||
var prop: String
|
||||
}
|
||||
|
||||
interface DerivedFromWithAbstractDeclaration : WithAbstractDeclaration
|
||||
@@ -0,0 +1,27 @@
|
||||
package test
|
||||
|
||||
interface Base {
|
||||
fun foo() {}
|
||||
}
|
||||
|
||||
interface Derived : Base
|
||||
|
||||
interface BaseWithProperty {
|
||||
val prop: String
|
||||
get() = "123"
|
||||
}
|
||||
|
||||
interface DerivedWithProperty : BaseWithProperty
|
||||
|
||||
interface Empty
|
||||
|
||||
interface EmptyWithNested {
|
||||
interface Nested
|
||||
}
|
||||
|
||||
interface WithAbstractDeclaration {
|
||||
fun foo()
|
||||
var prop: String
|
||||
}
|
||||
|
||||
interface DerivedFromWithAbstractDeclaration : WithAbstractDeclaration
|
||||
+35
-16
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.serialization
|
||||
|
||||
import org.jetbrains.kotlin.config.AnalysisFlag
|
||||
import org.jetbrains.kotlin.config.LanguageVersion
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
@@ -28,19 +29,17 @@ abstract class AbstractVersionRequirementTest : TestCaseWithTmpdir() {
|
||||
expectedVersionKind: ProtoBuf.VersionRequirement.VersionKind,
|
||||
expectedErrorCode: Int?,
|
||||
customLanguageVersion: LanguageVersion = LanguageVersionSettingsImpl.DEFAULT.languageVersion,
|
||||
fqNames: List<String>
|
||||
analysisFlags: Map<AnalysisFlag<*>, Any?> = emptyMap(),
|
||||
fqNamesWithRequirements: List<String>,
|
||||
fqNamesWithoutRequirement: List<String> = emptyList()
|
||||
) {
|
||||
compileFiles(listOf(File("compiler/testData/versionRequirement/${getTestName(true)}.kt")), tmpdir, customLanguageVersion)
|
||||
compileFiles(listOf(File("compiler/testData/versionRequirement/${getTestName(true)}.kt")), tmpdir, customLanguageVersion, analysisFlags)
|
||||
val module = loadModule(tmpdir)
|
||||
|
||||
for (fqName in fqNames) {
|
||||
for (fqName in fqNamesWithRequirements) {
|
||||
val descriptor = module.findUnambiguousDescriptorByFqName(fqName)
|
||||
|
||||
val requirement = when (descriptor) {
|
||||
is DeserializedMemberDescriptor -> descriptor.versionRequirements.singleOrNull()
|
||||
is DeserializedClassDescriptor -> descriptor.versionRequirements.singleOrNull()
|
||||
else -> throw AssertionError("Unknown descriptor: $descriptor")
|
||||
} ?: throw AssertionError("No VersionRequirement for $descriptor")
|
||||
val requirement = extractRequirement(descriptor) ?: throw AssertionError("No VersionRequirement for $descriptor")
|
||||
|
||||
assertEquals("Incorrect version for $fqName", expectedVersionRequirement, requirement.version)
|
||||
assertEquals("Incorrect level for $fqName", expectedLevel, requirement.level)
|
||||
@@ -48,6 +47,21 @@ abstract class AbstractVersionRequirementTest : TestCaseWithTmpdir() {
|
||||
assertEquals("Incorrect versionKind for $fqName", expectedVersionKind, requirement.kind)
|
||||
assertEquals("Incorrect errorCode for $fqName", expectedErrorCode, requirement.errorCode)
|
||||
}
|
||||
|
||||
for (fqName in fqNamesWithoutRequirement) {
|
||||
val descriptor = module.findUnambiguousDescriptorByFqName(fqName)
|
||||
|
||||
val requirenment = extractRequirement(descriptor)
|
||||
assertNull("Expecting absence of any requirements for $fqName, but `$requirenment`", requirenment)
|
||||
}
|
||||
}
|
||||
|
||||
private fun extractRequirement(descriptor: DeclarationDescriptor): VersionRequirement? {
|
||||
return when (descriptor) {
|
||||
is DeserializedMemberDescriptor -> descriptor.versionRequirements.singleOrNull()
|
||||
is DeserializedClassDescriptor -> descriptor.versionRequirements.singleOrNull()
|
||||
else -> throw AssertionError("Unknown descriptor: $descriptor")
|
||||
}
|
||||
}
|
||||
|
||||
private fun ModuleDescriptor.findUnambiguousDescriptorByFqName(fqName: String): DeclarationDescriptor {
|
||||
@@ -71,7 +85,12 @@ abstract class AbstractVersionRequirementTest : TestCaseWithTmpdir() {
|
||||
return descriptor
|
||||
}
|
||||
|
||||
protected abstract fun compileFiles(files: List<File>, outputDirectory: File, languageVersion: LanguageVersion)
|
||||
protected abstract fun compileFiles(
|
||||
files: List<File>,
|
||||
outputDirectory: File,
|
||||
languageVersion: LanguageVersion,
|
||||
analysisFlags: Map<AnalysisFlag<*>, Any?>
|
||||
)
|
||||
|
||||
protected abstract fun loadModule(directory: File): ModuleDescriptor
|
||||
|
||||
@@ -79,7 +98,7 @@ abstract class AbstractVersionRequirementTest : TestCaseWithTmpdir() {
|
||||
doTest(
|
||||
VersionRequirement.Version(1, 3), DeprecationLevel.ERROR, null, ProtoBuf.VersionRequirement.VersionKind.LANGUAGE_VERSION, null,
|
||||
customLanguageVersion = LanguageVersion.KOTLIN_1_3,
|
||||
fqNames = listOf(
|
||||
fqNamesWithRequirements = listOf(
|
||||
"test.topLevel",
|
||||
"test.Foo.member",
|
||||
"test.Foo.<init>",
|
||||
@@ -96,7 +115,7 @@ abstract class AbstractVersionRequirementTest : TestCaseWithTmpdir() {
|
||||
doTest(
|
||||
VersionRequirement.Version(1, 1), DeprecationLevel.WARNING, "message",
|
||||
ProtoBuf.VersionRequirement.VersionKind.LANGUAGE_VERSION, 42,
|
||||
fqNames = listOf(
|
||||
fqNamesWithRequirements = listOf(
|
||||
"test.Klass",
|
||||
"test.Konstructor.<init>",
|
||||
"test.Typealias",
|
||||
@@ -109,7 +128,7 @@ abstract class AbstractVersionRequirementTest : TestCaseWithTmpdir() {
|
||||
fun testApiVersionViaAnnotation() {
|
||||
doTest(
|
||||
VersionRequirement.Version(1, 1), DeprecationLevel.WARNING, "message", ProtoBuf.VersionRequirement.VersionKind.API_VERSION, 42,
|
||||
fqNames = listOf(
|
||||
fqNamesWithRequirements = listOf(
|
||||
"test.Klass",
|
||||
"test.Konstructor.<init>",
|
||||
"test.Typealias",
|
||||
@@ -123,7 +142,7 @@ abstract class AbstractVersionRequirementTest : TestCaseWithTmpdir() {
|
||||
doTest(
|
||||
VersionRequirement.Version(1, 1), DeprecationLevel.WARNING, "message",
|
||||
ProtoBuf.VersionRequirement.VersionKind.COMPILER_VERSION, 42,
|
||||
fqNames = listOf(
|
||||
fqNamesWithRequirements = listOf(
|
||||
"test.Klass",
|
||||
"test.Konstructor.<init>",
|
||||
"test.Typealias",
|
||||
@@ -137,7 +156,7 @@ abstract class AbstractVersionRequirementTest : TestCaseWithTmpdir() {
|
||||
doTest(
|
||||
VersionRequirement.Version(1, 1, 50), DeprecationLevel.HIDDEN, null,
|
||||
ProtoBuf.VersionRequirement.VersionKind.LANGUAGE_VERSION, null,
|
||||
fqNames = listOf("test.Klass")
|
||||
fqNamesWithRequirements = listOf("test.Klass")
|
||||
)
|
||||
}
|
||||
|
||||
@@ -145,7 +164,7 @@ abstract class AbstractVersionRequirementTest : TestCaseWithTmpdir() {
|
||||
doTest(
|
||||
VersionRequirement.Version(1, 3), DeprecationLevel.ERROR, null, ProtoBuf.VersionRequirement.VersionKind.LANGUAGE_VERSION, null,
|
||||
customLanguageVersion = LanguageVersion.KOTLIN_1_3,
|
||||
fqNames = listOf(
|
||||
fqNamesWithRequirements = listOf(
|
||||
"test.Outer.Inner.Deep",
|
||||
"test.Outer.Inner.Deep.<init>",
|
||||
"test.Outer.Inner.Deep.f",
|
||||
@@ -160,7 +179,7 @@ abstract class AbstractVersionRequirementTest : TestCaseWithTmpdir() {
|
||||
fun testInlineClassesAndRelevantDeclarations() {
|
||||
doTest(
|
||||
VersionRequirement.Version(1, 3), DeprecationLevel.ERROR, null, ProtoBuf.VersionRequirement.VersionKind.LANGUAGE_VERSION, null,
|
||||
fqNames = listOf(
|
||||
fqNamesWithRequirements = listOf(
|
||||
"test.IC",
|
||||
"test.Ctor.<init>",
|
||||
"test.simpleFun",
|
||||
|
||||
@@ -31,7 +31,12 @@ import org.jetbrains.kotlin.test.TestJdkKind
|
||||
import java.io.File
|
||||
|
||||
class JvmVersionRequirementTest : AbstractVersionRequirementTest() {
|
||||
override fun compileFiles(files: List<File>, outputDirectory: File, languageVersion: LanguageVersion) {
|
||||
override fun compileFiles(
|
||||
files: List<File>,
|
||||
outputDirectory: File,
|
||||
languageVersion: LanguageVersion,
|
||||
analysisFlags: Map<AnalysisFlag<*>, Any?>
|
||||
) {
|
||||
LoadDescriptorUtil.compileKotlinToDirAndGetModule(
|
||||
listOf(File("compiler/testData/versionRequirement/${getTestName(true)}.kt")), outputDirectory,
|
||||
KotlinCoreEnvironment.createForTests(
|
||||
@@ -41,10 +46,7 @@ class JvmVersionRequirementTest : AbstractVersionRequirementTest() {
|
||||
languageVersionSettings = LanguageVersionSettingsImpl(
|
||||
languageVersion,
|
||||
ApiVersion.createByLanguageVersion(languageVersion),
|
||||
mapOf(
|
||||
JvmAnalysisFlags.jvmDefaultMode to JvmDefaultMode.ENABLE,
|
||||
AnalysisFlags.explicitApiVersion to true
|
||||
),
|
||||
analysisFlags.toMap() + mapOf(AnalysisFlags.explicitApiVersion to true),
|
||||
emptyMap()
|
||||
)
|
||||
},
|
||||
@@ -64,24 +66,60 @@ class JvmVersionRequirementTest : AbstractVersionRequirementTest() {
|
||||
fun testJvmDefault() {
|
||||
doTest(
|
||||
VersionRequirement.Version(1, 2, 40), DeprecationLevel.ERROR, null, COMPILER_VERSION, null,
|
||||
fqNames = listOf(
|
||||
analysisFlags = mapOf(JvmAnalysisFlags.jvmDefaultMode to JvmDefaultMode.ENABLE),
|
||||
fqNamesWithRequirements = listOf(
|
||||
"test.Base",
|
||||
"test.Derived"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun testAllJvmDefault() {
|
||||
doTest(
|
||||
VersionRequirement.Version(1, 4, 0), DeprecationLevel.ERROR, null, COMPILER_VERSION, null,
|
||||
analysisFlags = mapOf(JvmAnalysisFlags.jvmDefaultMode to JvmDefaultMode.ALL_INCOMPATIBLE),
|
||||
fqNamesWithRequirements = listOf(
|
||||
"test.Base",
|
||||
"test.Derived",
|
||||
"test.BaseWithProperty",
|
||||
"test.DerivedWithProperty",
|
||||
"test.Empty",
|
||||
"test.EmptyWithNested",
|
||||
"test.WithAbstractDeclaration",
|
||||
"test.DerivedFromWithAbstractDeclaration"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun testAllCompatibilityJvmDefault() {
|
||||
doTest(
|
||||
VersionRequirement.Version(1, 4, 0), DeprecationLevel.ERROR, null, COMPILER_VERSION, null,
|
||||
analysisFlags = mapOf(JvmAnalysisFlags.jvmDefaultMode to JvmDefaultMode.ALL_COMPATIBILITY),
|
||||
fqNamesWithRequirements = emptyList(),
|
||||
fqNamesWithoutRequirement = listOf(
|
||||
"test.Base",
|
||||
"test.Derived",
|
||||
"test.BaseWithProperty",
|
||||
"test.DerivedWithProperty",
|
||||
"test.Empty",
|
||||
"test.EmptyWithNested",
|
||||
"test.WithAbstractDeclaration",
|
||||
"test.DerivedFromWithAbstractDeclaration"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun testJvmFieldInInterfaceCompanion() {
|
||||
doTest(
|
||||
VersionRequirement.Version(1, 2, 70), DeprecationLevel.ERROR, null, COMPILER_VERSION, null,
|
||||
fqNames = listOf("test.Base.Companion.foo")
|
||||
fqNamesWithRequirements = listOf("test.Base.Companion.foo")
|
||||
)
|
||||
}
|
||||
|
||||
fun testInlineParameterNullCheck() {
|
||||
doTest(
|
||||
VersionRequirement.Version(1, 3, 50), DeprecationLevel.ERROR, null, COMPILER_VERSION, null,
|
||||
fqNames = listOf(
|
||||
fqNamesWithRequirements = listOf(
|
||||
"test.doRun",
|
||||
"test.lambdaVarProperty",
|
||||
"test.extensionProperty"
|
||||
@@ -94,7 +132,7 @@ class JvmVersionRequirementTest : AbstractVersionRequirementTest() {
|
||||
doTest(
|
||||
VersionRequirement.Version(1, 1), DeprecationLevel.ERROR, null, LANGUAGE_VERSION, null,
|
||||
customLanguageVersion = LanguageVersion.KOTLIN_1_2,
|
||||
fqNames = listOf(
|
||||
fqNamesWithRequirements = listOf(
|
||||
"test.topLevel",
|
||||
"test.Foo.member",
|
||||
"test.Foo.<init>",
|
||||
|
||||
@@ -8,10 +8,7 @@ package org.jetbrains.kotlin.serialization.js
|
||||
import org.jetbrains.kotlin.cli.common.output.writeAllTo
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.config.ApiVersion
|
||||
import org.jetbrains.kotlin.config.LanguageVersion
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
|
||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||
import org.jetbrains.kotlin.config.*
|
||||
import org.jetbrains.kotlin.context.ContextForNewModule
|
||||
import org.jetbrains.kotlin.context.MutableModuleContext
|
||||
import org.jetbrains.kotlin.context.ProjectContext
|
||||
@@ -33,7 +30,12 @@ import org.jetbrains.kotlin.test.TestJdkKind
|
||||
import java.io.File
|
||||
|
||||
class JsVersionRequirementTest : AbstractVersionRequirementTest() {
|
||||
override fun compileFiles(files: List<File>, outputDirectory: File, languageVersion: LanguageVersion) {
|
||||
override fun compileFiles(
|
||||
files: List<File>,
|
||||
outputDirectory: File,
|
||||
languageVersion: LanguageVersion,
|
||||
analysisFlags: Map<AnalysisFlag<*>, Any?>
|
||||
) {
|
||||
val environment = createEnvironment(languageVersion)
|
||||
val ktFiles = files.map { file -> KotlinTestUtils.createFile(file.name, file.readText(), environment.project) }
|
||||
val trace = BindingTraceContext()
|
||||
|
||||
Reference in New Issue
Block a user