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:
+43
-4
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user