From 0e90d538df097a4546c1d741028d13c0eb89adc3 Mon Sep 17 00:00:00 2001 From: Mikhail Zarechenskiy Date: Mon, 18 Nov 2019 13:25:17 +0300 Subject: [PATCH] FIC: propagate info about conversions for deserialized classes --- .../useDeserializedFunInterface.kt | 29 +++++++++++++++++++ ...KlibMetadataModuleDescriptorFactoryImpl.kt | 3 +- .../jvm/JvmBuiltInsPackageFragmentProvider.kt | 6 ++-- .../DeserializationComponentsForJava.kt | 3 +- .../runtime/components/RuntimeModuleData.kt | 6 ++-- .../MetadataPackageFragmentProvider.kt | 6 ++-- .../builtins/BuiltInsLoaderImpl.kt | 4 ++- .../serialization/deserialization/context.kt | 3 +- .../DeserializedClassDescriptor.kt | 7 +++++ .../DeserializerForClassfileDecompiler.kt | 3 +- ...KotlinMetadataDeserializerForDecompiler.kt | 4 ++- ...NativeMetadataDeserializerForDecompiler.kt | 4 ++- ...kotlinJavascriptPackageFragmentProvider.kt | 3 +- 13 files changed, 66 insertions(+), 15 deletions(-) create mode 100644 compiler/testData/compileKotlinAgainstKotlin/useDeserializedFunInterface.kt diff --git a/compiler/testData/compileKotlinAgainstKotlin/useDeserializedFunInterface.kt b/compiler/testData/compileKotlinAgainstKotlin/useDeserializedFunInterface.kt new file mode 100644 index 00000000000..01b95bde8f5 --- /dev/null +++ b/compiler/testData/compileKotlinAgainstKotlin/useDeserializedFunInterface.kt @@ -0,0 +1,29 @@ +// !LANGUAGE: +NewInference +FunctionInterfaceConversion +SamConversionPerArgument +SamConversionForKotlinFunctions + +// FILE: A.kt + +fun interface KRunnable { + fun invoke(): String +} + +fun inA(k: KRunnable): String = k.invoke() + +// FILE: B.kt + +fun inB(k: KRunnable): String = k.invoke() + +fun box(): String { + val first = inA(KRunnable { "O" }) + inB(KRunnable { "K" }) + if (first != "OK") return "fail1: $first" + + val second = inA { "O" } + inB { "K" } + if (second != "OK") return "fail2: $second" + + val f1: () -> String = { "O" } + val f2: () -> String = { "K" } + + val third = inA(f1) + inB(f2) + if (third != "OK") return "fail3: $third" + + return "OK" +} diff --git a/compiler/util-klib-metadata/src/org/jetbrains/kotlin/library/metadata/impl/KlibMetadataModuleDescriptorFactoryImpl.kt b/compiler/util-klib-metadata/src/org/jetbrains/kotlin/library/metadata/impl/KlibMetadataModuleDescriptorFactoryImpl.kt index 28ab4074c8f..9d5c97b7980 100644 --- a/compiler/util-klib-metadata/src/org/jetbrains/kotlin/library/metadata/impl/KlibMetadataModuleDescriptorFactoryImpl.kt +++ b/compiler/util-klib-metadata/src/org/jetbrains/kotlin/library/metadata/impl/KlibMetadataModuleDescriptorFactoryImpl.kt @@ -150,7 +150,8 @@ class KlibMetadataModuleDescriptorFactoryImpl( emptyList(), notFoundClasses, ContractDeserializerImpl(configuration, storageManager), - extensionRegistryLite = KlibMetadataSerializerProtocol.extensionRegistry + extensionRegistryLite = KlibMetadataSerializerProtocol.extensionRegistry, + samConversionResolver = SamConversionResolverImpl(storageManager, samWithReceiverResolvers = emptyList()) ) fragmentsToInitialize.forEach { diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/builtins/jvm/JvmBuiltInsPackageFragmentProvider.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/builtins/jvm/JvmBuiltInsPackageFragmentProvider.kt index 8e4e87046bf..cc59de310c2 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/builtins/jvm/JvmBuiltInsPackageFragmentProvider.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/builtins/jvm/JvmBuiltInsPackageFragmentProvider.kt @@ -28,7 +28,8 @@ class JvmBuiltInsPackageFragmentProvider( additionalClassPartsProvider: AdditionalClassPartsProvider, platformDependentDeclarationFilter: PlatformDependentDeclarationFilter, deserializationConfiguration: DeserializationConfiguration, - kotlinTypeChecker: NewKotlinTypeChecker + kotlinTypeChecker: NewKotlinTypeChecker, + samConversionResolver: SamConversionResolver ) : AbstractDeserializedPackageFragmentProvider(storageManager, finder, moduleDescriptor) { init { components = DeserializationComponents( @@ -50,7 +51,8 @@ class JvmBuiltInsPackageFragmentProvider( ContractDeserializer.DEFAULT, additionalClassPartsProvider, platformDependentDeclarationFilter, BuiltInSerializerProtocol.extensionRegistry, - kotlinTypeChecker + kotlinTypeChecker, + samConversionResolver ) } diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/DeserializationComponentsForJava.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/DeserializationComponentsForJava.kt index 7c82c0f675a..70060296e77 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/DeserializationComponentsForJava.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/DeserializationComponentsForJava.kt @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.descriptors.deserialization.PlatformDependentDeclara import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.load.java.lazy.LazyJavaPackageFragmentProvider import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil +import org.jetbrains.kotlin.resolve.sam.SamConversionResolverImpl import org.jetbrains.kotlin.serialization.deserialization.* import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.types.checker.NewKotlinTypeChecker @@ -55,7 +56,7 @@ class DeserializationComponentsForJava( additionalClassPartsProvider = jvmBuiltIns?.settings ?: AdditionalClassPartsProvider.None, platformDependentDeclarationFilter = jvmBuiltIns?.settings ?: PlatformDependentDeclarationFilter.NoPlatformDependent, extensionRegistryLite = JvmProtoBufUtil.EXTENSION_REGISTRY, - kotlinTypeChecker = kotlinTypeChecker + kotlinTypeChecker = kotlinTypeChecker, samConversionResolver = SamConversionResolverImpl(storageManager, emptyList()) ) } } diff --git a/core/descriptors.runtime/src/org/jetbrains/kotlin/descriptors/runtime/components/RuntimeModuleData.kt b/core/descriptors.runtime/src/org/jetbrains/kotlin/descriptors/runtime/components/RuntimeModuleData.kt index e555a6f1702..1af25bbf58c 100644 --- a/core/descriptors.runtime/src/org/jetbrains/kotlin/descriptors/runtime/components/RuntimeModuleData.kt +++ b/core/descriptors.runtime/src/org/jetbrains/kotlin/descriptors/runtime/components/RuntimeModuleData.kt @@ -29,13 +29,13 @@ import org.jetbrains.kotlin.load.java.AnnotationTypeQualifierResolver import org.jetbrains.kotlin.load.java.JavaClassesTracker import org.jetbrains.kotlin.load.java.components.JavaPropertyInitializerEvaluator import org.jetbrains.kotlin.load.java.components.JavaResolverCache -import org.jetbrains.kotlin.resolve.sam.SamConversionResolver import org.jetbrains.kotlin.load.java.components.SignaturePropagator import org.jetbrains.kotlin.load.java.lazy.* import org.jetbrains.kotlin.load.java.typeEnhancement.SignatureEnhancement import org.jetbrains.kotlin.load.kotlin.* import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.jvm.JavaDescriptorResolver +import org.jetbrains.kotlin.resolve.sam.SamConversionResolverImpl import org.jetbrains.kotlin.serialization.deserialization.ContractDeserializer import org.jetbrains.kotlin.serialization.deserialization.DeserializationComponents import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration @@ -85,7 +85,7 @@ class RuntimeModuleData private constructor( val stdlibClassLoader = Unit::class.java.classLoader val builtinsProvider = JvmBuiltInsPackageFragmentProvider( storageManager, ReflectKotlinClassFinder(stdlibClassLoader), module, notFoundClasses, builtIns.settings, builtIns.settings, - DeserializationConfiguration.Default, NewKotlinTypeChecker.Default + DeserializationConfiguration.Default, NewKotlinTypeChecker.Default, SamConversionResolverImpl(storageManager, emptyList()) ) module.setDependencies(module) @@ -113,7 +113,7 @@ fun makeLazyJavaPackageFragmentFromClassLoaderProvider( val javaResolverComponents = JavaResolverComponents( storageManager, ReflectJavaClassFinder(classLoader), reflectKotlinClassFinder, deserializedDescriptorResolver, SignaturePropagator.DO_NOTHING, RuntimeErrorReporter, JavaResolverCache.EMPTY, - JavaPropertyInitializerEvaluator.DoNothing, SamConversionResolver.Empty, RuntimeSourceElementFactory, + JavaPropertyInitializerEvaluator.DoNothing, SamConversionResolverImpl(storageManager, emptyList()), RuntimeSourceElementFactory, singleModuleClassResolver, packagePartProvider, SupertypeLoopChecker.EMPTY, LookupTracker.DO_NOTHING, module, ReflectionTypes(module, notFoundClasses), annotationTypeQualifierResolver, SignatureEnhancement(annotationTypeQualifierResolver, Jsr305State.DISABLED), diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/MetadataPackageFragmentProvider.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/MetadataPackageFragmentProvider.kt index d7789808532..61b63f2ab97 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/MetadataPackageFragmentProvider.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/MetadataPackageFragmentProvider.kt @@ -44,7 +44,8 @@ class MetadataPackageFragmentProvider( notFoundClasses: NotFoundClasses, private val metadataPartProvider: MetadataPartProvider, contractDeserializer: ContractDeserializer, - kotlinTypeChecker: NewKotlinTypeChecker + kotlinTypeChecker: NewKotlinTypeChecker, + samConversionResolver: SamConversionResolver ) : AbstractDeserializedPackageFragmentProvider(storageManager, finder, moduleDescriptor) { init { components = DeserializationComponents( @@ -63,7 +64,8 @@ class MetadataPackageFragmentProvider( contractDeserializer, AdditionalClassPartsProvider.None, PlatformDependentDeclarationFilter.All, BuiltInSerializerProtocol.extensionRegistry, - kotlinTypeChecker + kotlinTypeChecker, + samConversionResolver ) } diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/builtins/BuiltInsLoaderImpl.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/builtins/BuiltInsLoaderImpl.kt index 0b412a80437..4f03076e87e 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/builtins/BuiltInsLoaderImpl.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/builtins/BuiltInsLoaderImpl.kt @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.descriptors.deserialization.ClassDescriptorFactory import org.jetbrains.kotlin.descriptors.deserialization.PlatformDependentDeclarationFilter import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.resolve.sam.SamConversionResolverImpl import org.jetbrains.kotlin.serialization.deserialization.* import org.jetbrains.kotlin.storage.StorageManager import java.io.InputStream @@ -78,7 +79,8 @@ class BuiltInsLoaderImpl : BuiltInsLoader { ContractDeserializer.DEFAULT, additionalClassPartsProvider, platformDependentDeclarationFilter, - BuiltInSerializerProtocol.extensionRegistry + BuiltInSerializerProtocol.extensionRegistry, + samConversionResolver = SamConversionResolverImpl(storageManager, samWithReceiverResolvers = emptyList()) ) for (packageFragment in packageFragments) { diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/context.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/context.kt index c716c073b9e..41385ac59eb 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/context.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/context.kt @@ -49,7 +49,8 @@ class DeserializationComponents( val additionalClassPartsProvider: AdditionalClassPartsProvider = AdditionalClassPartsProvider.None, val platformDependentDeclarationFilter: PlatformDependentDeclarationFilter = PlatformDependentDeclarationFilter.All, val extensionRegistryLite: ExtensionRegistryLite, - val kotlinTypeChecker: NewKotlinTypeChecker = NewKotlinTypeChecker.Default + val kotlinTypeChecker: NewKotlinTypeChecker = NewKotlinTypeChecker.Default, + val samConversionResolver: SamConversionResolver ) { val classDeserializer: ClassDeserializer = ClassDeserializer(this) diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt index 521911899c4..acf9b659887 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.resolve.scopes.StaticScopeForKotlinEnum import org.jetbrains.kotlin.serialization.deserialization.* import org.jetbrains.kotlin.types.AbstractClassTypeConstructor import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.SimpleType import org.jetbrains.kotlin.types.TypeConstructor import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner import org.jetbrains.kotlin.types.refinement.TypeRefinement @@ -172,6 +173,12 @@ class DeserializedClassDescriptor( override fun getDeclaredTypeParameters() = c.typeDeserializer.ownTypeParameters + override fun getDefaultFunctionTypeForSamInterface(): SimpleType? { + return c.components.samConversionResolver.resolveFunctionTypeIfSamInterface(this) + } + + override fun isDefinitelyNotSamInterface() = !isFun + private inner class DeserializedClassTypeConstructor : AbstractClassTypeConstructor(c.storageManager) { private val parameters = c.storageManager.createLazyValue { this@DeserializedClassDescriptor.computeConstructorTypeParameters() diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/classFile/DeserializerForClassfileDecompiler.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/classFile/DeserializerForClassfileDecompiler.kt index 7d18d6a2cf3..7d52c056de7 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/classFile/DeserializerForClassfileDecompiler.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/classFile/DeserializerForClassfileDecompiler.kt @@ -66,7 +66,8 @@ class DeserializerForClassfileDecompiler( packageFragmentProvider, ResolveEverythingToKotlinAnyLocalClassifierResolver(builtIns), LoggingErrorReporter(LOG), LookupTracker.DO_NOTHING, JavaFlexibleTypeDeserializer, emptyList(), notFoundClasses, ContractDeserializerImpl(configuration, storageManager), - extensionRegistryLite = JvmProtoBufUtil.EXTENSION_REGISTRY + extensionRegistryLite = JvmProtoBufUtil.EXTENSION_REGISTRY, + samConversionResolver = SamConversionResolverImpl(storageManager, samWithReceiverResolvers = emptyList()) ) } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/common/KotlinMetadataDeserializerForDecompiler.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/common/KotlinMetadataDeserializerForDecompiler.kt index 7c1ce11b3f2..baeabc8ad0f 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/common/KotlinMetadataDeserializerForDecompiler.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/common/KotlinMetadataDeserializerForDecompiler.kt @@ -18,6 +18,7 @@ import org.jetbrains.kotlin.metadata.ProtoBuf import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion import org.jetbrains.kotlin.metadata.deserialization.NameResolver import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.resolve.sam.SamConversionResolverImpl import org.jetbrains.kotlin.serialization.SerializerExtensionProtocol import org.jetbrains.kotlin.serialization.deserialization.* import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPackageMemberScope @@ -44,7 +45,8 @@ class KotlinMetadataDeserializerForDecompiler( ResolveEverythingToKotlinAnyLocalClassifierResolver(builtIns), LoggingErrorReporter(LOG), LookupTracker.DO_NOTHING, flexibleTypeDeserializer, emptyList(), notFoundClasses, ContractDeserializer.DEFAULT, - extensionRegistryLite = serializerProtocol.extensionRegistry + extensionRegistryLite = serializerProtocol.extensionRegistry, + samConversionResolver = SamConversionResolverImpl(storageManager, samWithReceiverResolvers = emptyList()) ) } diff --git a/idea/idea-native/src/org/jetbrains/kotlin/ide/konan/decompiler/KotlinNativeMetadataDeserializerForDecompiler.kt b/idea/idea-native/src/org/jetbrains/kotlin/ide/konan/decompiler/KotlinNativeMetadataDeserializerForDecompiler.kt index 4c3555a7041..bf5d8c103bb 100644 --- a/idea/idea-native/src/org/jetbrains/kotlin/ide/konan/decompiler/KotlinNativeMetadataDeserializerForDecompiler.kt +++ b/idea/idea-native/src/org/jetbrains/kotlin/ide/konan/decompiler/KotlinNativeMetadataDeserializerForDecompiler.kt @@ -19,6 +19,7 @@ import org.jetbrains.kotlin.library.metadata.KlibMetadataClassDataFinder import org.jetbrains.kotlin.metadata.ProtoBuf import org.jetbrains.kotlin.metadata.deserialization.NameResolver import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.resolve.sam.SamConversionResolverImpl import org.jetbrains.kotlin.serialization.SerializerExtensionProtocol import org.jetbrains.kotlin.serialization.deserialization.* import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPackageMemberScope @@ -43,7 +44,8 @@ class KotlinNativeMetadataDeserializerForDecompiler( AnnotationAndConstantLoaderImpl(moduleDescriptor, notFoundClasses, serializerProtocol), packageFragmentProvider, ResolveEverythingToKotlinAnyLocalClassifierResolver(builtIns), createLoggingErrorReporter(LOG), LookupTracker.DO_NOTHING, flexibleTypeDeserializer, emptyList(), notFoundClasses, ContractDeserializer.DEFAULT, - extensionRegistryLite = serializerProtocol.extensionRegistry + extensionRegistryLite = serializerProtocol.extensionRegistry, + samConversionResolver = SamConversionResolverImpl(storageManager, samWithReceiverResolvers = emptyList()) ) } diff --git a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/kotlinJavascriptPackageFragmentProvider.kt b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/kotlinJavascriptPackageFragmentProvider.kt index 5a3d39f711f..b029c2b68ea 100644 --- a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/kotlinJavascriptPackageFragmentProvider.kt +++ b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/kotlinJavascriptPackageFragmentProvider.kt @@ -79,7 +79,8 @@ fun createKotlinJavascriptPackageFragmentProvider( notFoundClasses, ContractDeserializerImpl(configuration, storageManager), platformDependentDeclarationFilter = PlatformDependentDeclarationFilter.NoPlatformDependent, - extensionRegistryLite = JsSerializerProtocol.extensionRegistry + extensionRegistryLite = JsSerializerProtocol.extensionRegistry, + samConversionResolver = SamConversionResolverImpl(storageManager, samWithReceiverResolvers = emptyList()) ) for (packageFragment in packageFragments.filterIsInstance()) {