From f32c3551909f3e510d8d7c4821c3d52a10d3cc2b Mon Sep 17 00:00:00 2001 From: Ivan Kochurkin Date: Tue, 1 Feb 2022 23:45:53 +0300 Subject: [PATCH] [FIR] Correct resolving of sam with suspend function from another module, ^KT-51007 Fixed Ignore fir ide test probably because of KT-50732 --- ...CompilerTestFE10TestdataTestGenerated.java | 6 +++ ...irOldFrontendDiagnosticsTestGenerated.java | 6 +++ ...DiagnosticsWithLightTreeTestGenerated.java | 6 +++ .../resolve/inference/PostponedArguments.kt | 1 - ...rCallCompletionResultsWriterTransformer.kt | 37 +++++++++++-------- ...samWithSuspendFunctionFromAnotherModule.kt | 20 ++++++++++ ...amWithSuspendFunctionFromAnotherModule.txt | 16 ++++++++ .../test/runners/DiagnosticTestGenerated.java | 6 +++ 8 files changed, 82 insertions(+), 16 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/multimodule/samWithSuspendFunctionFromAnotherModule.kt create mode 100644 compiler/testData/diagnostics/tests/multimodule/samWithSuspendFunctionFromAnotherModule.txt diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java index 4f690ca918b..4719e886f58 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java @@ -19638,6 +19638,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag runTest("compiler/testData/diagnostics/tests/multimodule/redundantElseInWhen.kt"); } + @Test + @TestMetadata("samWithSuspendFunctionFromAnotherModule.kt") + public void testSamWithSuspendFunctionFromAnotherModule() throws Exception { + runTest("compiler/testData/diagnostics/tests/multimodule/samWithSuspendFunctionFromAnotherModule.kt"); + } + @Test @TestMetadata("varargConflict.kt") public void testVarargConflict() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java index 5697eab7762..41928d17502 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java @@ -19638,6 +19638,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/multimodule/redundantElseInWhen.kt"); } + @Test + @TestMetadata("samWithSuspendFunctionFromAnotherModule.kt") + public void testSamWithSuspendFunctionFromAnotherModule() throws Exception { + runTest("compiler/testData/diagnostics/tests/multimodule/samWithSuspendFunctionFromAnotherModule.kt"); + } + @Test @TestMetadata("varargConflict.kt") public void testVarargConflict() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java index ce06bcb91be..a36b97b7ec8 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java @@ -19638,6 +19638,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac runTest("compiler/testData/diagnostics/tests/multimodule/redundantElseInWhen.kt"); } + @Test + @TestMetadata("samWithSuspendFunctionFromAnotherModule.kt") + public void testSamWithSuspendFunctionFromAnotherModule() throws Exception { + runTest("compiler/testData/diagnostics/tests/multimodule/samWithSuspendFunctionFromAnotherModule.kt"); + } + @Test @TestMetadata("varargConflict.kt") public void testVarargConflict() throws Exception { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/PostponedArguments.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/PostponedArguments.kt index 1c6b3f050c5..737bc985b06 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/PostponedArguments.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/PostponedArguments.kt @@ -61,7 +61,6 @@ fun Candidate.preprocessLambdaArgument( ) ?: extractLambdaInfo(expectedType, anonymousFunction, csBuilder, context.session, this) if (expectedType != null) { - // TODO: add SAM conversion processing val parameters = resolvedArgument.parameters val lambdaType = createFunctionalType( if (resolvedArgument.coerceFirstParameterToExtensionReceiver) parameters.drop(1) else parameters, diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt index f97a30ae7ee..c705f9e5fc6 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt @@ -6,14 +6,13 @@ package org.jetbrains.kotlin.fir.resolve.transformers import org.jetbrains.kotlin.KtFakeSourceElementKind -import org.jetbrains.kotlin.descriptors.ClassKind +import org.jetbrains.kotlin.builtins.functions.FunctionClassKind import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.fakeElement import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.utils.isInline import org.jetbrains.kotlin.fir.declarations.utils.isLocal -import org.jetbrains.kotlin.fir.declarations.utils.isSuspend import org.jetbrains.kotlin.fir.declarations.utils.visibility import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind @@ -23,19 +22,17 @@ import org.jetbrains.kotlin.fir.references.FirNamedReference import org.jetbrains.kotlin.fir.references.builder.buildErrorNamedReference import org.jetbrains.kotlin.fir.references.builder.buildResolvedCallableReference import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference +import org.jetbrains.kotlin.fir.resolve.* import org.jetbrains.kotlin.fir.resolve.calls.Candidate import org.jetbrains.kotlin.fir.resolve.calls.FirErrorReferenceWithCandidate import org.jetbrains.kotlin.fir.resolve.calls.FirNamedReferenceWithCandidate -import org.jetbrains.kotlin.fir.resolve.constructFunctionalTypeRef -import org.jetbrains.kotlin.fir.resolve.createFunctionalType import org.jetbrains.kotlin.fir.resolve.dfa.FirDataFlowAnalyzer import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeConstraintSystemHasContradiction import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeInapplicableCandidateError import org.jetbrains.kotlin.fir.resolve.diagnostics.ConePropertyAsOperator import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeTypeParameterInQualifiedAccess -import org.jetbrains.kotlin.fir.resolve.inference.* -import org.jetbrains.kotlin.fir.resolve.propagateTypeFromQualifiedAccessAfterNullCheck -import org.jetbrains.kotlin.fir.resolve.providers.firProvider +import org.jetbrains.kotlin.fir.resolve.inference.ResolvedLambdaAtom +import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirArrayOfCallTransformer import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.remapArgumentsWithVararg @@ -79,6 +76,8 @@ class FirCallCompletionResultsWriterTransformer( private val arrayOfCallTransformer = FirArrayOfCallTransformer() private var enableArrayOfCallTransformation = false + private val samResolver: FirSamResolver = FirSamResolverImpl(session, ScopeSession()) + enum class Mode { Normal, DelegatedPropertyCompletion } @@ -584,14 +583,22 @@ class FirCallCompletionResultsWriterTransformer( expectedArgumentType.isBuiltinFunctionalType(session) -> expectedArgumentType // fun interface (a.k.a. SAM), then unwrap it and build a functional type from that interface function expectedArgumentType is ConeClassLikeType -> { - val sam = - (session.firProvider.getFirClassifierByFqName(expectedArgumentType.lookupTag.classId) as? FirClass) - ?.takeIf { it.classKind == ClassKind.INTERFACE } - ?.declarations?.singleOrNull() as? FirSimpleFunction - sam?.let { - createFunctionalType( - sam.valueParameters.map { it.returnTypeRef.coneType }, null, sam.returnTypeRef.coneType, sam.isSuspend - ) + val firRegularClass = + session.symbolProvider.getClassLikeSymbolByClassId(expectedArgumentType.lookupTag.classId)?.fir as? FirRegularClass + + firRegularClass?.let { + val functionType = samResolver.getFunctionTypeForPossibleSamType(firRegularClass.defaultType()) + if (functionType != null) { + createFunctionalType( + functionType.typeArguments.dropLast(1).map { it as ConeKotlinType }, + null, + functionType.typeArguments.last() as ConeKotlinType, + functionType.classId?.relativeClassName?.asString() + ?.startsWith(FunctionClassKind.SuspendFunction.classNamePrefix) == true + ) + } else { + null + } } } else -> null diff --git a/compiler/testData/diagnostics/tests/multimodule/samWithSuspendFunctionFromAnotherModule.kt b/compiler/testData/diagnostics/tests/multimodule/samWithSuspendFunctionFromAnotherModule.kt new file mode 100644 index 00000000000..82883735e73 --- /dev/null +++ b/compiler/testData/diagnostics/tests/multimodule/samWithSuspendFunctionFromAnotherModule.kt @@ -0,0 +1,20 @@ +// FIR_IDENTICAL +// FIR_IDE_IGNORE +// TODO: KT-50732 +// ISSUE: KT-51007 + +// MODULE: lib +fun interface A { + suspend fun foo() +} + +// MODULE: main(lib) +suspend fun bar() {} + +fun takeA(a: A?) {} + +fun test() { + takeA { + bar() + } +} diff --git a/compiler/testData/diagnostics/tests/multimodule/samWithSuspendFunctionFromAnotherModule.txt b/compiler/testData/diagnostics/tests/multimodule/samWithSuspendFunctionFromAnotherModule.txt new file mode 100644 index 00000000000..05709b67e26 --- /dev/null +++ b/compiler/testData/diagnostics/tests/multimodule/samWithSuspendFunctionFromAnotherModule.txt @@ -0,0 +1,16 @@ +// -- Module: -- +package + +public fun interface A { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract suspend fun foo(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +// -- Module:
-- +package + +public suspend fun bar(): kotlin.Unit +public fun takeA(/*0*/ a: A?): kotlin.Unit +public fun test(): kotlin.Unit diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index de1e916ba39..ef7f3b17c42 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -19644,6 +19644,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/multimodule/redundantElseInWhen.kt"); } + @Test + @TestMetadata("samWithSuspendFunctionFromAnotherModule.kt") + public void testSamWithSuspendFunctionFromAnotherModule() throws Exception { + runTest("compiler/testData/diagnostics/tests/multimodule/samWithSuspendFunctionFromAnotherModule.kt"); + } + @Test @TestMetadata("varargConflict.kt") public void testVarargConflict() throws Exception {