From 8f0b073c08c5b7418124b821b61310cad8cf77bd Mon Sep 17 00:00:00 2001 From: Stanislav Erokhin Date: Tue, 1 May 2018 23:46:15 +0300 Subject: [PATCH] [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 --- .../binding/CodegenAnnotatingVisitor.java | 45 +++++++++++++- .../java/sam/JvmSamConversionTransformer.kt | 36 ++++++++++++ .../jvm/platform/JvmPlatformConfigurator.kt | 2 + .../synthetic/SamAdapterFunctionsScope.kt | 24 +++++++- .../kotlin/resolve/TargetPlatform.kt | 2 + .../tower/KotlinToResolvedCallTransformer.kt | 30 ++++++++-- .../calls/components/ExternalComponents.kt | 11 ++++ .../NewOverloadingConflictResolver.kt | 2 +- .../calls/components/ResolutionParts.kt | 45 +++++++++++++- .../calls/model/KotlinResolverContext.kt | 3 +- .../resolve/calls/model/ResolutionAtoms.kt | 7 +++ .../calls/model/ResolutionCandidate.kt | 13 ++++- .../testData/codegen/box/sam/partialSam.kt | 44 ++++++++++++++ .../testData/codegen/box/sam/partialSamKT.kt | 41 +++++++++++++ .../generic/dependOnArgumentType.kt | 5 +- .../disallowForSamAdapterConstructor.kt | 2 +- .../disallowForSamAdapterFunction.kt | 2 +- .../tests/platformTypes/rawTypes/samRaw.kt | 3 +- .../samConversions/DisabledForKTSimple.kt | 20 +++++++ .../samConversions/DisabledForKTSimple.txt | 18 ++++++ .../samConversions/GenericSubstitution.kt | 29 ++++++++++ .../samConversions/GenericSubstitution.txt | 25 ++++++++ .../samConversions/GenericSubstitutionKT.kt | 27 +++++++++ .../samConversions/GenericSubstitutionKT.txt | 25 ++++++++ .../tests/samConversions/OverloadPriority.kt | 31 ++++++++++ .../tests/samConversions/OverloadPriority.txt | 29 ++++++++++ .../samConversions/OverloadPriorityKT.kt | 30 ++++++++++ .../samConversions/OverloadPriorityKT.txt | 29 ++++++++++ .../samConversions/SAMAfterSubstitution.kt | 18 ++++++ .../samConversions/SAMAfterSubstitution.txt | 17 ++++++ .../samConversions/SAMAfterSubstitutionKT.kt | 17 ++++++ .../samConversions/SAMAfterSubstitutionKT.txt | 17 ++++++ .../tests/samConversions/SimpleCorrect.kt | 34 +++++++++++ .../tests/samConversions/SimpleCorrect.txt | 19 ++++++ .../tests/samConversions/SimpleCorrectKT.kt | 31 ++++++++++ .../tests/samConversions/SimpleCorrectKT.txt | 19 ++++++ .../syntheticSAMExtensions.kt | 2 +- .../samAdapters/InnerClassInGeneric.kt | 2 +- .../samAdapters/NoNamedArgsAllowed.kt | 4 +- .../samAdapters/ParameterTypeAnnotation.kt | 2 +- .../samAdapters/Private.kt | 3 +- .../ir/IrBlackBoxCodegenTestGenerated.java | 10 ++++ .../checkers/DiagnosticsTestGenerated.java | 58 +++++++++++++++++++ .../DiagnosticsUsingJavacTestGenerated.java | 58 +++++++++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 10 ++++ .../LightAnalysisModeTestGenerated.java | 10 ++++ .../kotlin/config/LanguageVersionSettings.kt | 2 + .../js/resolve/JsPlatformConfigurator.kt | 2 + 48 files changed, 889 insertions(+), 26 deletions(-) create mode 100644 compiler/frontend.java/src/org/jetbrains/kotlin/load/java/sam/JvmSamConversionTransformer.kt create mode 100644 compiler/testData/codegen/box/sam/partialSam.kt create mode 100644 compiler/testData/codegen/box/sam/partialSamKT.kt create mode 100644 compiler/testData/diagnostics/tests/samConversions/DisabledForKTSimple.kt create mode 100644 compiler/testData/diagnostics/tests/samConversions/DisabledForKTSimple.txt create mode 100644 compiler/testData/diagnostics/tests/samConversions/GenericSubstitution.kt create mode 100644 compiler/testData/diagnostics/tests/samConversions/GenericSubstitution.txt create mode 100644 compiler/testData/diagnostics/tests/samConversions/GenericSubstitutionKT.kt create mode 100644 compiler/testData/diagnostics/tests/samConversions/GenericSubstitutionKT.txt create mode 100644 compiler/testData/diagnostics/tests/samConversions/OverloadPriority.kt create mode 100644 compiler/testData/diagnostics/tests/samConversions/OverloadPriority.txt create mode 100644 compiler/testData/diagnostics/tests/samConversions/OverloadPriorityKT.kt create mode 100644 compiler/testData/diagnostics/tests/samConversions/OverloadPriorityKT.txt create mode 100644 compiler/testData/diagnostics/tests/samConversions/SAMAfterSubstitution.kt create mode 100644 compiler/testData/diagnostics/tests/samConversions/SAMAfterSubstitution.txt create mode 100644 compiler/testData/diagnostics/tests/samConversions/SAMAfterSubstitutionKT.kt create mode 100644 compiler/testData/diagnostics/tests/samConversions/SAMAfterSubstitutionKT.txt create mode 100644 compiler/testData/diagnostics/tests/samConversions/SimpleCorrect.kt create mode 100644 compiler/testData/diagnostics/tests/samConversions/SimpleCorrect.txt create mode 100644 compiler/testData/diagnostics/tests/samConversions/SimpleCorrectKT.kt create mode 100644 compiler/testData/diagnostics/tests/samConversions/SimpleCorrectKT.txt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenAnnotatingVisitor.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenAnnotatingVisitor.java index d535338cb7d..0583f114f12 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenAnnotatingVisitor.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenAnnotatingVisitor.java @@ -9,6 +9,7 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.stubs.StubElement; import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.TokenSet; +import com.intellij.util.SmartList; import com.intellij.util.containers.Stack; import kotlin.Pair; import kotlin.collections.CollectionsKt; @@ -44,6 +45,8 @@ import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument; import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall; import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument; import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall; +import org.jetbrains.kotlin.resolve.calls.tower.NewResolvedCallImpl; +import org.jetbrains.kotlin.resolve.calls.tower.NewVariableAsFunctionResolvedCallImpl; import org.jetbrains.kotlin.resolve.constants.ConstantValue; import org.jetbrains.kotlin.resolve.constants.EnumValue; import org.jetbrains.kotlin.resolve.constants.NullValue; @@ -694,18 +697,54 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid { CallableDescriptor descriptor = call.getResultingDescriptor(); if (!(descriptor instanceof FunctionDescriptor)) return; + recordSamValueForNewInference(call); recordSamConstructorIfNeeded(expression, call); FunctionDescriptor original = SamCodegenUtil.getOriginalIfSamAdapter((FunctionDescriptor) descriptor); if (original == null) return; - List valueArguments = call.getValueArgumentsByIndex(); - if (valueArguments == null) return; - + List valueParametersWithSAMConversion = new SmartList<>(); for (ValueParameterDescriptor valueParameter : original.getValueParameters()) { ValueParameterDescriptor adaptedParameter = descriptor.getValueParameters().get(valueParameter.getIndex()); if (KotlinTypeChecker.DEFAULT.equalTypes(adaptedParameter.getType(), valueParameter.getType())) continue; + valueParametersWithSAMConversion.add(valueParameter); + } + writeSamValueForValueParameters(valueParametersWithSAMConversion, call.getValueArgumentsByIndex()); + } + private void recordSamValueForNewInference(@NotNull ResolvedCall call) { + NewResolvedCallImpl newResolvedCall = null; + if (call instanceof NewVariableAsFunctionResolvedCallImpl) { + newResolvedCall = ((NewVariableAsFunctionResolvedCallImpl) call).getFunctionCall(); + } + else if(call instanceof NewResolvedCallImpl) { + newResolvedCall = (NewResolvedCallImpl) call; + } + if (newResolvedCall == null) return; + + List valueParametersWithSAMConversion = new SmartList<>(); + Map arguments = newResolvedCall.getValueArguments(); + for (ValueParameterDescriptor valueParameter : arguments.keySet()) { + ResolvedValueArgument argument = arguments.get(valueParameter); + + if (!(argument instanceof ExpressionValueArgument)) continue; + ValueArgument valueArgument = ((ExpressionValueArgument) argument).getValueArgument(); + + if (valueArgument == null || newResolvedCall.getExpectedTypeForSamConvertedArgument(valueArgument) == null) continue; + + valueParametersWithSAMConversion.add(valueParameter.getOriginal()); + } + writeSamValueForValueParameters(valueParametersWithSAMConversion, newResolvedCall.getValueArgumentsByIndex()); + + } + + private void writeSamValueForValueParameters( + @NotNull Collection valueParametersWithSAMConversion, + @Nullable List valueArguments + ) { + if (valueArguments == null) return; + + for (ValueParameterDescriptor valueParameter : valueParametersWithSAMConversion) { SamType samType = SamType.createByValueParameter(valueParameter); if (samType == null) continue; diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/sam/JvmSamConversionTransformer.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/sam/JvmSamConversionTransformer.kt new file mode 100644 index 00000000000..1624d6ef567 --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/sam/JvmSamConversionTransformer.kt @@ -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() + } +} \ No newline at end of file diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/platform/JvmPlatformConfigurator.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/platform/JvmPlatformConfigurator.kt index 0a77bfc8b1c..b3b7bc26922 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/platform/JvmPlatformConfigurator.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/platform/JvmPlatformConfigurator.kt @@ -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() container.useInstance(JvmTypeSpecificityComparator) container.useImpl() + container.useImpl() } } 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 24cda9d8cc7..8ef11ee52f2 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/SamAdapterFunctionsScope.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/SamAdapterFunctionsScope.kt @@ -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 { function -> extensionForFunctionNotCached(function) @@ -95,6 +98,8 @@ class SamAdapterFunctionsScope( } override fun getSyntheticMemberFunctions(receiverTypes: Collection, name: Name, location: LookupLocation): Collection { + if (samViaSyntheticScopeDisabled) return emptyList() + var result: SmartList? = null for (type in receiverTypes) { for (function in type.memberScope.getContributedFunctions(name, location)) { @@ -134,6 +139,8 @@ class SamAdapterFunctionsScope( } override fun getSyntheticMemberFunctions(receiverTypes: Collection): Collection { + if (samViaSyntheticScopeDisabled) return emptyList() + return receiverTypes.flatMapTo(LinkedHashSet()) { type -> type.memberScope.getContributedDescriptors(DescriptorKindFilter.FUNCTIONS) .filterIsInstance() @@ -148,12 +155,17 @@ class SamAdapterFunctionsScope( override fun getSyntheticExtensionProperties(receiverTypes: Collection): Collection = emptyList() override fun getSyntheticStaticFunctions(scope: ResolutionScope, name: Name, location: LookupLocation): Collection { + if (samViaSyntheticScopeDisabled) return emptyList() + return getSamFunctions(scope.getContributedFunctions(name, location), location) } override fun getSyntheticConstructors(scope: ResolutionScope, name: Name, location: LookupLocation): Collection { 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 { + if (samViaSyntheticScopeDisabled) return emptyList() + return getSamFunctions(scope.getContributedDescriptors(DescriptorKindFilter.FUNCTIONS), location = null) } override fun getSyntheticConstructors(scope: ResolutionScope): Collection { - return scope.getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS) - .filterIsInstance() - .flatMap { getAllSamConstructors(it) } + val classifiers = scope.getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS).filterIsInstance() + + 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 -> { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/TargetPlatform.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/TargetPlatform.kt index 490ca764910..f433e3b6d2e 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/TargetPlatform.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/TargetPlatform.kt @@ -14,6 +14,7 @@ import org.jetbrains.kotlin.platform.PlatformToKotlinClassMap import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.UserDataProperty import org.jetbrains.kotlin.resolve.calls.checkers.* +import org.jetbrains.kotlin.resolve.calls.components.SamConversionTransformer import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator import org.jetbrains.kotlin.resolve.checkers.* import org.jetbrains.kotlin.resolve.lazy.DelegationFilter @@ -62,6 +63,7 @@ abstract class TargetPlatform(val platformName: String) { ) { override fun configureModuleComponents(container: StorageComponentContainer) { container.useInstance(SyntheticScopes.Empty) + container.useInstance(SamConversionTransformer.Empty) container.useInstance(TypeSpecificityComparator.NONE) } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt index ed7b66c3590..8658b13d6fa 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt @@ -209,10 +209,14 @@ class KotlinToResolvedCallTransformer( for (valueArgument in resolvedCall.call.valueArguments) { val argumentMapping = resolvedCall.getArgumentMapping(valueArgument!!) val (expectedType, callPosition) = when (argumentMapping) { - is ArgumentMatch -> Pair( - getEffectiveExpectedType(argumentMapping.valueParameter, valueArgument, context), - CallPosition.ValueArgumentPosition(resolvedCall, argumentMapping.valueParameter, valueArgument) - ) + is ArgumentMatch -> { + val expectedType = resolvedCall.getExpectedTypeForSamConvertedArgument(valueArgument) + ?: getEffectiveExpectedType(argumentMapping.valueParameter, valueArgument, context) + Pair( + expectedType, + CallPosition.ValueArgumentPosition(resolvedCall, argumentMapping.valueParameter, valueArgument) + ) + } else -> Pair(TypeUtils.NO_EXPECTED_TYPE, CallPosition.Unknown) } val newContext = @@ -522,6 +526,8 @@ class NewResolvedCallImpl( private var extensionReceiver = resolvedCallAtom.extensionReceiverArgument?.receiver?.receiverValue private var dispatchReceiver = resolvedCallAtom.dispatchReceiverArgument?.receiver?.receiverValue private var smartCastDispatchReceiverType: KotlinType? = null + private var expedtedTypeForSamConvertedArgumentMap: MutableMap? = null + override val kotlinCall: KotlinCall get() = resolvedCallAtom.atom @@ -610,6 +616,22 @@ class NewResolvedCallImpl( val substituted = (substitutor ?: FreshVariableNewTypeSubstitutor.Empty).safeSubstitute(it.defaultType) TypeApproximator().approximateToSuperType(substituted, TypeApproximatorConfiguration.CapturedTypesApproximation) ?: substituted } + + calculateExpedtedTypeForSamConvertedArgumentMap(substitutor) + } + + fun getExpectedTypeForSamConvertedArgument(valueArgument: ValueArgument): UnwrappedType? = + expedtedTypeForSamConvertedArgumentMap?.get(valueArgument) + + private fun calculateExpedtedTypeForSamConvertedArgumentMap(substitutor: NewTypeSubstitutor?) { + if (resolvedCallAtom.argumentsWithConversion.isEmpty()) return + + expedtedTypeForSamConvertedArgumentMap = hashMapOf() + for ((argument, description) in resolvedCallAtom.argumentsWithConversion) { + val typeWithFreshVariables = resolvedCallAtom.substitutor.safeSubstitute(description.convertedTypeByCandidateParameter) + val expectedType = substitutor?.safeSubstitute(typeWithFreshVariables) ?: typeWithFreshVariables + expedtedTypeForSamConvertedArgumentMap!![argument.psiCallArgument.valueArgument] = expectedType + } } init { diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ExternalComponents.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ExternalComponents.kt index ca9c6bf36ac..abf573e8166 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ExternalComponents.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ExternalComponents.kt @@ -49,4 +49,15 @@ interface KotlinResolutionCallbacks { fun isCompileTimeConstant(resolvedAtom: ResolvedCallAtom, expectedType: UnwrappedType): Boolean val inferenceSession: InferenceSession +} + +interface SamConversionTransformer { + fun getFunctionTypeForPossibleSamType(possibleSamType: UnwrappedType): UnwrappedType? + + fun shouldRunSamConversionForFunction(candidate: CallableDescriptor): Boolean + + object Empty : SamConversionTransformer { + override fun getFunctionTypeForPossibleSamType(possibleSamType: UnwrappedType): UnwrappedType? = null + override fun shouldRunSamConversionForFunction(candidate: CallableDescriptor): Boolean = false + } } \ No newline at end of file diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/NewOverloadingConflictResolver.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/NewOverloadingConflictResolver.kt index 7c416c3ac85..5060eb87ad7 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/NewOverloadingConflictResolver.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/NewOverloadingConflictResolver.kt @@ -61,7 +61,7 @@ class NewOverloadingConflictResolver( } else { val originalValueParameter = originalValueParameters[valueParameter.index] for (valueArgument in resolvedValueArgument.arguments) { - valueArgumentToParameterType[valueArgument] = + valueArgumentToParameterType[valueArgument] = candidate.resolvedCall.argumentsWithConversion[valueArgument]?.convertedTypeByOriginParameter ?: valueArgument.getExpectedType(originalValueParameter, candidate.callComponents.languageVersionSettings) } } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt index 1455a6987ef..f5b8b014a8a 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt @@ -6,6 +6,8 @@ package org.jetbrains.kotlin.resolve.calls.components import org.jetbrains.kotlin.builtins.getReceiverTypeFromFunctionType +import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor +import org.jetbrains.kotlin.builtins.getFunctionalClassKind import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.resolve.calls.components.TypeArgumentsToParametersMapper.TypeArgumentsMapping.NoExplicitArguments import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemOperation @@ -21,6 +23,7 @@ import org.jetbrains.kotlin.resolve.calls.tower.VisibilityError import org.jetbrains.kotlin.types.ErrorUtils import org.jetbrains.kotlin.types.typeUtil.contains import org.jetbrains.kotlin.types.UnwrappedType +import org.jetbrains.kotlin.types.checker.anySuperTypeConstructor import org.jetbrains.kotlin.utils.addToStdlib.safeAs internal object CheckInstantiationOfAbstractClass : ResolutionPart() { @@ -28,7 +31,8 @@ internal object CheckInstantiationOfAbstractClass : ResolutionPart() { val candidateDescriptor = resolvedCall.candidateDescriptor if (candidateDescriptor is ConstructorDescriptor && - !callComponents.statelessCallbacks.isSuperOrDelegatingConstructorCall(resolvedCall.atom)) { + !callComponents.statelessCallbacks.isSuperOrDelegatingConstructorCall(resolvedCall.atom) + ) { if (candidateDescriptor.constructedClass.modality == Modality.ABSTRACT) { addDiagnostic(InstantiationOfAbstractClass) } @@ -244,11 +248,48 @@ private fun KotlinResolutionCandidate.prepareExpectedType( argument: KotlinCallArgument, candidateParameter: ParameterDescriptor ): UnwrappedType { - val argumentType = argument.getExpectedType(candidateParameter, callComponents.languageVersionSettings) + val argumentType = getExpectedTypeWithSAMConversion(argument, candidateParameter) ?: argument.getExpectedType( + candidateParameter, + callComponents.languageVersionSettings + ) val resultType = knownTypeParametersResultingSubstitutor?.substitute(argumentType) ?: argumentType return resolvedCall.substitutor.substituteKeepAnnotations(resultType) } +private fun KotlinResolutionCandidate.getExpectedTypeWithSAMConversion( + argument: KotlinCallArgument, + candidateParameter: ParameterDescriptor +): UnwrappedType? { + if (!callComponents.samConversionTransformer.shouldRunSamConversionForFunction(resolvedCall.candidateDescriptor)) return null + + val argumentIsFunctional = when (argument) { + is SimpleKotlinCallArgument -> argument.receiver.stableType.isSubtypeOfFunctionType() + is LambdaKotlinCallArgument, is CallableReferenceKotlinCallArgument -> true + else -> false + } + if (!argumentIsFunctional) return null + + val originalExpectedType = argument.getExpectedType(candidateParameter.original, callComponents.languageVersionSettings) + val convertedTypeByOriginal = callComponents.samConversionTransformer.getFunctionTypeForPossibleSamType(originalExpectedType) ?: return null + + val candidateExpectedType = argument.getExpectedType(candidateParameter, callComponents.languageVersionSettings) + val convertedTypeByCandidate = callComponents.samConversionTransformer.getFunctionTypeForPossibleSamType(candidateExpectedType) + + assert(candidateExpectedType.constructor == originalExpectedType.constructor && convertedTypeByCandidate != null) { + "If original type is SAM type, then candidate should have same type constructor and corresponding function type\n" + + "originalExpectType: $originalExpectedType, candidateExpectType: $candidateExpectedType\n" + + "functionTypeByOriginal: $convertedTypeByOriginal, functionTypeByCandidate: $convertedTypeByCandidate" + } + + resolvedCall.registerArgumentWithSamConversion(argument, SamConversionDescription(convertedTypeByOriginal, convertedTypeByCandidate!!)) + + return convertedTypeByCandidate +} + +private fun UnwrappedType.isSubtypeOfFunctionType() = anySuperTypeConstructor { + it.declarationDescriptor?.getFunctionalClassKind() == FunctionClassDescriptor.Kind.Function +} + internal object CheckReceivers : ResolutionPart() { private fun KotlinResolutionCandidate.checkReceiver( receiverArgument: SimpleKotlinCallArgument?, diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinResolverContext.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinResolverContext.kt index 2e92f3381e0..a3b3d75d479 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinResolverContext.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinResolverContext.kt @@ -42,7 +42,8 @@ class KotlinCallComponents( val constraintInjector: ConstraintInjector, val reflectionTypes: ReflectionTypes, val builtIns: KotlinBuiltIns, - val languageVersionSettings: LanguageVersionSettings + val languageVersionSettings: LanguageVersionSettings, + val samConversionTransformer: SamConversionTransformer ) class SimpleCandidateFactory( diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolutionAtoms.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolutionAtoms.kt index 180e34a8e70..f682006a0a0 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolutionAtoms.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolutionAtoms.kt @@ -61,8 +61,15 @@ abstract class ResolvedCallAtom : ResolvedAtom() { abstract val typeArgumentMappingByOriginal: TypeArgumentsToParametersMapper.TypeArgumentsMapping abstract val argumentMappingByOriginal: Map abstract val substitutor: FreshVariableNewTypeSubstitutor + + abstract val argumentsWithConversion: Map } +class SamConversionDescription( + val convertedTypeByOriginParameter: UnwrappedType, + val convertedTypeByCandidateParameter: UnwrappedType // expected type for corresponding argument +) + class ResolvedExpressionAtom(override val atom: ExpressionKotlinCallArgument) : ResolvedAtom() { init { setAnalyzedResults(listOf()) diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolutionCandidate.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolutionCandidate.kt index a779c728f90..ad43fb1d778 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolutionCandidate.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolutionCandidate.kt @@ -24,10 +24,10 @@ import org.jetbrains.kotlin.resolve.calls.inference.NewConstraintSystem import org.jetbrains.kotlin.resolve.calls.inference.components.FreshVariableNewTypeSubstitutor import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage import org.jetbrains.kotlin.resolve.calls.inference.model.NewConstraintSystemImpl -import org.jetbrains.kotlin.resolve.calls.inference.model.TypeVariableFromCallableDescriptor import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind import org.jetbrains.kotlin.resolve.calls.tower.* import org.jetbrains.kotlin.types.TypeSubstitutor +import org.jetbrains.kotlin.types.UnwrappedType abstract class ResolutionPart { @@ -176,6 +176,17 @@ class MutableResolvedCallAtom( override lateinit var argumentMappingByOriginal: Map override lateinit var substitutor: FreshVariableNewTypeSubstitutor lateinit var argumentToCandidateParameter: Map + private var samAdapterMap: HashMap? = null + + override val argumentsWithConversion: Map + get() = samAdapterMap ?: emptyMap() + + fun registerArgumentWithSamConversion(argument: KotlinCallArgument, samConversionDescription: SamConversionDescription) { + if (samAdapterMap == null) + samAdapterMap = hashMapOf() + + samAdapterMap!![argument] = samConversionDescription + } override public fun setAnalyzedResults(subResolvedAtoms: List) { super.setAnalyzedResults(subResolvedAtoms) diff --git a/compiler/testData/codegen/box/sam/partialSam.kt b/compiler/testData/codegen/box/sam/partialSam.kt new file mode 100644 index 00000000000..f399c298324 --- /dev/null +++ b/compiler/testData/codegen/box/sam/partialSam.kt @@ -0,0 +1,44 @@ +// !LANGUAGE: +NewInference +// TARGET_BACKEND: JVM +// WITH_RUNTIME +// FILE: Fn.java +public interface Fn { + R run(String s, int i, T t); +} + +// FILE: J.java +public class J { + public int runConversion(Fn f1, Fn f2) { + return f1.run("Bar", 1, f2.run("Foo", 42, 239)); + } +} + +// FILE: 1.kt +fun box(): String { + val j = J() + var x = "" + + val fsi = object : Fn { + override fun run(s: String, i: Int, t: String): Int { + x += "$s$i$t " + return i + } + } + + val fis = object : Fn { + override fun run(s: String, i: Int, t: Int): String { + x += "$s$i$t " + return s + } + } + + val r1 = j.runConversion(fsi) { s, i, ti -> x += "L$s$i$ti "; "L$s"} + val r2 = j.runConversion({ s, i, ts -> x += "L$s$i$ts"; i }, fis) + + if (r1 != 1) return "fail r1: $r1" + if (r2 != 1) return "fail r2: $r2" + + if (x != "LFoo42239 Bar1LFoo Foo42239 LBar1Foo") return x + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/sam/partialSamKT.kt b/compiler/testData/codegen/box/sam/partialSamKT.kt new file mode 100644 index 00000000000..964ee86673b --- /dev/null +++ b/compiler/testData/codegen/box/sam/partialSamKT.kt @@ -0,0 +1,41 @@ +// !LANGUAGE: +NewInference +SamConversionForKotlinFunctions +// TARGET_BACKEND: JVM +// WITH_RUNTIME +// FILE: Fn.java +public interface Fn { + R run(String s, int i, T t); +} + +// FILE: 1.kt +class K { + fun runConversion(f1: Fn, f2: Fn) = f1.run("Bar", 1, f2.run("Foo", 42, 239)) +} + +fun box(): String { + val k = K() + var x = "" + + val fsi = object : Fn { + override fun run(s: String, i: Int, t: String): Int { + x += "$s$i$t " + return i + } + } + + val fis = object : Fn { + override fun run(s: String, i: Int, t: Int): String { + x += "$s$i$t " + return s + } + } + + val r1 = k.runConversion(fsi) { s, i, ti -> x += "L$s$i$ti "; "L$s"} + val r2 = k.runConversion({ s, i, ts -> x += "L$s$i$ts"; i }, fis) + + if (r1 != 1) return "fail r1: $r1" + if (r2 != 1) return "fail r2: $r2" + + if (x != "LFoo42239 Bar1LFoo Foo42239 LBar1Foo") return x + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/callableReference/generic/dependOnArgumentType.kt b/compiler/testData/diagnostics/tests/callableReference/generic/dependOnArgumentType.kt index 730c5c8c92a..fbe342c6e36 100644 --- a/compiler/testData/diagnostics/tests/callableReference/generic/dependOnArgumentType.kt +++ b/compiler/testData/diagnostics/tests/callableReference/generic/dependOnArgumentType.kt @@ -1,3 +1,4 @@ +// !WITH_NEW_INFERENCE // !DIAGNOSTICS: -UNUSED_PARAMETER // FILE: A.java @@ -15,14 +16,14 @@ fun bar(s: T) {} fun complex(t: T, f: (T) -> Unit) {} fun test1() { - foo(1, A::invokeLater) + foo(1, A::invokeLater) // KT-24507 SAM conversion accidentally applied to callable reference and incorrectly handled via BE foo(1, ::bar) complex(1, ::bar) } fun test2(x: R) { - foo(x, A::invokeLater) + foo(x, A::invokeLater) // KT-24507 SAM conversion accidentally applied to callable reference and incorrectly handled via BE foo(x, ::bar) complex(x, ::bar) diff --git a/compiler/testData/diagnostics/tests/namedArguments/disallowForSamAdapterConstructor.kt b/compiler/testData/diagnostics/tests/namedArguments/disallowForSamAdapterConstructor.kt index a66c092f403..7ec20ec9c19 100644 --- a/compiler/testData/diagnostics/tests/namedArguments/disallowForSamAdapterConstructor.kt +++ b/compiler/testData/diagnostics/tests/namedArguments/disallowForSamAdapterConstructor.kt @@ -13,5 +13,5 @@ public class J { package test fun test() { - J("", r = { }, z = false) + J("", r = { }, z = false) } diff --git a/compiler/testData/diagnostics/tests/namedArguments/disallowForSamAdapterFunction.kt b/compiler/testData/diagnostics/tests/namedArguments/disallowForSamAdapterFunction.kt index d50c2a49f28..5d9af118432 100644 --- a/compiler/testData/diagnostics/tests/namedArguments/disallowForSamAdapterFunction.kt +++ b/compiler/testData/diagnostics/tests/namedArguments/disallowForSamAdapterFunction.kt @@ -13,5 +13,5 @@ public class J { package test fun test() { - J.foo("", r = { }, z = false) + J.foo("", r = { }, z = false) } diff --git a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/samRaw.kt b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/samRaw.kt index 277f20657ae..0f43cdde327 100644 --- a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/samRaw.kt +++ b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/samRaw.kt @@ -1,3 +1,4 @@ +// !WITH_NEW_INFERENCE // !DIAGNOSTICS: -UNUSED_VARIABLE // FILE: A.java @@ -20,7 +21,7 @@ class B { fun main() { fun println() {} // All parameters in SAM adapter of `foo` have functional types - B().foo({ println() }, B.bar()) + B().foo({ println() }, B.bar()) // So you should use SAM constructors when you want to use mix lambdas and Java objects B().foo(Runnable { println() }, B.bar()) B().foo({ println() }, { it: Any? -> it == null } ) diff --git a/compiler/testData/diagnostics/tests/samConversions/DisabledForKTSimple.kt b/compiler/testData/diagnostics/tests/samConversions/DisabledForKTSimple.kt new file mode 100644 index 00000000000..2e41d8f80d7 --- /dev/null +++ b/compiler/testData/diagnostics/tests/samConversions/DisabledForKTSimple.kt @@ -0,0 +1,20 @@ +// !LANGUAGE: +NewInference +// FILE: Runnable.java +public interface Runnable { + void run(); +} + +// FILE: 1.kt +interface K { + fun foo1(r: Runnable) + fun foo2(r1: Runnable, r2: Runnable) +} +fun test(k: K, r: Runnable) { + k.foo1(r) + k.foo1({}) + + k.foo2(r, r) + k.foo2({}, {}) + k.foo2(r, {}) + k.foo2({}, r) +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/samConversions/DisabledForKTSimple.txt b/compiler/testData/diagnostics/tests/samConversions/DisabledForKTSimple.txt new file mode 100644 index 00000000000..8fbe5fdc5e8 --- /dev/null +++ b/compiler/testData/diagnostics/tests/samConversions/DisabledForKTSimple.txt @@ -0,0 +1,18 @@ +package + +public fun test(/*0*/ k: K, /*1*/ r: Runnable): kotlin.Unit + +public interface K { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract fun foo1(/*0*/ r: Runnable): kotlin.Unit + public abstract fun foo2(/*0*/ r1: Runnable, /*1*/ r2: Runnable): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface Runnable { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public abstract fun run(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/samConversions/GenericSubstitution.kt b/compiler/testData/diagnostics/tests/samConversions/GenericSubstitution.kt new file mode 100644 index 00000000000..bdaa10de4c9 --- /dev/null +++ b/compiler/testData/diagnostics/tests/samConversions/GenericSubstitution.kt @@ -0,0 +1,29 @@ +// !LANGUAGE: +NewInference +// !CHECK_TYPE +// FILE: J.java +public interface J { + void f_t(F f1, F f2); + void f_r(F f1, F f2); + void f_pr(F> f1, F> f2); +} + +// FILE: F.java +public interface F { + void apply(S s); +} + +// FILE: PR.java +public interface PR {} + +// FILE: 1.kt + +fun test( + j: J, + f_string: F, + f_int: F, + f_pr: F> +) { + j.f_t(f_string) { it checkType { _() } } + j.f_r(f_int) { it checkType { _() } } + j.f_pr(f_pr) { it checkType { _>() } } +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/samConversions/GenericSubstitution.txt b/compiler/testData/diagnostics/tests/samConversions/GenericSubstitution.txt new file mode 100644 index 00000000000..2a2a82f2515 --- /dev/null +++ b/compiler/testData/diagnostics/tests/samConversions/GenericSubstitution.txt @@ -0,0 +1,25 @@ +package + +public fun test(/*0*/ j: J, /*1*/ f_string: F, /*2*/ f_int: F, /*3*/ f_pr: F>): kotlin.Unit + +public interface F { + public abstract fun apply(/*0*/ s: S!): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface J { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract fun f_pr(/*0*/ f1: F!>!, /*1*/ f2: F!>!): kotlin.Unit + public abstract fun f_r(/*0*/ f1: F!, /*1*/ f2: F!): kotlin.Unit + public abstract fun f_t(/*0*/ f1: F!, /*1*/ f2: F!): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface PR { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/samConversions/GenericSubstitutionKT.kt b/compiler/testData/diagnostics/tests/samConversions/GenericSubstitutionKT.kt new file mode 100644 index 00000000000..15ff40e4c46 --- /dev/null +++ b/compiler/testData/diagnostics/tests/samConversions/GenericSubstitutionKT.kt @@ -0,0 +1,27 @@ +// !LANGUAGE: +NewInference +SamConversionForKotlinFunctions +// !CHECK_TYPE +// FILE: F.java +public interface F { + void apply(S s); +} + +// FILE: PR.java +public interface PR {} + +// FILE: 1.kt +interface K { + fun f_t(f1: F, f2: F) + fun f_r(f1: F, f2: F) + fun f_pr(f1: F>, f2: F>) +} + +fun test( + k: K, + f_string: F, + f_int: F, + f_pr: F> +) { + k.f_t(f_string) { it checkType { _() } } + k.f_r(f_int) { it checkType { _() } } + k.f_pr(f_pr) { it checkType { _>() } } +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/samConversions/GenericSubstitutionKT.txt b/compiler/testData/diagnostics/tests/samConversions/GenericSubstitutionKT.txt new file mode 100644 index 00000000000..9be462c107f --- /dev/null +++ b/compiler/testData/diagnostics/tests/samConversions/GenericSubstitutionKT.txt @@ -0,0 +1,25 @@ +package + +public fun test(/*0*/ k: K, /*1*/ f_string: F, /*2*/ f_int: F, /*3*/ f_pr: F>): kotlin.Unit + +public interface F { + public abstract fun apply(/*0*/ s: S!): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface K { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract fun f_pr(/*0*/ f1: F>, /*1*/ f2: F>): kotlin.Unit + public abstract fun f_r(/*0*/ f1: F, /*1*/ f2: F): kotlin.Unit + public abstract fun f_t(/*0*/ f1: F, /*1*/ f2: F): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface PR { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/samConversions/OverloadPriority.kt b/compiler/testData/diagnostics/tests/samConversions/OverloadPriority.kt new file mode 100644 index 00000000000..5fc2e26224d --- /dev/null +++ b/compiler/testData/diagnostics/tests/samConversions/OverloadPriority.kt @@ -0,0 +1,31 @@ +// !LANGUAGE: +NewInference +// !CHECK_TYPE +// FILE: Fn.java +public interface Fn { + R apply(T t); +} + +// FILE: Fn2.java +public interface Fn2 extends Fn {} + +// FILE: J.java +public interface J { + String foo(Fn f, Object o); + int foo(Fn f, String s); // (Any) -> Any <: (String) -> Any <=> String <: Any + + String bas(Fn f, Object o); + int bas(Fn f, String s); // (Any) -> String <: (Any) -> Any <=> String <: Any + + String bar(Fn f); + int bar(Fn2 f); // Fn2 seems more specific one even function type same +} + +// FILE: 1.kt +fun test(j: J) { + j.foo({ it checkType { _() }; "" }, "") checkType { _() } + + j.bas({ it checkType { _() }; "" }, "") checkType { _() } + + // NI: TODO + j.bar { it checkType { _() }; "" } checkType { _() } +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/samConversions/OverloadPriority.txt b/compiler/testData/diagnostics/tests/samConversions/OverloadPriority.txt new file mode 100644 index 00000000000..0f22a5eabd9 --- /dev/null +++ b/compiler/testData/diagnostics/tests/samConversions/OverloadPriority.txt @@ -0,0 +1,29 @@ +package + +public fun test(/*0*/ j: J): kotlin.Unit + +public interface Fn { + public abstract fun apply(/*0*/ t: T!): R! + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface Fn2 : Fn { + public abstract override /*1*/ /*fake_override*/ fun apply(/*0*/ t: T!): R! + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface J { + public abstract fun bar(/*0*/ f: Fn2!): kotlin.Int + public abstract fun bar(/*0*/ f: Fn!): kotlin.String! + public abstract fun bas(/*0*/ f: Fn!, /*1*/ o: kotlin.Any!): kotlin.String! + public abstract fun bas(/*0*/ f: Fn!, /*1*/ s: kotlin.String!): kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract fun foo(/*0*/ f: Fn!, /*1*/ s: kotlin.String!): kotlin.Int + public abstract fun foo(/*0*/ f: Fn!, /*1*/ o: kotlin.Any!): kotlin.String! + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/samConversions/OverloadPriorityKT.kt b/compiler/testData/diagnostics/tests/samConversions/OverloadPriorityKT.kt new file mode 100644 index 00000000000..100df86b001 --- /dev/null +++ b/compiler/testData/diagnostics/tests/samConversions/OverloadPriorityKT.kt @@ -0,0 +1,30 @@ +// !LANGUAGE: +NewInference +SamConversionForKotlinFunctions +// !CHECK_TYPE +// FILE: Fn.java +public interface Fn { + R apply(T t); +} + +// FILE: Fn2.java +public interface Fn2 extends Fn {} + +// FILE: 1.kt +interface K { + fun foo(f: Fn): String + fun foo(f: Fn): Int + + fun bas(f: Fn): String + fun bas(f: Fn): Int + + fun bar(f: Fn): String + fun bar(f: Fn2): Int +} + +fun test(k: K) { + k.foo { it checkType { _() }; "" } checkType { _() } + + k.bas { it checkType { _() }; "" } checkType { _() } + + // NI: TODO + k.bar { it checkType { _() }; "" } checkType { _() } +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/samConversions/OverloadPriorityKT.txt b/compiler/testData/diagnostics/tests/samConversions/OverloadPriorityKT.txt new file mode 100644 index 00000000000..71cd97e1579 --- /dev/null +++ b/compiler/testData/diagnostics/tests/samConversions/OverloadPriorityKT.txt @@ -0,0 +1,29 @@ +package + +public fun test(/*0*/ k: K): kotlin.Unit + +public interface Fn { + public abstract fun apply(/*0*/ t: T!): R! + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface Fn2 : Fn { + public abstract override /*1*/ /*fake_override*/ fun apply(/*0*/ t: T!): R! + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface K { + public abstract fun bar(/*0*/ f: Fn2): kotlin.Int + public abstract fun bar(/*0*/ f: Fn): kotlin.String + public abstract fun bas(/*0*/ f: Fn): kotlin.String + public abstract fun bas(/*0*/ f: Fn): kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract fun foo(/*0*/ f: Fn): kotlin.Int + public abstract fun foo(/*0*/ f: Fn): kotlin.String + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/samConversions/SAMAfterSubstitution.kt b/compiler/testData/diagnostics/tests/samConversions/SAMAfterSubstitution.kt new file mode 100644 index 00000000000..f27dc31f887 --- /dev/null +++ b/compiler/testData/diagnostics/tests/samConversions/SAMAfterSubstitution.kt @@ -0,0 +1,18 @@ +// !LANGUAGE: +NewInference +// FILE: J.java +public interface J { + public void foo(T r1, T r2); +} + +// FILE: Runnable.java +public interface Runnable { + void run(); +} + +// FILE: 1.kt +fun test(j: J, r: Runnable) { + j.foo(r, r) + j.foo(r, {}) + j.foo({}, r) + j.foo({}, {}) +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/samConversions/SAMAfterSubstitution.txt b/compiler/testData/diagnostics/tests/samConversions/SAMAfterSubstitution.txt new file mode 100644 index 00000000000..b90d1529154 --- /dev/null +++ b/compiler/testData/diagnostics/tests/samConversions/SAMAfterSubstitution.txt @@ -0,0 +1,17 @@ +package + +public fun test(/*0*/ j: J, /*1*/ r: Runnable): kotlin.Unit + +public interface J { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract fun foo(/*0*/ r1: T!, /*1*/ r2: T!): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface Runnable { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public abstract fun run(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/samConversions/SAMAfterSubstitutionKT.kt b/compiler/testData/diagnostics/tests/samConversions/SAMAfterSubstitutionKT.kt new file mode 100644 index 00000000000..ba2a0ed973f --- /dev/null +++ b/compiler/testData/diagnostics/tests/samConversions/SAMAfterSubstitutionKT.kt @@ -0,0 +1,17 @@ +// !LANGUAGE: +NewInference +SamConversionForKotlinFunctions +// FILE: Runnable.java +public interface Runnable { + void run(); +} + +// FILE: 1.kt +interface K { + fun foo(t1: T, t2: T) +} + +fun test(k: K, r: Runnable) { + k.foo(r, r) + k.foo(r, {}) + k.foo({}, r) + k.foo({}, {}) +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/samConversions/SAMAfterSubstitutionKT.txt b/compiler/testData/diagnostics/tests/samConversions/SAMAfterSubstitutionKT.txt new file mode 100644 index 00000000000..40f7351199d --- /dev/null +++ b/compiler/testData/diagnostics/tests/samConversions/SAMAfterSubstitutionKT.txt @@ -0,0 +1,17 @@ +package + +public fun test(/*0*/ k: K, /*1*/ r: Runnable): kotlin.Unit + +public interface K { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract fun foo(/*0*/ t1: T, /*1*/ t2: T): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface Runnable { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public abstract fun run(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/samConversions/SimpleCorrect.kt b/compiler/testData/diagnostics/tests/samConversions/SimpleCorrect.kt new file mode 100644 index 00000000000..3da568b283f --- /dev/null +++ b/compiler/testData/diagnostics/tests/samConversions/SimpleCorrect.kt @@ -0,0 +1,34 @@ +// !LANGUAGE: +NewInference +SamConversionForKotlinFunctions +// FILE: J.java +public interface J { + public void foo1(Runnable r); + + public void foo2(Runnable r1, Runnable r2); + + public void foo3(Runnable r1, Runnable r2, Runnable r3); +} + +// FILE: Runnable.java +public interface Runnable { + void run(); +} + +// FILE: 1.kt +fun test(j: J, r: Runnable) { + j.foo1(r) + j.foo1({}) + + j.foo2(r, r) + j.foo2({}, {}) + j.foo2(r, {}) + j.foo2({}, r) + + j.foo3(r, r, r) + j.foo3(r, r, {}) + j.foo3(r, {}, r) + j.foo3(r, {}, {}) + j.foo3({}, r, r) + j.foo3({}, r, {}) + j.foo3({}, {}, r) + j.foo3({}, {}, {}) +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/samConversions/SimpleCorrect.txt b/compiler/testData/diagnostics/tests/samConversions/SimpleCorrect.txt new file mode 100644 index 00000000000..95addc26cac --- /dev/null +++ b/compiler/testData/diagnostics/tests/samConversions/SimpleCorrect.txt @@ -0,0 +1,19 @@ +package + +public fun test(/*0*/ j: J, /*1*/ r: Runnable): kotlin.Unit + +public interface J { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract fun foo1(/*0*/ r: Runnable!): kotlin.Unit + public abstract fun foo2(/*0*/ r1: Runnable!, /*1*/ r2: Runnable!): kotlin.Unit + public abstract fun foo3(/*0*/ r1: Runnable!, /*1*/ r2: Runnable!, /*2*/ r3: Runnable!): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface Runnable { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public abstract fun run(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/samConversions/SimpleCorrectKT.kt b/compiler/testData/diagnostics/tests/samConversions/SimpleCorrectKT.kt new file mode 100644 index 00000000000..a5a8b0920f2 --- /dev/null +++ b/compiler/testData/diagnostics/tests/samConversions/SimpleCorrectKT.kt @@ -0,0 +1,31 @@ +// !LANGUAGE: +NewInference +SamConversionForKotlinFunctions +// FILE: Runnable.java +public interface Runnable { + void run(); +} + +// FILE: 1.kt + +interface K { + fun foo1(r: Runnable) + fun foo2(r1: Runnable, r2: Runnable) + fun foo3(r1: Runnable, r2: Runnable, r3: Runnable) +} +fun test(k: K, r: Runnable) { + k.foo1(r) + k.foo1({}) + + k.foo2(r, r) + k.foo2({}, {}) + k.foo2(r, {}) + k.foo2({}, r) + + k.foo3(r, r, r) + k.foo3(r, r, {}) + k.foo3(r, {}, r) + k.foo3(r, {}, {}) + k.foo3({}, r, r) + k.foo3({}, r, {}) + k.foo3({}, {}, r) + k.foo3({}, {}, {}) +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/samConversions/SimpleCorrectKT.txt b/compiler/testData/diagnostics/tests/samConversions/SimpleCorrectKT.txt new file mode 100644 index 00000000000..5ca15fd90d3 --- /dev/null +++ b/compiler/testData/diagnostics/tests/samConversions/SimpleCorrectKT.txt @@ -0,0 +1,19 @@ +package + +public fun test(/*0*/ k: K, /*1*/ r: Runnable): kotlin.Unit + +public interface K { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract fun foo1(/*0*/ r: Runnable): kotlin.Unit + public abstract fun foo2(/*0*/ r1: Runnable, /*1*/ r2: Runnable): kotlin.Unit + public abstract fun foo3(/*0*/ r1: Runnable, /*1*/ r2: Runnable, /*2*/ r3: Runnable): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface Runnable { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public abstract fun run(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/scopes/protectedVisibility/syntheticSAMExtensions.kt b/compiler/testData/diagnostics/tests/scopes/protectedVisibility/syntheticSAMExtensions.kt index f0e62c09462..308acfa0c82 100644 --- a/compiler/testData/diagnostics/tests/scopes/protectedVisibility/syntheticSAMExtensions.kt +++ b/compiler/testData/diagnostics/tests/scopes/protectedVisibility/syntheticSAMExtensions.kt @@ -21,7 +21,7 @@ class B : A() { } if (d.x is B) { - d.x.foo {} + d.x.foo {} } } } diff --git a/compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/InnerClassInGeneric.kt b/compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/InnerClassInGeneric.kt index 0f3160e2a19..d31957c8eb0 100644 --- a/compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/InnerClassInGeneric.kt +++ b/compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/InnerClassInGeneric.kt @@ -2,7 +2,7 @@ // FILE: KotlinFile.kt fun foo(javaClass: JavaClass): Int { val inner = javaClass.createInner() - return inner.doSomething(1, "") { } + return inner.doSomething(1, "") { } } // FILE: JavaClass.java diff --git a/compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/NoNamedArgsAllowed.kt b/compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/NoNamedArgsAllowed.kt index 3add3166896..c0f3ecee47e 100644 --- a/compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/NoNamedArgsAllowed.kt +++ b/compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/NoNamedArgsAllowed.kt @@ -1,9 +1,9 @@ // !WITH_NEW_INFERENCE // FILE: KotlinFile.kt fun foo(javaClass: JavaClass) { - javaClass.doSomething(p = 1) { + javaClass.doSomething(p = 1) { bar() - } + } } fun bar(){} diff --git a/compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/ParameterTypeAnnotation.kt b/compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/ParameterTypeAnnotation.kt index 97791b6009c..1bfca31f3ea 100644 --- a/compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/ParameterTypeAnnotation.kt +++ b/compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/ParameterTypeAnnotation.kt @@ -1,7 +1,7 @@ // !WITH_NEW_INFERENCE // FILE: KotlinFile.kt fun foo(javaInterface: JavaInterface) { - javaInterface.doIt(null) { } + javaInterface.doIt(null) { } javaInterface.doIt("", null) } diff --git a/compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/Private.kt b/compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/Private.kt index 586b539be78..044299fd325 100644 --- a/compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/Private.kt +++ b/compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/Private.kt @@ -1,6 +1,7 @@ +// !WITH_NEW_INFERENCE // FILE: KotlinFile.kt fun foo(javaClass: JavaClass) { - javaClass.doSomething { } + javaClass.doSomething { } } // FILE: JavaClass.java diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 7d04fc5101c..026d96f108b 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -19425,6 +19425,16 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/sam/kt22906_2.kt"); } + @TestMetadata("partialSam.kt") + public void testPartialSam() throws Exception { + runTest("compiler/testData/codegen/box/sam/partialSam.kt"); + } + + @TestMetadata("partialSamKT.kt") + public void testPartialSamKT() throws Exception { + runTest("compiler/testData/codegen/box/sam/partialSamKT.kt"); + } + @TestMetadata("compiler/testData/codegen/box/sam/constructors") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index c9de2409ff4..c6f9cc1e27b 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -17166,6 +17166,64 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { } } + @TestMetadata("compiler/testData/diagnostics/tests/samConversions") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class SamConversions extends AbstractDiagnosticsTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath); + } + + public void testAllFilesPresentInSamConversions() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/samConversions"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); + } + + @TestMetadata("DisabledForKTSimple.kt") + public void testDisabledForKTSimple() throws Exception { + runTest("compiler/testData/diagnostics/tests/samConversions/DisabledForKTSimple.kt"); + } + + @TestMetadata("GenericSubstitution.kt") + public void testGenericSubstitution() throws Exception { + runTest("compiler/testData/diagnostics/tests/samConversions/GenericSubstitution.kt"); + } + + @TestMetadata("GenericSubstitutionKT.kt") + public void testGenericSubstitutionKT() throws Exception { + runTest("compiler/testData/diagnostics/tests/samConversions/GenericSubstitutionKT.kt"); + } + + @TestMetadata("OverloadPriority.kt") + public void testOverloadPriority() throws Exception { + runTest("compiler/testData/diagnostics/tests/samConversions/OverloadPriority.kt"); + } + + @TestMetadata("OverloadPriorityKT.kt") + public void testOverloadPriorityKT() throws Exception { + runTest("compiler/testData/diagnostics/tests/samConversions/OverloadPriorityKT.kt"); + } + + @TestMetadata("SAMAfterSubstitution.kt") + public void testSAMAfterSubstitution() throws Exception { + runTest("compiler/testData/diagnostics/tests/samConversions/SAMAfterSubstitution.kt"); + } + + @TestMetadata("SAMAfterSubstitutionKT.kt") + public void testSAMAfterSubstitutionKT() throws Exception { + runTest("compiler/testData/diagnostics/tests/samConversions/SAMAfterSubstitutionKT.kt"); + } + + @TestMetadata("SimpleCorrect.kt") + public void testSimpleCorrect() throws Exception { + runTest("compiler/testData/diagnostics/tests/samConversions/SimpleCorrect.kt"); + } + + @TestMetadata("SimpleCorrectKT.kt") + public void testSimpleCorrectKT() throws Exception { + runTest("compiler/testData/diagnostics/tests/samConversions/SimpleCorrectKT.kt"); + } + } + @TestMetadata("compiler/testData/diagnostics/tests/scopes") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java index 600b0308863..25e4738f900 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java @@ -17166,6 +17166,64 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing } } + @TestMetadata("compiler/testData/diagnostics/tests/samConversions") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class SamConversions extends AbstractDiagnosticsUsingJavacTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath); + } + + public void testAllFilesPresentInSamConversions() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/samConversions"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); + } + + @TestMetadata("DisabledForKTSimple.kt") + public void testDisabledForKTSimple() throws Exception { + runTest("compiler/testData/diagnostics/tests/samConversions/DisabledForKTSimple.kt"); + } + + @TestMetadata("GenericSubstitution.kt") + public void testGenericSubstitution() throws Exception { + runTest("compiler/testData/diagnostics/tests/samConversions/GenericSubstitution.kt"); + } + + @TestMetadata("GenericSubstitutionKT.kt") + public void testGenericSubstitutionKT() throws Exception { + runTest("compiler/testData/diagnostics/tests/samConversions/GenericSubstitutionKT.kt"); + } + + @TestMetadata("OverloadPriority.kt") + public void testOverloadPriority() throws Exception { + runTest("compiler/testData/diagnostics/tests/samConversions/OverloadPriority.kt"); + } + + @TestMetadata("OverloadPriorityKT.kt") + public void testOverloadPriorityKT() throws Exception { + runTest("compiler/testData/diagnostics/tests/samConversions/OverloadPriorityKT.kt"); + } + + @TestMetadata("SAMAfterSubstitution.kt") + public void testSAMAfterSubstitution() throws Exception { + runTest("compiler/testData/diagnostics/tests/samConversions/SAMAfterSubstitution.kt"); + } + + @TestMetadata("SAMAfterSubstitutionKT.kt") + public void testSAMAfterSubstitutionKT() throws Exception { + runTest("compiler/testData/diagnostics/tests/samConversions/SAMAfterSubstitutionKT.kt"); + } + + @TestMetadata("SimpleCorrect.kt") + public void testSimpleCorrect() throws Exception { + runTest("compiler/testData/diagnostics/tests/samConversions/SimpleCorrect.kt"); + } + + @TestMetadata("SimpleCorrectKT.kt") + public void testSimpleCorrectKT() throws Exception { + runTest("compiler/testData/diagnostics/tests/samConversions/SimpleCorrectKT.kt"); + } + } + @TestMetadata("compiler/testData/diagnostics/tests/scopes") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index d2f7e2d19e6..4b2295a8be6 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -19425,6 +19425,16 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/sam/kt22906_2.kt"); } + @TestMetadata("partialSam.kt") + public void testPartialSam() throws Exception { + runTest("compiler/testData/codegen/box/sam/partialSam.kt"); + } + + @TestMetadata("partialSamKT.kt") + public void testPartialSamKT() throws Exception { + runTest("compiler/testData/codegen/box/sam/partialSamKT.kt"); + } + @TestMetadata("compiler/testData/codegen/box/sam/constructors") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index df59df65ee4..b8f28b55c20 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -19425,6 +19425,16 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/sam/kt22906_2.kt"); } + @TestMetadata("partialSam.kt") + public void testPartialSam() throws Exception { + runTest("compiler/testData/codegen/box/sam/partialSam.kt"); + } + + @TestMetadata("partialSamKT.kt") + public void testPartialSamKT() throws Exception { + runTest("compiler/testData/codegen/box/sam/partialSamKT.kt"); + } + @TestMetadata("compiler/testData/codegen/box/sam/constructors") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt index 8d7bbebd0db..a67fc57f171 100644 --- a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt +++ b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt @@ -91,6 +91,8 @@ enum class LanguageFeature( NewInference(sinceVersion = KOTLIN_1_3, defaultState = State.DISABLED), + SamConversionForKotlinFunctions(sinceVersion = KOTLIN_1_3, defaultState = State.DISABLED), + InlineClasses(sinceVersion = null, defaultState = State.DISABLED, kind = UNSTABLE_FEATURE), ; diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/JsPlatformConfigurator.kt b/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/JsPlatformConfigurator.kt index 8c2044451ab..11ed611a7f3 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/JsPlatformConfigurator.kt +++ b/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/JsPlatformConfigurator.kt @@ -28,6 +28,7 @@ import org.jetbrains.kotlin.resolve.OverloadFilter import org.jetbrains.kotlin.resolve.OverridesBackwardCompatibilityHelper import org.jetbrains.kotlin.resolve.PlatformConfigurator import org.jetbrains.kotlin.resolve.calls.checkers.ReifiedTypeParameterSubstitutionChecker +import org.jetbrains.kotlin.resolve.calls.components.SamConversionTransformer import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker import org.jetbrains.kotlin.resolve.lazy.DelegationFilter import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes @@ -63,6 +64,7 @@ object JsPlatformConfigurator : PlatformConfigurator( container.useInstance(NameSuggestion()) container.useImpl() container.useInstance(SyntheticScopes.Empty) + container.useInstance(SamConversionTransformer.Empty) container.useInstance(JsTypeSpecificityComparator) container.useImpl() container.useImpl()