Improve 1.0-compatibility mode for JDK dependent members

Just reporting error by call checker may be too restrictive
in case there are some extensions that can be used successfully

Solution is to annotate additional members with
@Deprecated(level=Error) + @kotlin.internal.LowPriorityInOverloadResolution
This commit is contained in:
Denis Zharkov
2016-09-21 16:31:04 +03:00
parent a7dedfab70
commit 5381c06936
10 changed files with 86 additions and 33 deletions
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.load.kotlin
import org.jetbrains.kotlin.builtins.BuiltInsInitializer
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptorImpl
import org.jetbrains.kotlin.descriptors.annotations.AnnotationsImpl
import org.jetbrains.kotlin.descriptors.annotations.createDeprecatedAnnotation
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl
@@ -31,6 +32,7 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
import org.jetbrains.kotlin.platform.createMappedTypeParametersSubstitution
import org.jetbrains.kotlin.resolve.OverridingUtil
import org.jetbrains.kotlin.resolve.descriptorUtil.LOW_PRIORITY_IN_OVERLOAD_RESOLUTION_FQ_NAME
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
@@ -47,17 +49,20 @@ import org.jetbrains.kotlin.types.LazyWrappedType
import org.jetbrains.kotlin.utils.DFS
import org.jetbrains.kotlin.utils.SmartSet
import org.jetbrains.kotlin.utils.addToStdlib.check
import org.jetbrains.kotlin.utils.addToStdlib.singletonList
import java.io.Serializable
import java.util.*
open class JvmBuiltInsSettings(
private val moduleDescriptor: ModuleDescriptor,
storageManager: StorageManager,
deferredOwnerModuleDescriptor: () -> ModuleDescriptor
deferredOwnerModuleDescriptor: () -> ModuleDescriptor,
isAdditionalBuiltInsFeatureSupported: () -> Boolean
) : AdditionalClassPartsProvider, PlatformDependentDeclarationFilter {
private val j2kClassMap = JavaToKotlinClassMap.INSTANCE
private val ownerModuleDescriptor: ModuleDescriptor by lazy(deferredOwnerModuleDescriptor)
private val isAdditionalBuiltInsFeatureSupported: Boolean by lazy(isAdditionalBuiltInsFeatureSupported)
private val mockSerializableType = storageManager.createMockJavaIoSerializableType()
@@ -70,6 +75,28 @@ open class JvmBuiltInsSettings(
).let { AnnotationsImpl(listOf(it)) }
}
private val notSupportedDeprecation by storageManager.createLazyValue {
// We use both LowPriorityInOverloadResolution to achieve the following goals:
// - If there is something to resolve to beside an additional built-in member, it's *almost* always will win
// - Otherwise error will be reported because of Deprecated annotation with Error level
val lowPriorityAnnotation =
ClassDescriptorImpl(
moduleDescriptor.getPackage(LOW_PRIORITY_IN_OVERLOAD_RESOLUTION_FQ_NAME.parent()),
LOW_PRIORITY_IN_OVERLOAD_RESOLUTION_FQ_NAME.shortName(), Modality.FINAL, ClassKind.ANNOTATION_CLASS,
moduleDescriptor.builtIns.anyType.singletonList(), SourceElement.NO_SOURCE
).run {
initialize(MemberScope.Empty, emptySet(), null)
AnnotationDescriptorImpl(defaultType, emptyMap(), SourceElement.NO_SOURCE)
}
val errorDeprecation = moduleDescriptor.builtIns.createDeprecatedAnnotation(
"This member is not supported by Kotlin compiler on this language level",
level = DeprecationLevel.ERROR.name
)
AnnotationsImpl(listOf(lowPriorityAnnotation, errorDeprecation))
}
private fun StorageManager.createMockJavaIoSerializableType(): KotlinType {
val mockJavaIoPackageFragment = object : PackageFragmentDescriptorImpl(moduleDescriptor, FqName("java.io")) {
override fun getMemberScope() = MemberScope.Empty
@@ -120,12 +147,21 @@ open class JvmBuiltInsSettings(
}
JDKMemberStatus.NOT_CONSIDERED -> {
setAdditionalAnnotations(notConsideredDeprecation)
if (!isAdditionalBuiltInsFeatureSupported) {
setAdditionalAnnotations(notSupportedDeprecation)
}
else {
setAdditionalAnnotations(notConsideredDeprecation)
}
}
JDKMemberStatus.DROP -> return@mapNotNull null
JDKMemberStatus.WHITE_LIST -> {} // Do nothing
JDKMemberStatus.WHITE_LIST -> {
if (!isAdditionalBuiltInsFeatureSupported) {
setAdditionalAnnotations(notSupportedDeprecation)
}
}
}
}.build()!!
@@ -260,7 +296,10 @@ open class JvmBuiltInsSettings(
setPreserveSourceElement()
setSubstitution(substitutor.substitution)
if (SignatureBuildingComponents.signature(javaAnalogueDescriptor, javaConstructor.computeJvmDescriptor()) !in WHITE_LIST_CONSTRUCTOR_SIGNATURES) {
if (!isAdditionalBuiltInsFeatureSupported) {
setAdditionalAnnotations(notSupportedDeprecation)
}
else if (SignatureBuildingComponents.signature(javaAnalogueDescriptor, javaConstructor.computeJvmDescriptor()) !in WHITE_LIST_CONSTRUCTOR_SIGNATURES) {
setAdditionalAnnotations(notConsideredDeprecation)
}
@@ -26,10 +26,12 @@ import org.jetbrains.kotlin.utils.sure
class JvmBuiltIns(storageManager: StorageManager) : KotlinBuiltIns(storageManager) {
// Module containing JDK classes or having them among dependencies
private var ownerModuleDescriptor: ModuleDescriptor? = null
private var isAdditionalBuiltInsFeatureSupported: Boolean = true
fun initialize(moduleDescriptor: ModuleDescriptor) {
fun initialize(moduleDescriptor: ModuleDescriptor, isAdditionalBuiltInsFeatureSupported: Boolean) {
assert(ownerModuleDescriptor == null) { "JvmBuiltins repeated initialization" }
this.ownerModuleDescriptor = moduleDescriptor
this.isAdditionalBuiltInsFeatureSupported = isAdditionalBuiltInsFeatureSupported
}
lateinit var settings: JvmBuiltInsSettings
@@ -39,7 +41,8 @@ class JvmBuiltIns(storageManager: StorageManager) : KotlinBuiltIns(storageManage
override fun getPlatformDependentDeclarationFilter(): PlatformDependentDeclarationFilter {
settings = JvmBuiltInsSettings(
builtInsModule, storageManager,
{ ownerModuleDescriptor.sure { "JvmBuiltins has not been initialized properly" } }
{ ownerModuleDescriptor.sure { "JvmBuiltins has not been initialized properly" } },
{ isAdditionalBuiltInsFeatureSupported }
)
return settings