[FIR] Correct resolving of sam with suspend function from another module, ^KT-51007 Fixed

Ignore fir ide test probably because of KT-50732
This commit is contained in:
Ivan Kochurkin
2022-02-01 23:45:53 +03:00
committed by teamcity
parent 17c64cf955
commit f32c355190
8 changed files with 82 additions and 16 deletions
@@ -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 {
@@ -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 {
@@ -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 {
@@ -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,
@@ -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
@@ -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()
}
}
@@ -0,0 +1,16 @@
// -- Module: <lib> --
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: <main> --
package
public suspend fun bar(): kotlin.Unit
public fun takeA(/*0*/ a: A?): kotlin.Unit
public fun test(): kotlin.Unit
@@ -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 {