K2: Support callable references adaptation on top-level
^KT-45989 In progress ^KT-54709 Related ^KT-55217 Fixed
This commit is contained in:
committed by
Space Team
parent
8f8ea8c57f
commit
dcdc48a233
+16
@@ -3102,6 +3102,22 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
|
|||||||
runTest("compiler/testData/diagnostics/tests/callableReference/withQuestionMarks.kt");
|
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
|
@Nested
|
||||||
@TestMetadata("compiler/testData/diagnostics/tests/callableReference/bound")
|
@TestMetadata("compiler/testData/diagnostics/tests/callableReference/bound")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
|||||||
+16
@@ -3108,6 +3108,22 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
|||||||
runTest("compiler/testData/diagnostics/tests/callableReference/withQuestionMarks.kt");
|
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
|
@Nested
|
||||||
@TestMetadata("compiler/testData/diagnostics/tests/callableReference/bound")
|
@TestMetadata("compiler/testData/diagnostics/tests/callableReference/bound")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
|||||||
+16
@@ -3102,6 +3102,22 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
|||||||
runTest("compiler/testData/diagnostics/tests/callableReference/withQuestionMarks.kt");
|
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
|
@Nested
|
||||||
@TestMetadata("compiler/testData/diagnostics/tests/callableReference/bound")
|
@TestMetadata("compiler/testData/diagnostics/tests/callableReference/bound")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
|||||||
@@ -34,4 +34,9 @@ object SyntheticCallableId {
|
|||||||
syntheticPackageName,
|
syntheticPackageName,
|
||||||
Name.identifier("ID_CALL")
|
Name.identifier("ID_CALL")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val ACCEPT_SPECIFIC_TYPE = CallableId(
|
||||||
|
syntheticPackageName,
|
||||||
|
Name.identifier("ACCEPT_SPECIFIC_TYPE_CALL")
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+17
-17
@@ -154,34 +154,36 @@ class FirSyntheticCallGenerator(
|
|||||||
): FirCallableReferenceAccess? {
|
): FirCallableReferenceAccess? {
|
||||||
val argumentList = buildUnaryArgumentList(callableReferenceAccess)
|
val argumentList = buildUnaryArgumentList(callableReferenceAccess)
|
||||||
|
|
||||||
val typeArguments =
|
val parameterTypeRef =
|
||||||
when {
|
when {
|
||||||
expectedTypeRef is FirResolvedTypeRef && !expectedTypeRef.coneType.isUnitOrFlexibleUnit -> listOf(
|
expectedTypeRef is FirResolvedTypeRef && !expectedTypeRef.coneType.isUnitOrFlexibleUnit -> expectedTypeRef
|
||||||
buildTypeProjectionWithVariance {
|
else -> context.session.builtinTypes.anyType
|
||||||
variance = Variance.INVARIANT
|
|
||||||
typeRef = expectedTypeRef
|
|
||||||
}
|
|
||||||
)
|
|
||||||
else -> emptyList()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val callableId = SyntheticCallableId.ACCEPT_SPECIFIC_TYPE
|
||||||
|
val functionSymbol = FirSyntheticFunctionSymbol(callableId)
|
||||||
|
// fun accept(p: <parameterTypeRef>): Unit
|
||||||
|
val function =
|
||||||
|
generateMemberFunction(functionSymbol, callableId.callableName, returnType = context.session.builtinTypes.unitType).apply {
|
||||||
|
valueParameters += parameterTypeRef.toValueParameter("reference", functionSymbol, isVararg = false)
|
||||||
|
}.build()
|
||||||
|
|
||||||
val reference =
|
val reference =
|
||||||
generateCalleeReferenceWithCandidate(
|
generateCalleeReferenceWithCandidate(
|
||||||
callableReferenceAccess,
|
callableReferenceAccess,
|
||||||
idFunction,
|
function,
|
||||||
argumentList,
|
argumentList,
|
||||||
SyntheticCallableId.ID.callableName,
|
callableId.callableName,
|
||||||
CallKind.SyntheticIdForCallableReferencesResolution,
|
CallKind.SyntheticIdForCallableReferencesResolution,
|
||||||
context,
|
context,
|
||||||
typeArguments,
|
|
||||||
)
|
)
|
||||||
val fakeCallElement = buildFunctionCall {
|
val fakeCallElement = buildFunctionCall {
|
||||||
calleeReference = reference
|
calleeReference = reference
|
||||||
this.argumentList = argumentList
|
this.argumentList = argumentList
|
||||||
}
|
}
|
||||||
|
|
||||||
val argument = components.callCompleter.completeCall(fakeCallElement, expectedTypeRef).result.argument
|
val argument = components.callCompleter.completeCall(fakeCallElement, expectedTypeRef = null).result.argument
|
||||||
return ((argument as? FirVarargArgumentsExpression)?.arguments?.get(0) ?: argument) as FirCallableReferenceAccess?
|
return argument as FirCallableReferenceAccess?
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateCalleeReferenceWithCandidate(
|
private fun generateCalleeReferenceWithCandidate(
|
||||||
@@ -191,9 +193,8 @@ class FirSyntheticCallGenerator(
|
|||||||
name: Name,
|
name: Name,
|
||||||
callKind: CallKind = CallKind.SyntheticSelect,
|
callKind: CallKind = CallKind.SyntheticSelect,
|
||||||
context: ResolutionContext,
|
context: ResolutionContext,
|
||||||
typeArguments: List<FirTypeProjection> = emptyList()
|
|
||||||
): FirNamedReferenceWithCandidate {
|
): FirNamedReferenceWithCandidate {
|
||||||
val callInfo = generateCallInfo(callSite, name, argumentList, callKind, typeArguments)
|
val callInfo = generateCallInfo(callSite, name, argumentList, callKind)
|
||||||
val candidate = generateCandidate(callInfo, function, context)
|
val candidate = generateCandidate(callInfo, function, context)
|
||||||
val applicability = components.resolutionStageRunner.processCandidate(candidate, context)
|
val applicability = components.resolutionStageRunner.processCandidate(candidate, context)
|
||||||
if (applicability <= CandidateApplicability.INAPPLICABLE) {
|
if (applicability <= CandidateApplicability.INAPPLICABLE) {
|
||||||
@@ -224,7 +225,6 @@ class FirSyntheticCallGenerator(
|
|||||||
name: Name,
|
name: Name,
|
||||||
argumentList: FirArgumentList,
|
argumentList: FirArgumentList,
|
||||||
callKind: CallKind,
|
callKind: CallKind,
|
||||||
typeArguments: List<FirTypeProjection> = emptyList()
|
|
||||||
) = CallInfo(
|
) = CallInfo(
|
||||||
callSite = callSite,
|
callSite = callSite,
|
||||||
callKind = callKind,
|
callKind = callKind,
|
||||||
@@ -232,7 +232,7 @@ class FirSyntheticCallGenerator(
|
|||||||
explicitReceiver = null,
|
explicitReceiver = null,
|
||||||
argumentList = argumentList,
|
argumentList = argumentList,
|
||||||
isImplicitInvoke = false,
|
isImplicitInvoke = false,
|
||||||
typeArguments = typeArguments,
|
typeArguments = emptyList(),
|
||||||
session = session,
|
session = session,
|
||||||
containingFile = components.file,
|
containingFile = components.file,
|
||||||
containingDeclarations = components.containingDeclarations
|
containingDeclarations = components.containingDeclarations
|
||||||
|
|||||||
Vendored
+10
@@ -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)
|
||||||
|
}
|
||||||
Vendored
+10
@@ -0,0 +1,10 @@
|
|||||||
|
// SKIP_TXT
|
||||||
|
fun baz(options: String = ""): String = ""
|
||||||
|
|
||||||
|
fun runForString(x: () -> String) {}
|
||||||
|
|
||||||
|
fun foo(dumpStrategy: String) {
|
||||||
|
val dump0: () -> String = <!TYPE_MISMATCH!>::<!TYPE_MISMATCH!>baz<!><!>
|
||||||
|
|
||||||
|
runForString(::baz)
|
||||||
|
}
|
||||||
Vendored
+1
-1
@@ -5,5 +5,5 @@ fun foo(x: Any, y: Int) = y
|
|||||||
fun main() {
|
fun main() {
|
||||||
::<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!>
|
::<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!>
|
||||||
|
|
||||||
val fooRef: (Int, Any) -> Unit = ::<!UNRESOLVED_REFERENCE!>foo<!>
|
val fooRef: (Int, Any) -> Unit = ::foo
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -6,5 +6,5 @@ fun foo(i: Int) {}
|
|||||||
|
|
||||||
val fn1: (Int) -> Unit = ::foo
|
val fn1: (Int) -> Unit = ::foo
|
||||||
val fn2: (IntArray) -> Unit = ::foo
|
val fn2: (IntArray) -> Unit = ::foo
|
||||||
val fn3: (Int, Int) -> Unit = ::<!UNRESOLVED_REFERENCE!>foo<!>
|
val fn3: (Int, Int) -> Unit = ::foo
|
||||||
val fn4: (Array<String>) -> Unit = ::foo
|
val fn4: (Array<String>) -> Unit = ::foo
|
||||||
|
|||||||
+3
-4
@@ -4,8 +4,7 @@
|
|||||||
fun main(b: Boolean) {
|
fun main(b: Boolean) {
|
||||||
callWithLambda {
|
callWithLambda {
|
||||||
// The only relevant case for KT-55729, Unit conversion should work, but doesn't in K1 1.8.0
|
// 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
|
||||||
::<!UNRESOLVED_REFERENCE!>test1<!>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
callWithLambda {
|
callWithLambda {
|
||||||
@@ -23,8 +22,8 @@ fun main(b: Boolean) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
callWithLambda {
|
callWithLambda {
|
||||||
// That hasn't been working ever in K1 nor K2
|
// Doesn't work in K1, but does in K2
|
||||||
(::<!UNRESOLVED_REFERENCE!>test1<!>)
|
(::test1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Vendored
+1
-2
@@ -4,7 +4,6 @@
|
|||||||
fun main(b: Boolean) {
|
fun main(b: Boolean) {
|
||||||
callWithLambda {
|
callWithLambda {
|
||||||
// The only relevant case for KT-55729, Unit conversion should work, but doesn't in K1 1.8.0
|
// 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
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,7 +22,7 @@ fun main(b: Boolean) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
callWithLambda {
|
callWithLambda {
|
||||||
// That hasn't been working ever in K1 nor K2
|
// Doesn't work in K1, but does in K2
|
||||||
(<!TYPE_MISMATCH, TYPE_MISMATCH!>::<!TYPE_MISMATCH!>test1<!><!>)
|
(<!TYPE_MISMATCH, TYPE_MISMATCH!>::<!TYPE_MISMATCH!>test1<!><!>)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+16
@@ -3108,6 +3108,22 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
|||||||
runTest("compiler/testData/diagnostics/tests/callableReference/withQuestionMarks.kt");
|
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
|
@Nested
|
||||||
@TestMetadata("compiler/testData/diagnostics/tests/callableReference/bound")
|
@TestMetadata("compiler/testData/diagnostics/tests/callableReference/bound")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
|||||||
+6
-6
@@ -16,11 +16,11 @@ class Case1() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
fun case1() {
|
fun case1() {
|
||||||
val y0: (String)-> Case1 = ::<!UNRESOLVED_REFERENCE!>foo<!>
|
val y0: (String)-> Case1 = ::foo
|
||||||
val y1: (String)-> Case1 = Case1.Companion::<!UNRESOLVED_REFERENCE!>foo<!>
|
val y1: (String)-> Case1 = Case1.Companion::foo
|
||||||
val y2: (String)-> Case1 = (Case1)::<!UNRESOLVED_REFERENCE!>foo<!>
|
val y2: (String)-> Case1 = (Case1)::foo
|
||||||
}
|
}
|
||||||
|
|
||||||
fun case1_0() : (String)-> Case1 = ::<!UNRESOLVED_REFERENCE!>foo<!>
|
fun case1_0() : (String)-> Case1 = ::foo
|
||||||
fun case1_1() : (String)-> Case1 = (Case1)::<!UNRESOLVED_REFERENCE!>foo<!>
|
fun case1_1() : (String)-> Case1 = (Case1)::foo
|
||||||
fun case1_2(): (String)-> Case1 = Case1.Companion::<!UNRESOLVED_REFERENCE!>foo<!>
|
fun case1_2(): (String)-> Case1 = Case1.Companion::foo
|
||||||
|
|||||||
Reference in New Issue
Block a user