From dcdc48a2330267afc93b7168e8a856f16580ba6e Mon Sep 17 00:00:00 2001 From: "Denis.Zharkov" Date: Fri, 25 Nov 2022 12:28:18 +0100 Subject: [PATCH] K2: Support callable references adaptation on top-level ^KT-45989 In progress ^KT-54709 Related ^KT-55217 Fixed --- ...CompilerTestFE10TestdataTestGenerated.java | 16 +++++++++ ...irOldFrontendDiagnosticsTestGenerated.java | 16 +++++++++ ...DiagnosticsWithLightTreeTestGenerated.java | 16 +++++++++ .../kotlin/fir/symbols/SyntheticCallableId.kt | 5 +++ .../transformers/FirSyntheticCallGenerator.kt | 34 +++++++++---------- .../simpleAdaptationOutsideOfCall.fir.kt | 10 ++++++ .../adapted/simpleAdaptationOutsideOfCall.kt | 10 ++++++ .../ambiguityTopLevelVsTopLevel.fir.kt | 2 +- .../resolve/withVararg.fir.kt | 2 +- .../conversionLastStatementInLambda.fir.kt | 7 ++-- .../conversionLastStatementInLambda.kt | 3 +- .../test/runners/DiagnosticTestGenerated.java | 16 +++++++++ .../p-1/neg/1.1.fir.kt | 12 +++---- 13 files changed, 118 insertions(+), 31 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/callableReference/adapted/simpleAdaptationOutsideOfCall.fir.kt create mode 100644 compiler/testData/diagnostics/tests/callableReference/adapted/simpleAdaptationOutsideOfCall.kt 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 19099f1dfd0..04e2f7b4f1b 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 @@ -3102,6 +3102,22 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag runTest("compiler/testData/diagnostics/tests/callableReference/withQuestionMarks.kt"); } + @Nested + @TestMetadata("compiler/testData/diagnostics/tests/callableReference/adapted") + @TestDataPath("$PROJECT_ROOT") + public class Adapted { + @Test + public void testAllFilesPresentInAdapted() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/callableReference/adapted"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); + } + + @Test + @TestMetadata("simpleAdaptationOutsideOfCall.kt") + public void testSimpleAdaptationOutsideOfCall() throws Exception { + runTest("compiler/testData/diagnostics/tests/callableReference/adapted/simpleAdaptationOutsideOfCall.kt"); + } + } + @Nested @TestMetadata("compiler/testData/diagnostics/tests/callableReference/bound") @TestDataPath("$PROJECT_ROOT") 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 357d7d832ed..3ad81affa5e 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 @@ -3108,6 +3108,22 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/callableReference/withQuestionMarks.kt"); } + @Nested + @TestMetadata("compiler/testData/diagnostics/tests/callableReference/adapted") + @TestDataPath("$PROJECT_ROOT") + public class Adapted { + @Test + public void testAllFilesPresentInAdapted() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/callableReference/adapted"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); + } + + @Test + @TestMetadata("simpleAdaptationOutsideOfCall.kt") + public void testSimpleAdaptationOutsideOfCall() throws Exception { + runTest("compiler/testData/diagnostics/tests/callableReference/adapted/simpleAdaptationOutsideOfCall.kt"); + } + } + @Nested @TestMetadata("compiler/testData/diagnostics/tests/callableReference/bound") @TestDataPath("$PROJECT_ROOT") 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 c080ad70215..eeb41cc45a7 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 @@ -3102,6 +3102,22 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac runTest("compiler/testData/diagnostics/tests/callableReference/withQuestionMarks.kt"); } + @Nested + @TestMetadata("compiler/testData/diagnostics/tests/callableReference/adapted") + @TestDataPath("$PROJECT_ROOT") + public class Adapted { + @Test + public void testAllFilesPresentInAdapted() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/callableReference/adapted"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); + } + + @Test + @TestMetadata("simpleAdaptationOutsideOfCall.kt") + public void testSimpleAdaptationOutsideOfCall() throws Exception { + runTest("compiler/testData/diagnostics/tests/callableReference/adapted/simpleAdaptationOutsideOfCall.kt"); + } + } + @Nested @TestMetadata("compiler/testData/diagnostics/tests/callableReference/bound") @TestDataPath("$PROJECT_ROOT") diff --git a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/symbols/SyntheticCallableId.kt b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/symbols/SyntheticCallableId.kt index 076dad0458c..bbce8406a73 100644 --- a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/symbols/SyntheticCallableId.kt +++ b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/symbols/SyntheticCallableId.kt @@ -34,4 +34,9 @@ object SyntheticCallableId { syntheticPackageName, Name.identifier("ID_CALL") ) + + val ACCEPT_SPECIFIC_TYPE = CallableId( + syntheticPackageName, + Name.identifier("ACCEPT_SPECIFIC_TYPE_CALL") + ) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSyntheticCallGenerator.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSyntheticCallGenerator.kt index 7be0790c0e6..4fb30d787f2 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSyntheticCallGenerator.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSyntheticCallGenerator.kt @@ -154,34 +154,36 @@ class FirSyntheticCallGenerator( ): FirCallableReferenceAccess? { val argumentList = buildUnaryArgumentList(callableReferenceAccess) - val typeArguments = + val parameterTypeRef = when { - expectedTypeRef is FirResolvedTypeRef && !expectedTypeRef.coneType.isUnitOrFlexibleUnit -> listOf( - buildTypeProjectionWithVariance { - variance = Variance.INVARIANT - typeRef = expectedTypeRef - } - ) - else -> emptyList() + expectedTypeRef is FirResolvedTypeRef && !expectedTypeRef.coneType.isUnitOrFlexibleUnit -> expectedTypeRef + else -> context.session.builtinTypes.anyType } + val callableId = SyntheticCallableId.ACCEPT_SPECIFIC_TYPE + val functionSymbol = FirSyntheticFunctionSymbol(callableId) + // fun accept(p: ): Unit + val function = + generateMemberFunction(functionSymbol, callableId.callableName, returnType = context.session.builtinTypes.unitType).apply { + valueParameters += parameterTypeRef.toValueParameter("reference", functionSymbol, isVararg = false) + }.build() + val reference = generateCalleeReferenceWithCandidate( callableReferenceAccess, - idFunction, + function, argumentList, - SyntheticCallableId.ID.callableName, + callableId.callableName, CallKind.SyntheticIdForCallableReferencesResolution, context, - typeArguments, ) val fakeCallElement = buildFunctionCall { calleeReference = reference this.argumentList = argumentList } - val argument = components.callCompleter.completeCall(fakeCallElement, expectedTypeRef).result.argument - return ((argument as? FirVarargArgumentsExpression)?.arguments?.get(0) ?: argument) as FirCallableReferenceAccess? + val argument = components.callCompleter.completeCall(fakeCallElement, expectedTypeRef = null).result.argument + return argument as FirCallableReferenceAccess? } private fun generateCalleeReferenceWithCandidate( @@ -191,9 +193,8 @@ class FirSyntheticCallGenerator( name: Name, callKind: CallKind = CallKind.SyntheticSelect, context: ResolutionContext, - typeArguments: List = emptyList() ): FirNamedReferenceWithCandidate { - val callInfo = generateCallInfo(callSite, name, argumentList, callKind, typeArguments) + val callInfo = generateCallInfo(callSite, name, argumentList, callKind) val candidate = generateCandidate(callInfo, function, context) val applicability = components.resolutionStageRunner.processCandidate(candidate, context) if (applicability <= CandidateApplicability.INAPPLICABLE) { @@ -224,7 +225,6 @@ class FirSyntheticCallGenerator( name: Name, argumentList: FirArgumentList, callKind: CallKind, - typeArguments: List = emptyList() ) = CallInfo( callSite = callSite, callKind = callKind, @@ -232,7 +232,7 @@ class FirSyntheticCallGenerator( explicitReceiver = null, argumentList = argumentList, isImplicitInvoke = false, - typeArguments = typeArguments, + typeArguments = emptyList(), session = session, containingFile = components.file, containingDeclarations = components.containingDeclarations diff --git a/compiler/testData/diagnostics/tests/callableReference/adapted/simpleAdaptationOutsideOfCall.fir.kt b/compiler/testData/diagnostics/tests/callableReference/adapted/simpleAdaptationOutsideOfCall.fir.kt new file mode 100644 index 00000000000..58e2e01ef30 --- /dev/null +++ b/compiler/testData/diagnostics/tests/callableReference/adapted/simpleAdaptationOutsideOfCall.fir.kt @@ -0,0 +1,10 @@ +// SKIP_TXT +fun baz(options: String = ""): String = "" + +fun runForString(x: () -> String) {} + +fun foo(dumpStrategy: String) { + val dump0: () -> String = ::baz + + runForString(::baz) +} diff --git a/compiler/testData/diagnostics/tests/callableReference/adapted/simpleAdaptationOutsideOfCall.kt b/compiler/testData/diagnostics/tests/callableReference/adapted/simpleAdaptationOutsideOfCall.kt new file mode 100644 index 00000000000..1cce02bc022 --- /dev/null +++ b/compiler/testData/diagnostics/tests/callableReference/adapted/simpleAdaptationOutsideOfCall.kt @@ -0,0 +1,10 @@ +// SKIP_TXT +fun baz(options: String = ""): String = "" + +fun runForString(x: () -> String) {} + +fun foo(dumpStrategy: String) { + val dump0: () -> String = ::baz + + runForString(::baz) +} diff --git a/compiler/testData/diagnostics/tests/callableReference/function/ambiguityTopLevelVsTopLevel.fir.kt b/compiler/testData/diagnostics/tests/callableReference/function/ambiguityTopLevelVsTopLevel.fir.kt index c9732474f75..146821e9f2f 100644 --- a/compiler/testData/diagnostics/tests/callableReference/function/ambiguityTopLevelVsTopLevel.fir.kt +++ b/compiler/testData/diagnostics/tests/callableReference/function/ambiguityTopLevelVsTopLevel.fir.kt @@ -5,5 +5,5 @@ fun foo(x: Any, y: Int) = y fun main() { ::foo - val fooRef: (Int, Any) -> Unit = ::foo + val fooRef: (Int, Any) -> Unit = ::foo } diff --git a/compiler/testData/diagnostics/tests/callableReference/resolve/withVararg.fir.kt b/compiler/testData/diagnostics/tests/callableReference/resolve/withVararg.fir.kt index c31d3da2ec2..eaf58f466f5 100644 --- a/compiler/testData/diagnostics/tests/callableReference/resolve/withVararg.fir.kt +++ b/compiler/testData/diagnostics/tests/callableReference/resolve/withVararg.fir.kt @@ -6,5 +6,5 @@ fun foo(i: Int) {} val fn1: (Int) -> Unit = ::foo val fn2: (IntArray) -> Unit = ::foo -val fn3: (Int, Int) -> Unit = ::foo +val fn3: (Int, Int) -> Unit = ::foo val fn4: (Array) -> Unit = ::foo diff --git a/compiler/testData/diagnostics/tests/inference/callableReferences/conversionLastStatementInLambda.fir.kt b/compiler/testData/diagnostics/tests/inference/callableReferences/conversionLastStatementInLambda.fir.kt index 93b30d7be7a..7aa57a311c0 100644 --- a/compiler/testData/diagnostics/tests/inference/callableReferences/conversionLastStatementInLambda.fir.kt +++ b/compiler/testData/diagnostics/tests/inference/callableReferences/conversionLastStatementInLambda.fir.kt @@ -4,8 +4,7 @@ fun main(b: Boolean) { callWithLambda { // The only relevant case for KT-55729, Unit conversion should work, but doesn't in K1 1.8.0 - // For K2, it still doesn't work (see KT-55936) - ::test1 + ::test1 } callWithLambda { @@ -23,8 +22,8 @@ fun main(b: Boolean) { } callWithLambda { - // That hasn't been working ever in K1 nor K2 - (::test1) + // Doesn't work in K1, but does in K2 + (::test1) } } diff --git a/compiler/testData/diagnostics/tests/inference/callableReferences/conversionLastStatementInLambda.kt b/compiler/testData/diagnostics/tests/inference/callableReferences/conversionLastStatementInLambda.kt index 0af7a93ec30..cf436ad4f03 100644 --- a/compiler/testData/diagnostics/tests/inference/callableReferences/conversionLastStatementInLambda.kt +++ b/compiler/testData/diagnostics/tests/inference/callableReferences/conversionLastStatementInLambda.kt @@ -4,7 +4,6 @@ fun main(b: Boolean) { callWithLambda { // The only relevant case for KT-55729, Unit conversion should work, but doesn't in K1 1.8.0 - // For K2, it still doesn't work (see KT-55936) ::test1 } @@ -23,7 +22,7 @@ fun main(b: Boolean) { } callWithLambda { - // That hasn't been working ever in K1 nor K2 + // Doesn't work in K1, but does in K2 (::test1) } } 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 6a888d7c267..cac555b8b19 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 @@ -3108,6 +3108,22 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/callableReference/withQuestionMarks.kt"); } + @Nested + @TestMetadata("compiler/testData/diagnostics/tests/callableReference/adapted") + @TestDataPath("$PROJECT_ROOT") + public class Adapted { + @Test + public void testAllFilesPresentInAdapted() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/callableReference/adapted"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); + } + + @Test + @TestMetadata("simpleAdaptationOutsideOfCall.kt") + public void testSimpleAdaptationOutsideOfCall() throws Exception { + runTest("compiler/testData/diagnostics/tests/callableReference/adapted/simpleAdaptationOutsideOfCall.kt"); + } + } + @Nested @TestMetadata("compiler/testData/diagnostics/tests/callableReference/bound") @TestDataPath("$PROJECT_ROOT") diff --git a/compiler/tests-spec/testData/diagnostics/linked/overload-resolution/resolving-callable-references/resolving-callable-references-not-used-as-arguments-to-a-call/p-1/neg/1.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/overload-resolution/resolving-callable-references/resolving-callable-references-not-used-as-arguments-to-a-call/p-1/neg/1.1.fir.kt index 2d0bf501a7d..76480559666 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/overload-resolution/resolving-callable-references/resolving-callable-references-not-used-as-arguments-to-a-call/p-1/neg/1.1.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/overload-resolution/resolving-callable-references/resolving-callable-references-not-used-as-arguments-to-a-call/p-1/neg/1.1.fir.kt @@ -16,11 +16,11 @@ class Case1() { } fun case1() { - val y0: (String)-> Case1 = ::foo - val y1: (String)-> Case1 = Case1.Companion::foo - val y2: (String)-> Case1 = (Case1)::foo + val y0: (String)-> Case1 = ::foo + val y1: (String)-> Case1 = Case1.Companion::foo + val y2: (String)-> Case1 = (Case1)::foo } -fun case1_0() : (String)-> Case1 = ::foo -fun case1_1() : (String)-> Case1 = (Case1)::foo -fun case1_2(): (String)-> Case1 = Case1.Companion::foo +fun case1_0() : (String)-> Case1 = ::foo +fun case1_1() : (String)-> Case1 = (Case1)::foo +fun case1_2(): (String)-> Case1 = Case1.Companion::foo