FIR: Run callable references resolution for synthetic-select calls

This commit is contained in:
Denis Zharkov
2020-02-11 13:16:27 +03:00
parent 003aea2e68
commit 5a2cdfcab4
15 changed files with 82 additions and 45 deletions
@@ -17,7 +17,8 @@ enum class CallKind(vararg resolutionSequence: ResolutionStage) {
SyntheticSelect( SyntheticSelect(
MapArguments, MapArguments,
CreateFreshTypeVariableSubstitutorStage, CreateFreshTypeVariableSubstitutorStage,
CheckArguments CheckArguments,
EagerResolveOfCallableReferences
), ),
Function( Function(
CheckVisibility, CheckVisibility,
@@ -185,6 +185,7 @@ internal object CheckArguments : CheckerStage() {
internal object EagerResolveOfCallableReferences : CheckerStage() { internal object EagerResolveOfCallableReferences : CheckerStage() {
override suspend fun check(candidate: Candidate, sink: CheckerSink, callInfo: CallInfo) { override suspend fun check(candidate: Candidate, sink: CheckerSink, callInfo: CallInfo) {
if (candidate.postponedAtoms.isEmpty()) return
for (atom in candidate.postponedAtoms.filterIsInstance<ResolvedCallableReferenceAtom>()) { for (atom in candidate.postponedAtoms.filterIsInstance<ResolvedCallableReferenceAtom>()) {
if (!candidate.bodyResolveComponents.callResolver.resolveCallableReference(candidate.csBuilder, atom)) { if (!candidate.bodyResolveComponents.callResolver.resolveCallableReference(candidate.csBuilder, atom)) {
sink.yieldApplicability(CandidateApplicability.INAPPLICABLE) sink.yieldApplicability(CandidateApplicability.INAPPLICABLE)
@@ -7,7 +7,7 @@ interface KaptLogger {
fun test(logger: KaptLogger) { fun test(logger: KaptLogger) {
val func = if (logger.isVerbose) val func = if (logger.isVerbose)
<!UNRESOLVED_REFERENCE!>logger::warn<!> logger::warn
else else
<!UNRESOLVED_REFERENCE!>logger::error<!> logger::error
} }
@@ -9,12 +9,12 @@ FILE: callableReferenceOnInstance.kt
} }
public final fun test(logger: R|KaptLogger|): R|kotlin/Unit| { public final fun test(logger: R|KaptLogger|): R|kotlin/Unit| {
lval func: R|kotlin/Nothing| = when () { lval func: R|kotlin/reflect/KFunction1<kotlin/String, kotlin/Unit>| = when () {
R|<local>/logger|.R|/KaptLogger.isVerbose| -> { R|<local>/logger|.R|/KaptLogger.isVerbose| -> {
R|<local>/logger|::<Unresolved reference: warn># R|<local>/logger|::R|/KaptLogger.warn|
} }
else -> { else -> {
R|<local>/logger|::<Unresolved reference: error># R|<local>/logger|::R|/KaptLogger.error|
} }
} }
@@ -0,0 +1,8 @@
private var Int.readOnlyWrapper: CharSequence? get() = null
private var Int.mutableWrapper: CharSequence? get() = null
fun main(x: Int) {
val x = if (x > 1) x::readOnlyWrapper else x::mutableWrapper
x.get()
}
@@ -0,0 +1,23 @@
FILE: ifWithCR.kt
private final var R|kotlin/Int|.readOnlyWrapper: R|kotlin/CharSequence?|
public get(): R|kotlin/CharSequence?| {
^ Null(null)
}
private set(value: R|kotlin/CharSequence?|): R|kotlin/Unit|
private final var R|kotlin/Int|.mutableWrapper: R|kotlin/CharSequence?|
public get(): R|kotlin/CharSequence?| {
^ Null(null)
}
private set(value: R|kotlin/CharSequence?|): R|kotlin/Unit|
public final fun main(x: R|kotlin/Int|): R|kotlin/Unit| {
lval x: R|kotlin/reflect/KMutableProperty0<kotlin/CharSequence?>| = when () {
>(R|<local>/x|, Int(1)) -> {
R|<local>/x|::R|/readOnlyWrapper|
}
else -> {
R|<local>/x|::R|/mutableWrapper|
}
}
R|<local>/x|.R|FakeOverride<kotlin/reflect/KProperty0.get: R|kotlin/CharSequence?|>|()
}
@@ -919,6 +919,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/resolve/testData/resolve/inference"), Pattern.compile("^([^.]+)\\.kt$"), null, true); KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/resolve/testData/resolve/inference"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
} }
@TestMetadata("callableReferenceOnInstance.kt")
public void testCallableReferenceOnInstance() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/inference/callableReferenceOnInstance.kt");
}
@TestMetadata("nestedLambdas.kt") @TestMetadata("nestedLambdas.kt")
public void testNestedLambdas() throws Exception { public void testNestedLambdas() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/inference/nestedLambdas.kt"); runTest("compiler/fir/resolve/testData/resolve/inference/nestedLambdas.kt");
@@ -1106,11 +1111,6 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
runTest("compiler/fir/resolve/testData/resolve/problems/bareTypes.kt"); runTest("compiler/fir/resolve/testData/resolve/problems/bareTypes.kt");
} }
@TestMetadata("callableReferenceOnInstance.kt")
public void testCallableReferenceOnInstance() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/problems/callableReferenceOnInstance.kt");
}
@TestMetadata("covariantArrayAsReceiver.kt") @TestMetadata("covariantArrayAsReceiver.kt")
public void testCovariantArrayAsReceiver() throws Exception { public void testCovariantArrayAsReceiver() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/problems/covariantArrayAsReceiver.kt"); runTest("compiler/fir/resolve/testData/resolve/problems/covariantArrayAsReceiver.kt");
@@ -919,6 +919,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/resolve/testData/resolve/inference"), Pattern.compile("^([^.]+)\\.kt$"), null, true); KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/resolve/testData/resolve/inference"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
} }
@TestMetadata("callableReferenceOnInstance.kt")
public void testCallableReferenceOnInstance() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/inference/callableReferenceOnInstance.kt");
}
@TestMetadata("nestedLambdas.kt") @TestMetadata("nestedLambdas.kt")
public void testNestedLambdas() throws Exception { public void testNestedLambdas() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/inference/nestedLambdas.kt"); runTest("compiler/fir/resolve/testData/resolve/inference/nestedLambdas.kt");
@@ -1106,11 +1111,6 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
runTest("compiler/fir/resolve/testData/resolve/problems/bareTypes.kt"); runTest("compiler/fir/resolve/testData/resolve/problems/bareTypes.kt");
} }
@TestMetadata("callableReferenceOnInstance.kt")
public void testCallableReferenceOnInstance() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/problems/callableReferenceOnInstance.kt");
}
@TestMetadata("covariantArrayAsReceiver.kt") @TestMetadata("covariantArrayAsReceiver.kt")
public void testCovariantArrayAsReceiver() throws Exception { public void testCovariantArrayAsReceiver() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/problems/covariantArrayAsReceiver.kt"); runTest("compiler/fir/resolve/testData/resolve/problems/covariantArrayAsReceiver.kt");
@@ -295,6 +295,11 @@ public class FirDiagnosticsWithStdlibTestGenerated extends AbstractFirDiagnostic
runTest("compiler/fir/resolve/testData/resolve/stdlib/callableReferences/extensionReceiverInference.kt"); runTest("compiler/fir/resolve/testData/resolve/stdlib/callableReferences/extensionReceiverInference.kt");
} }
@TestMetadata("ifWithCR.kt")
public void testIfWithCR() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/stdlib/callableReferences/ifWithCR.kt");
}
@TestMetadata("implicitTypes.kt") @TestMetadata("implicitTypes.kt")
public void testImplicitTypes() throws Exception { public void testImplicitTypes() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/stdlib/callableReferences/implicitTypes.kt"); runTest("compiler/fir/resolve/testData/resolve/stdlib/callableReferences/implicitTypes.kt");
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
fun baz(i: Int) = i fun baz(i: Int) = i
fun <T> bar(x: T): T = x fun <T> bar(x: T): T = x
@@ -27,4 +26,4 @@ fun box(): String {
if ((if (true) ::baz else ::baz)(1) != 1) return "fail 6" if ((if (true) ::baz else ::baz)(1) != 1) return "fail 6"
return "OK" return "OK"
} }
@@ -7,11 +7,11 @@ fun test() {
val a = if (true) { val a = if (true) {
val x = 1 val x = 1
"".length "".length
<!UNRESOLVED_REFERENCE!>::foo<!> ::foo
} else { } else {
<!UNRESOLVED_REFERENCE!>::foo<!> ::foo
} }
a checkType { <!UNRESOLVED_REFERENCE!>_<!><KFunction0<Int>>() } a checkType { <!UNRESOLVED_REFERENCE!>_<!><KFunction0<Int>>() }
} }
fun foo(): Int = 0 fun foo(): Int = 0
@@ -6,18 +6,18 @@ fun <T> bar(x: T): T = TODO()
fun nullableFun(): ((Int) -> Int)? = null fun nullableFun(): ((Int) -> Int)? = null
fun test() { fun test() {
val x1: (Int) -> Int = bar(if (true) <!UNRESOLVED_REFERENCE!>::baz<!> else <!UNRESOLVED_REFERENCE!>::baz<!>) val x1: (Int) -> Int = bar(if (true) ::baz else ::baz)
val x2: (Int) -> Int = bar(nullableFun() ?: <!UNRESOLVED_REFERENCE!>::baz<!>) val x2: (Int) -> Int = bar(nullableFun() ?: ::baz)
val x3: (Int) -> Int = bar(::baz ?: <!UNRESOLVED_REFERENCE!>::baz<!>) val x3: (Int) -> Int = bar(::baz ?: ::baz)
val i = 0 val i = 0
val x4: (Int) -> Int = bar(when (i) { val x4: (Int) -> Int = bar(when (i) {
10 -> <!UNRESOLVED_REFERENCE!>::baz<!> 10 -> ::baz
20 -> <!UNRESOLVED_REFERENCE!>::baz<!> 20 -> ::baz
else -> <!UNRESOLVED_REFERENCE!>::baz<!> else -> ::baz
}) })
val x5: (Int) -> Int = bar(<!UNRESOLVED_REFERENCE!>::baz<!>!!) val x5: (Int) -> Int = bar(::baz!!)
<!UNRESOLVED_REFERENCE!>(if (true) <!UNRESOLVED_REFERENCE!>::baz<!> else <!UNRESOLVED_REFERENCE!>::baz<!>)(1)<!> (if (true) ::baz else ::baz)(1)
} }
@@ -2,10 +2,10 @@
fun test() { fun test() {
data class Pair<F, S>(val first: F, val second: S) data class Pair<F, S>(val first: F, val second: S)
val (x, y) = val (<!UNRESOLVED_REFERENCE!>x<!>, <!UNRESOLVED_REFERENCE!>y<!>) =
Pair(1, <!INAPPLICABLE_CANDIDATE!>Pair<!>(1,
if (1 == 1) if (1 == 1)
<!UNRESOLVED_REFERENCE!>Pair<String, String>::first<!> Pair<String, String>::first
else else
<!UNRESOLVED_REFERENCE!>Pair<String, String>::second<!>) Pair<String, String>::second)
} }
@@ -18,8 +18,8 @@ class Foo(val a: String, val b: String)
fun test2() { fun test2() {
val prop : Foo.() -> String = if (true) { val prop : Foo.() -> String = if (true) {
<!UNRESOLVED_REFERENCE!>Foo::a<!> Foo::a
} else { } else {
<!UNRESOLVED_REFERENCE!>Foo::b<!> Foo::b
} }
} }
@@ -4,33 +4,33 @@
fun testWhen(x: Any?) { fun testWhen(x: Any?) {
val y = when (x) { val y = when (x) {
null -> "" null -> ""
else -> <!UNRESOLVED_REFERENCE!>::unresolved<!> else -> ::unresolved
} }
} }
fun testWhenWithBraces(x: Any?) { fun testWhenWithBraces(x: Any?) {
val z = when(x) { val z = when(x) {
null -> { "" } null -> { "" }
else -> { <!UNRESOLVED_REFERENCE!>::unresolved<!> } else -> { ::unresolved }
} }
} }
fun testIf(x: Any?) { fun testIf(x: Any?) {
val y = if (x != null) <!UNRESOLVED_REFERENCE!>::unresolved<!> else null val y = if (x != null) ::unresolved else null
} }
fun testIfWithBraces(x: Any?) { fun testIfWithBraces(x: Any?) {
val z = if (x != null) { <!UNRESOLVED_REFERENCE!>::unresolved<!> } else { null } val z = if (x != null) { ::unresolved } else { null }
} }
fun testElvis(x: Any?) { fun testElvis(x: Any?) {
val y = x ?: <!UNRESOLVED_REFERENCE!>::unresolved<!> val y = x ?: ::unresolved
} }
fun testExclExcl() { fun testExclExcl() {
val y = <!UNRESOLVED_REFERENCE!>:: unresolved<!>!! val y = :: unresolved!!
} }
fun testTry() { fun testTry() {
val v = try { <!UNRESOLVED_REFERENCE!>::unresolved<!> } catch (e: Exception) {} val v = try { ::unresolved } catch (e: Exception) {}
} }