diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/sam/SamAdapterDescriptor.java b/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/sam/SamAdapterDescriptor.java index 2561a31b25f..5b6e140e250 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/sam/SamAdapterDescriptor.java +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/sam/SamAdapterDescriptor.java @@ -17,9 +17,10 @@ package org.jetbrains.kotlin.load.java.sam; import org.jetbrains.kotlin.descriptors.FunctionDescriptor; +import org.jetbrains.kotlin.descriptors.synthetic.FunctionInterfaceAdapterDescriptor; import org.jetbrains.kotlin.descriptors.synthetic.SyntheticMemberDescriptor; import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor; -public interface SamAdapterDescriptor extends FunctionDescriptor, JavaCallableMemberDescriptor, - SyntheticMemberDescriptor { +public interface SamAdapterDescriptor + extends FunctionDescriptor, JavaCallableMemberDescriptor, FunctionInterfaceAdapterDescriptor { } diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/sam/SamConstructorDescriptor.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/sam/SamConstructorDescriptor.kt index d524b402a6a..2b0a78192d4 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/sam/SamConstructorDescriptor.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/sam/SamConstructorDescriptor.kt @@ -21,21 +21,21 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl -import org.jetbrains.kotlin.descriptors.synthetic.SyntheticMemberDescriptor +import org.jetbrains.kotlin.descriptors.synthetic.FunctionInterfaceConstructorDescriptor import org.jetbrains.kotlin.resolve.scopes.DescriptorKindExclude -interface SamConstructorDescriptor : SimpleFunctionDescriptor, SyntheticMemberDescriptor +interface SamConstructorDescriptor : SimpleFunctionDescriptor, FunctionInterfaceConstructorDescriptor class SamConstructorDescriptorImpl( - containingDeclaration: DeclarationDescriptor, - private val samInterface: ClassDescriptor + containingDeclaration: DeclarationDescriptor, + private val samInterface: ClassDescriptor ) : SimpleFunctionDescriptorImpl( - containingDeclaration, - null, - samInterface.annotations, - samInterface.name, - CallableMemberDescriptor.Kind.SYNTHESIZED, - samInterface.source + containingDeclaration, + null, + samInterface.annotations, + samInterface.name, + CallableMemberDescriptor.Kind.SYNTHESIZED, + samInterface.source ), SamConstructorDescriptor { override val baseDescriptorForSynthetic: ClassDescriptor get() = samInterface diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/SamAdapterFunctionsScope.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/SamAdapterFunctionsScope.kt index b6f3c74455f..b0b7369c90f 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/SamAdapterFunctionsScope.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/SamAdapterFunctionsScope.kt @@ -22,22 +22,22 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptorImpl -import org.jetbrains.kotlin.descriptors.synthetic.SyntheticMemberDescriptor +import org.jetbrains.kotlin.descriptors.synthetic.FunctionInterfaceAdapterExtensionFunctionDescriptor import org.jetbrains.kotlin.incremental.components.LookupLocation import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.incremental.record -import org.jetbrains.kotlin.resolve.sam.SamConversionResolver import org.jetbrains.kotlin.load.java.descriptors.JavaClassConstructorDescriptor import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor +import org.jetbrains.kotlin.load.java.sam.JavaSingleAbstractMethodUtils import org.jetbrains.kotlin.load.java.sam.SamAdapterDescriptor import org.jetbrains.kotlin.load.java.sam.SamConstructorDescriptor -import org.jetbrains.kotlin.load.java.sam.JavaSingleAbstractMethodUtils import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.calls.components.isVararg import org.jetbrains.kotlin.resolve.calls.inference.wrapWithCapturingSubstitution import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver import org.jetbrains.kotlin.resolve.sam.SamConversionOracle +import org.jetbrains.kotlin.resolve.sam.SamConversionResolver import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.ResolutionScope import org.jetbrains.kotlin.resolve.scopes.SyntheticScope @@ -46,7 +46,7 @@ import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.checker.findCorrespondingSupertype import kotlin.properties.Delegates -interface SamAdapterExtensionFunctionDescriptor : FunctionDescriptor, SyntheticMemberDescriptor { +interface SamAdapterExtensionFunctionDescriptor : FunctionDescriptor, FunctionInterfaceAdapterExtensionFunctionDescriptor { override val baseDescriptorForSynthetic: FunctionDescriptor } @@ -64,33 +64,32 @@ class SamAdapterFunctionsScope( private val shouldGenerateAdditionalSamCandidate = !samViaSyntheticScopeDisabled || shouldGenerateCandidateForVarargAfterSam private val extensionForFunction = - storageManager.createMemoizedFunctionWithNullableValues { function -> - extensionForFunctionNotCached(function) - } + storageManager.createMemoizedFunctionWithNullableValues { function -> + extensionForFunctionNotCached(function) + } private val samAdapterForStaticFunction = - storageManager.createMemoizedFunction> { function -> - JavaSingleAbstractMethodUtils - .createSamAdapterFunction(function, samResolver, samConversionOracle) - } + storageManager.createMemoizedFunction> { function -> + JavaSingleAbstractMethodUtils + .createSamAdapterFunction(function, samResolver, samConversionOracle) + } private val samConstructorForClassifier = - storageManager.createMemoizedFunction { classifier -> - JavaSingleAbstractMethodUtils - .createSamConstructorFunction(classifier.containingDeclaration, classifier, samResolver, samConversionOracle) - } + storageManager.createMemoizedFunction { classifier -> + JavaSingleAbstractMethodUtils + .createSamConstructorFunction(classifier.containingDeclaration, classifier, samResolver, samConversionOracle) + } private val samConstructorForJavaConstructor = - storageManager.createMemoizedFunction { constructor -> - JavaSingleAbstractMethodUtils - .createSamAdapterConstructor(constructor, samResolver, samConversionOracle) as ClassConstructorDescriptor - } + storageManager.createMemoizedFunction { constructor -> + JavaSingleAbstractMethodUtils + .createSamAdapterConstructor(constructor, samResolver, samConversionOracle) as ClassConstructorDescriptor + } private val samConstructorForTypeAliasConstructor = - storageManager.createMemoizedFunctionWithNullableValues, TypeAliasConstructorDescriptor> { - (constructor, typeAliasDescriptor) -> - TypeAliasConstructorDescriptorImpl.createIfAvailable(storageManager, typeAliasDescriptor, constructor) - } + storageManager.createMemoizedFunctionWithNullableValues, TypeAliasConstructorDescriptor> { (constructor, typeAliasDescriptor) -> + TypeAliasConstructorDescriptorImpl.createIfAvailable(storageManager, typeAliasDescriptor, constructor) + } private fun extensionForFunctionNotCached(function: FunctionDescriptor): FunctionDescriptor? { if (!function.visibility.isVisibleOutside()) return null @@ -144,10 +143,10 @@ class SamAdapterFunctionsScope( val correspondingSupertype = findCorrespondingSupertype(receiverType, containingClass.defaultType) ?: return null return substitute( - TypeConstructorSubstitution - .create(correspondingSupertype) - .wrapWithCapturingSubstitution(needApproximation = true) - .buildSubstitutor() + TypeConstructorSubstitution + .create(correspondingSupertype) + .wrapWithCapturingSubstitution(needApproximation = true) + .buildSubstitutor() ) } @@ -225,8 +224,8 @@ class SamAdapterFunctionsScope( } private fun getSamFunctions( - functions: Collection, - location: LookupLocation? + functions: Collection, + location: LookupLocation? ): List> { if (!shouldGenerateAdditionalSamCandidate) return emptyList() @@ -274,18 +273,19 @@ class SamAdapterFunctionsScope( if (!JavaSingleAbstractMethodUtils.isSamClassDescriptor(classDescriptor)) return null return JavaSingleAbstractMethodUtils.createTypeAliasSamConstructorFunction( - classifier, samConstructorForClassifier(classDescriptor), samResolver, samConversionOracle + classifier, samConstructorForClassifier(classDescriptor), samResolver, samConversionOracle ) } private class SamAdapterExtensionFunctionDescriptorImpl( - containingDeclaration: DeclarationDescriptor, - original: SimpleFunctionDescriptor?, - annotations: Annotations, - name: Name, - kind: CallableMemberDescriptor.Kind, - source: SourceElement - ) : SamAdapterExtensionFunctionDescriptor, SimpleFunctionDescriptorImpl(containingDeclaration, original, annotations, name, kind, source) { + containingDeclaration: DeclarationDescriptor, + original: SimpleFunctionDescriptor?, + annotations: Annotations, + name: Name, + kind: CallableMemberDescriptor.Kind, + source: SourceElement + ) : SamAdapterExtensionFunctionDescriptor, + SimpleFunctionDescriptorImpl(containingDeclaration, original, annotations, name, kind, source) { override var baseDescriptorForSynthetic: FunctionDescriptor by Delegates.notNull() private set @@ -301,29 +301,33 @@ class SamAdapterFunctionsScope( samConversionOracle: SamConversionOracle ): SamAdapterExtensionFunctionDescriptorImpl { val descriptor = SamAdapterExtensionFunctionDescriptorImpl( - sourceFunction.containingDeclaration, - null, - sourceFunction.annotations, - sourceFunction.name, - CallableMemberDescriptor.Kind.SYNTHESIZED, - sourceFunction.original.source) + sourceFunction.containingDeclaration, + null, + sourceFunction.annotations, + sourceFunction.name, + CallableMemberDescriptor.Kind.SYNTHESIZED, + sourceFunction.original.source + ) descriptor.baseDescriptorForSynthetic = sourceFunction val sourceTypeParams = (sourceFunction.typeParameters).toMutableList() val ownerClass = sourceFunction.containingDeclaration as ClassDescriptor val typeParameters = ArrayList(sourceTypeParams.size) - val typeSubstitutor = DescriptorSubstitutor.substituteTypeParameters(sourceTypeParams, TypeSubstitution.EMPTY, descriptor, typeParameters) + val typeSubstitutor = + DescriptorSubstitutor.substituteTypeParameters(sourceTypeParams, TypeSubstitution.EMPTY, descriptor, typeParameters) val returnType = typeSubstitutor.safeSubstitute(sourceFunction.returnType!!, Variance.INVARIANT) val valueParameters = JavaSingleAbstractMethodUtils.createValueParametersForSamAdapter( - sourceFunction, descriptor, typeSubstitutor, samResolver, samConversionOracle + sourceFunction, descriptor, typeSubstitutor, samResolver, samConversionOracle ) val visibility = syntheticVisibility(sourceFunction, isUsedForExtension = false) - descriptor.initialize(null, ownerClass.thisAsReceiverParameter, typeParameters, valueParameters, returnType, - Modality.FINAL, visibility) + descriptor.initialize( + null, ownerClass.thisAsReceiverParameter, typeParameters, valueParameters, returnType, + Modality.FINAL, visibility + ) descriptor.isOperator = sourceFunction.isOperator descriptor.isInfix = sourceFunction.isInfix @@ -336,33 +340,33 @@ class SamAdapterFunctionsScope( override fun hasSynthesizedParameterNames() = baseDescriptorForSynthetic.hasSynthesizedParameterNames() override fun createSubstitutedCopy( - newOwner: DeclarationDescriptor, - original: FunctionDescriptor?, - kind: CallableMemberDescriptor.Kind, - newName: Name?, - annotations: Annotations, - source: SourceElement + newOwner: DeclarationDescriptor, + original: FunctionDescriptor?, + kind: CallableMemberDescriptor.Kind, + newName: Name?, + annotations: Annotations, + source: SourceElement ): SamAdapterExtensionFunctionDescriptorImpl { return SamAdapterExtensionFunctionDescriptorImpl( - containingDeclaration, original as SimpleFunctionDescriptor?, annotations, newName ?: name, kind, source + containingDeclaration, original as SimpleFunctionDescriptor?, annotations, newName ?: name, kind, source ).apply { baseDescriptorForSynthetic = this@SamAdapterExtensionFunctionDescriptorImpl.baseDescriptorForSynthetic } } override fun newCopyBuilder(substitutor: TypeSubstitutor): CopyConfiguration = - super.newCopyBuilder(substitutor).setOriginal(this.original) + super.newCopyBuilder(substitutor).setOriginal(this.original) override fun doSubstitute(configuration: CopyConfiguration): FunctionDescriptor? { val descriptor = super.doSubstitute(configuration) as SamAdapterExtensionFunctionDescriptorImpl? ?: return null val original = configuration.original - ?: throw UnsupportedOperationException("doSubstitute with no original should not be called for synthetic extension $this") + ?: throw UnsupportedOperationException("doSubstitute with no original should not be called for synthetic extension $this") original as SamAdapterExtensionFunctionDescriptorImpl assert(original.original == original) { "original in doSubstitute should have no other original" } val sourceFunctionSubstitutor = - CompositionTypeSubstitution(configuration.substitution, fromSourceFunctionTypeParameters).buildSubstitutor() + CompositionTypeSubstitution(configuration.substitution, fromSourceFunctionTypeParameters).buildSubstitutor() descriptor.baseDescriptorForSynthetic = original.baseDescriptorForSynthetic.substitute(sourceFunctionSubstitutor) ?: return null return descriptor diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmGeneratorExtensions.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmGeneratorExtensions.kt index a63b73159fa..892db7e7212 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmGeneratorExtensions.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmGeneratorExtensions.kt @@ -7,7 +7,10 @@ package org.jetbrains.kotlin.backend.jvm import org.jetbrains.kotlin.backend.common.ir.createParameterDeclarations import org.jetbrains.kotlin.codegen.SamType -import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.descriptors.PropertyDescriptor +import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor +import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.descriptors.annotations.FilteredAnnotations import org.jetbrains.kotlin.ir.builders.declarations.buildClass import org.jetbrains.kotlin.ir.declarations.IrClass @@ -15,8 +18,6 @@ import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin import org.jetbrains.kotlin.load.java.JvmAnnotationNames import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor -import org.jetbrains.kotlin.load.java.sam.SamAdapterDescriptor -import org.jetbrains.kotlin.load.java.sam.SamConstructorDescriptor import org.jetbrains.kotlin.load.java.sam.JavaSingleAbstractMethodUtils import org.jetbrains.kotlin.load.java.typeEnhancement.hasEnhancedNullability import org.jetbrains.kotlin.load.kotlin.JvmPackagePartSource @@ -24,12 +25,7 @@ import org.jetbrains.kotlin.psi2ir.generators.GeneratorExtensions import org.jetbrains.kotlin.resolve.jvm.JvmClassName import org.jetbrains.kotlin.resolve.jvm.annotations.hasJvmFieldAnnotation import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource -import org.jetbrains.kotlin.resolve.sam.getFunctionTypeForAbstractMethod -import org.jetbrains.kotlin.resolve.sam.getSingleAbstractMethodOrNull -import org.jetbrains.kotlin.synthetic.SamAdapterExtensionFunctionDescriptor import org.jetbrains.kotlin.types.KotlinType -import org.jetbrains.kotlin.types.TypeSubstitutor -import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.typeUtil.replaceAnnotations class JvmGeneratorExtensions(private val generateFacades: Boolean = true) : GeneratorExtensions() { @@ -39,33 +35,12 @@ class JvmGeneratorExtensions(private val generateFacades: Boolean = true) : Gene get() = JvmSamConversion open class JvmSamConversion : SamConversion() { - override fun getOriginalForSamAdapter(descriptor: CallableDescriptor): CallableDescriptor? = - when (descriptor) { - is SamAdapterDescriptor<*> -> descriptor.baseDescriptorForSynthetic - is SamAdapterExtensionFunctionDescriptor -> descriptor.baseDescriptorForSynthetic - else -> null - } - override fun isSamConstructor(descriptor: CallableDescriptor): Boolean = - descriptor is SamConstructorDescriptor - - override fun isSamType(type: KotlinType): Boolean = + override fun isPlatformSamType(type: KotlinType): Boolean = JavaSingleAbstractMethodUtils.isSamType(type) - override fun getSamTypeInfoForValueParameter(valueParameter: ValueParameterDescriptor): KotlinType? { - val samType = SamType.createByValueParameter(valueParameter) ?: return null - return samType.type - } - - override fun getSubstitutedFunctionTypeForSamType(samType: KotlinType): KotlinType { - val descriptor = samType.constructor.declarationDescriptor as? ClassDescriptor - ?: throw AssertionError("SAM should be represented by a class: $samType") - val singleAbstractMethod = getSingleAbstractMethodOrNull(descriptor) - ?: throw AssertionError("$descriptor should have a single abstract method") - val unsubstitutedFunctionType = getFunctionTypeForAbstractMethod(singleAbstractMethod, false) - return TypeSubstitutor.create(samType).substitute(unsubstitutedFunctionType, Variance.INVARIANT) - ?: throw AssertionError("Failed to substitute function type $unsubstitutedFunctionType corresponding to $samType") - } + override fun getSamTypeForValueParameter(valueParameter: ValueParameterDescriptor): KotlinType? = + SamType.createByValueParameter(valueParameter)?.type companion object Instance : JvmSamConversion() } diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ArgumentsGenerationUtils.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ArgumentsGenerationUtils.kt index aec8ef948a9..52c30b9caaa 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ArgumentsGenerationUtils.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ArgumentsGenerationUtils.kt @@ -297,7 +297,7 @@ fun StatementGenerator.generateValueArgumentUsing( } fun StatementGenerator.castArgumentToFunctionalInterfaceForSamType(irExpression: IrExpression, samType: KotlinType): IrExpression { - val kotlinFunctionType = context.extensions.samConversion.getSubstitutedFunctionTypeForSamType(samType) + val kotlinFunctionType = samType.getSubstitutedFunctionTypeForSamType() val irFunctionType = context.typeTranslator.translateType(kotlinFunctionType) return irExpression.implicitCastTo(irFunctionType) } @@ -408,7 +408,7 @@ fun StatementGenerator.generateSamConversionForValueArgumentsIfRequired(call: Ca val samConversion = context.extensions.samConversion val originalDescriptor = resolvedCall.resultingDescriptor - val underlyingDescriptor = samConversion.getOriginalForSamAdapter(originalDescriptor) ?: originalDescriptor + val underlyingDescriptor = originalDescriptor.getOriginalForFunctionInterfaceAdapter() ?: originalDescriptor val originalValueParameters = originalDescriptor.valueParameters val underlyingValueParameters = underlyingDescriptor.valueParameters @@ -446,7 +446,8 @@ fun StatementGenerator.generateSamConversionForValueArgumentsIfRequired(call: Ca if (!originalValueParameters[i].type.isFunctionTypeOrSubtype) continue } - val samKotlinType = samConversion.getSamTypeInfoForValueParameter(underlyingValueParameter) ?: continue + val samKotlinType = samConversion.getSamTypeForValueParameter(underlyingValueParameter) + ?: underlyingValueParameter.type val originalArgument = call.irValueArgumentsByIndex[i] ?: continue @@ -497,24 +498,21 @@ fun StatementGenerator.pregenerateCallReceivers(resolvedCall: ResolvedCall<*>): return call } -private fun unwrapSpecialDescriptor( - descriptor: CallableDescriptor, - samConversion: GeneratorExtensions.SamConversion -): CallableDescriptor = +private fun unwrapSpecialDescriptor(descriptor: CallableDescriptor): CallableDescriptor = when (descriptor) { is ImportedFromObjectCallableDescriptor<*> -> - unwrapSpecialDescriptor(descriptor.callableFromObject, samConversion) + unwrapSpecialDescriptor(descriptor.callableFromObject) is TypeAliasConstructorDescriptor -> descriptor.underlyingConstructorDescriptor else -> - samConversion.getOriginalForSamAdapter(descriptor)?.let { unwrapSpecialDescriptor(it, samConversion) } ?: descriptor + descriptor.getOriginalForFunctionInterfaceAdapter()?.let { unwrapSpecialDescriptor(it) } ?: descriptor } fun unwrapCallableDescriptorAndTypeArguments(resolvedCall: ResolvedCall<*>, samConversion: GeneratorExtensions.SamConversion): CallBuilder { val originalDescriptor = resolvedCall.resultingDescriptor val candidateDescriptor = resolvedCall.candidateDescriptor - val unwrappedDescriptor = unwrapSpecialDescriptor(originalDescriptor, samConversion) + val unwrappedDescriptor = unwrapSpecialDescriptor(originalDescriptor) val originalTypeArguments = resolvedCall.typeArguments val unsubstitutedUnwrappedDescriptor = unwrappedDescriptor.original diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/CallGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/CallGenerator.kt index 56f546293b2..5fc05accfef 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/CallGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/CallGenerator.kt @@ -42,7 +42,7 @@ class CallGenerator(statementGenerator: StatementGenerator) : StatementGenerator fun generateCall(startOffset: Int, endOffset: Int, call: CallBuilder, origin: IrStatementOrigin? = null): IrExpression { val descriptor = call.descriptor - if (context.extensions.samConversion.isSamConstructor(descriptor.original)) { + if (descriptor.original.isSamConstructor()) { return generateSamConstructorCall(descriptor, startOffset, endOffset, call) } diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/GeneratorExtensions.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/GeneratorExtensions.kt index 93404c0e2ee..1541a92ef28 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/GeneratorExtensions.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/GeneratorExtensions.kt @@ -5,7 +5,6 @@ package org.jetbrains.kotlin.psi2ir.generators -import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.descriptors.Visibility @@ -17,18 +16,10 @@ open class GeneratorExtensions : StubGeneratorExtensions() { get() = SamConversion open class SamConversion { - // Returns null if descriptor is not a SAM adapter - open fun getOriginalForSamAdapter(descriptor: CallableDescriptor): CallableDescriptor? = null - open fun isSamConstructor(descriptor: CallableDescriptor): Boolean = false + open fun isPlatformSamType(type: KotlinType): Boolean = false - open fun isSamType(type: KotlinType): Boolean = false - - open fun getSamTypeInfoForValueParameter(valueParameter: ValueParameterDescriptor): KotlinType? = - throw UnsupportedOperationException("SAM conversion is not supported in this configuration (valueParameter=$valueParameter)") - - open fun getSubstitutedFunctionTypeForSamType(samType: KotlinType): KotlinType = - throw UnsupportedOperationException("SAM conversion is not supported in this configuration (samType=$samType)") + open fun getSamTypeForValueParameter(valueParameter: ValueParameterDescriptor): KotlinType? = null companion object Instance : SamConversion() } diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/samConversions.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/samConversions.kt new file mode 100644 index 00000000000..6981bc1e831 --- /dev/null +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/samConversions.kt @@ -0,0 +1,47 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * 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.psi2ir.generators + +import org.jetbrains.kotlin.descriptors.CallableDescriptor +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor +import org.jetbrains.kotlin.descriptors.synthetic.FunctionInterfaceAdapterDescriptor +import org.jetbrains.kotlin.descriptors.synthetic.FunctionInterfaceAdapterExtensionFunctionDescriptor +import org.jetbrains.kotlin.descriptors.synthetic.FunctionInterfaceConstructorDescriptor +import org.jetbrains.kotlin.resolve.sam.getFunctionTypeForAbstractMethod +import org.jetbrains.kotlin.resolve.sam.getSingleAbstractMethodOrNull +import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.TypeSubstitutor +import org.jetbrains.kotlin.types.Variance + +fun GeneratorExtensions.SamConversion.isSamType(kotlinType: KotlinType): Boolean { + val descriptor = kotlinType.constructor.declarationDescriptor + return descriptor is ClassDescriptor && descriptor.isFun || + isPlatformSamType(kotlinType) +} + +fun DeclarationDescriptor.isSamConstructor() = this is FunctionInterfaceConstructorDescriptor + +fun CallableDescriptor.getOriginalForFunctionInterfaceAdapter() = + when (this) { + is FunctionInterfaceAdapterDescriptor<*> -> + baseDescriptorForSynthetic + is FunctionInterfaceAdapterExtensionFunctionDescriptor -> + baseDescriptorForSynthetic + else -> + null + } + +fun KotlinType.getSubstitutedFunctionTypeForSamType(): KotlinType { + val descriptor = constructor.declarationDescriptor as? ClassDescriptor + ?: throw AssertionError("SAM should be represented by a class: $this") + val singleAbstractMethod = getSingleAbstractMethodOrNull(descriptor) + ?: throw AssertionError("$descriptor should have a single abstract method") + val unsubstitutedFunctionType = getFunctionTypeForAbstractMethod(singleAbstractMethod, false) + return TypeSubstitutor.create(this).substitute(unsubstitutedFunctionType, Variance.INVARIANT) + ?: throw AssertionError("Failed to substitute function type $unsubstitutedFunctionType corresponding to $this") +} diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt index ee133925703..2436d156a16 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt @@ -43,6 +43,7 @@ import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.psi2ir.containsNull import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext import org.jetbrains.kotlin.psi2ir.generators.GeneratorExtensions +import org.jetbrains.kotlin.psi2ir.generators.getSubstitutedFunctionTypeForSamType import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.checker.KotlinTypeChecker import org.jetbrains.kotlin.types.typeUtil.* @@ -251,9 +252,6 @@ internal class InsertImplicitCasts( finallyExpression = finallyExpression?.coerceToUnit() } - private fun KotlinType.getSubstitutedFunctionTypeForSamType() = - generatorExtensions.samConversion.getSubstitutedFunctionTypeForSamType(this) - override fun visitTypeOperator(expression: IrTypeOperatorCall): IrExpression = when (expression.operator) { IrTypeOperator.SAM_CONVERSION -> expression.transformPostfix { diff --git a/compiler/resolution/src/org/jetbrains/kotlin/descriptors/synthetic/SyntheticMemberDescriptor.kt b/compiler/resolution/src/org/jetbrains/kotlin/descriptors/synthetic/SyntheticMemberDescriptor.kt index af36942843d..38f3355c4f8 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/descriptors/synthetic/SyntheticMemberDescriptor.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/descriptors/synthetic/SyntheticMemberDescriptor.kt @@ -16,8 +16,16 @@ package org.jetbrains.kotlin.descriptors.synthetic +import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.descriptors.FunctionDescriptor interface SyntheticMemberDescriptor { val baseDescriptorForSynthetic: T } + +interface FunctionInterfaceConstructorDescriptor : SyntheticMemberDescriptor + +interface FunctionInterfaceAdapterDescriptor : SyntheticMemberDescriptor + +interface FunctionInterfaceAdapterExtensionFunctionDescriptor : SyntheticMemberDescriptor \ No newline at end of file