[NI] Prototype for SAM-conversion.

Supported:
- conversion in resolution parts. Also sam-with-receiver is supported automatically
- separate flag for kotlin function with java SAM as parameters

TODO:
- fix overload conflict error when function type is the same byte origin types is ordered
- consider case when parameter type is T, T <:> Runnable
- support vararg of Runnable

[NI] Turn off synthetic scope with SAM adapter functions if NI enabled
This commit is contained in:
Stanislav Erokhin
2018-05-01 23:46:15 +03:00
parent 4b8e95c243
commit 8f0b073c08
48 changed files with 889 additions and 26 deletions
@@ -0,0 +1,36 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.load.java.sam
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
import org.jetbrains.kotlin.load.java.components.SamConversionResolver
import org.jetbrains.kotlin.load.java.descriptors.JavaClassConstructorDescriptor
import org.jetbrains.kotlin.resolve.calls.components.SamConversionTransformer
import org.jetbrains.kotlin.synthetic.hasJavaOriginInHierarchy
import org.jetbrains.kotlin.types.UnwrappedType
class JvmSamConversionTransformer(
private val samResolver: SamConversionResolver,
private val languageVersionSettings: LanguageVersionSettings
) : SamConversionTransformer {
override fun getFunctionTypeForPossibleSamType(possibleSamType: UnwrappedType): UnwrappedType? =
SingleAbstractMethodUtils.getFunctionTypeForSamType(possibleSamType, samResolver)?.unwrap()
override fun shouldRunSamConversionForFunction(candidate: CallableDescriptor): Boolean {
if (languageVersionSettings.supportsFeature(LanguageFeature.SamConversionForKotlinFunctions)) return true
val functionDescriptor = candidate.original as? FunctionDescriptor ?: return false
if (functionDescriptor is TypeAliasConstructorDescriptor &&
functionDescriptor.underlyingConstructorDescriptor is JavaClassConstructorDescriptor) return true
return functionDescriptor.hasJavaOriginInHierarchy()
}
}
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.resolve.jvm.platform
import org.jetbrains.kotlin.container.StorageComponentContainer
import org.jetbrains.kotlin.container.useImpl
import org.jetbrains.kotlin.container.useInstance
import org.jetbrains.kotlin.load.java.sam.JvmSamConversionTransformer
import org.jetbrains.kotlin.load.java.sam.SamConversionResolverImpl
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
import org.jetbrains.kotlin.resolve.PlatformConfigurator
@@ -97,5 +98,6 @@ object JvmPlatformConfigurator : PlatformConfigurator(
container.useImpl<JvmModuleAccessibilityChecker.ClassifierUsage>()
container.useInstance(JvmTypeSpecificityComparator)
container.useImpl<JvmDefaultSuperCallChecker>()
container.useImpl<JvmSamConversionTransformer>()
}
}
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.synthetic
import com.intellij.util.SmartList
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
@@ -59,6 +60,8 @@ class SamAdapterFunctionsScope(
private val deprecationResolver: DeprecationResolver,
private val lookupTracker: LookupTracker
) : SyntheticScope {
private val samViaSyntheticScopeDisabled = languageVersionSettings.supportsFeature(LanguageFeature.NewInference)
private val extensionForFunction =
storageManager.createMemoizedFunctionWithNullableValues<FunctionDescriptor, FunctionDescriptor> { function ->
extensionForFunctionNotCached(function)
@@ -95,6 +98,8 @@ class SamAdapterFunctionsScope(
}
override fun getSyntheticMemberFunctions(receiverTypes: Collection<KotlinType>, name: Name, location: LookupLocation): Collection<FunctionDescriptor> {
if (samViaSyntheticScopeDisabled) return emptyList()
var result: SmartList<FunctionDescriptor>? = null
for (type in receiverTypes) {
for (function in type.memberScope.getContributedFunctions(name, location)) {
@@ -134,6 +139,8 @@ class SamAdapterFunctionsScope(
}
override fun getSyntheticMemberFunctions(receiverTypes: Collection<KotlinType>): Collection<FunctionDescriptor> {
if (samViaSyntheticScopeDisabled) return emptyList()
return receiverTypes.flatMapTo(LinkedHashSet<FunctionDescriptor>()) { type ->
type.memberScope.getContributedDescriptors(DescriptorKindFilter.FUNCTIONS)
.filterIsInstance<FunctionDescriptor>()
@@ -148,12 +155,17 @@ class SamAdapterFunctionsScope(
override fun getSyntheticExtensionProperties(receiverTypes: Collection<KotlinType>): Collection<PropertyDescriptor> = emptyList()
override fun getSyntheticStaticFunctions(scope: ResolutionScope, name: Name, location: LookupLocation): Collection<FunctionDescriptor> {
if (samViaSyntheticScopeDisabled) return emptyList()
return getSamFunctions(scope.getContributedFunctions(name, location), location)
}
override fun getSyntheticConstructors(scope: ResolutionScope, name: Name, location: LookupLocation): Collection<FunctionDescriptor> {
val classifier = scope.getContributedClassifier(name, location) ?: return emptyList()
recordSamLookupsToClassifier(classifier, location)
if (samViaSyntheticScopeDisabled) return listOfNotNull(getSamConstructor(classifier))
return getAllSamConstructors(classifier)
}
@@ -166,16 +178,22 @@ class SamAdapterFunctionsScope(
}
override fun getSyntheticStaticFunctions(scope: ResolutionScope): Collection<FunctionDescriptor> {
if (samViaSyntheticScopeDisabled) return emptyList()
return getSamFunctions(scope.getContributedDescriptors(DescriptorKindFilter.FUNCTIONS), location = null)
}
override fun getSyntheticConstructors(scope: ResolutionScope): Collection<FunctionDescriptor> {
return scope.getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS)
.filterIsInstance<ClassifierDescriptor>()
.flatMap { getAllSamConstructors(it) }
val classifiers = scope.getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS).filterIsInstance<ClassifierDescriptor>()
if (samViaSyntheticScopeDisabled) return classifiers.mapNotNull { getSamConstructor(it) }
return classifiers.flatMap { getAllSamConstructors(it) }
}
override fun getSyntheticConstructor(constructor: ConstructorDescriptor): ConstructorDescriptor? {
if (samViaSyntheticScopeDisabled) return null
return when (constructor) {
is JavaClassConstructorDescriptor -> createJavaSamAdapterConstructor(constructor)
is TypeAliasConstructorDescriptor -> {