FIR: Support callable references to properties
^KT-32725 In Progress
This commit is contained in:
@@ -226,6 +226,15 @@ fun createFunctionalType(
|
||||
return ConeClassTypeImpl(ConeClassLikeLookupTagImpl(functionalTypeId), receiverAndParameterTypes.toTypedArray(), isNullable = false)
|
||||
}
|
||||
|
||||
fun createKPropertyType(
|
||||
receiverType: ConeKotlinType?,
|
||||
rawReturnType: ConeKotlinType
|
||||
): ConeLookupTagBasedType {
|
||||
val arguments = if (receiverType != null) listOf(receiverType, rawReturnType) else listOf(rawReturnType)
|
||||
val classId = StandardClassIds.reflectByName("KProperty${arguments.size - 1}")
|
||||
return ConeClassTypeImpl(ConeClassLikeLookupTagImpl(classId), arguments.toTypedArray(), isNullable = false)
|
||||
}
|
||||
|
||||
fun BodyResolveComponents.typeForQualifier(resolvedQualifier: FirResolvedQualifier): FirTypeRef {
|
||||
val classId = resolvedQualifier.classId
|
||||
val resultType = resolvedQualifier.resultType
|
||||
|
||||
+2
-3
@@ -150,8 +150,7 @@ fun createCallableReferencesConsumer(
|
||||
// TODO: Use SamePriorityConsumer
|
||||
return PrioritizedTowerDataConsumer(
|
||||
resultCollector,
|
||||
createSimpleConsumer(session, name, TowerScopeLevel.Token.Functions, callInfo, bodyResolveComponents, resultCollector)
|
||||
// TODO: Support properties
|
||||
// , createSimpleConsumer(session, name, TowerScopeLevel.Token.Properties, callInfo, bodyResolveComponents, resultCollector)
|
||||
createSimpleConsumer(session, name, TowerScopeLevel.Token.Functions, callInfo, bodyResolveComponents, resultCollector),
|
||||
createSimpleConsumer(session, name, TowerScopeLevel.Token.Properties, callInfo, bodyResolveComponents, resultCollector)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.declarations.visibility
|
||||
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
|
||||
import org.jetbrains.kotlin.fir.resolve.DoubleColonLHS
|
||||
import org.jetbrains.kotlin.fir.resolve.createFunctionalType
|
||||
import org.jetbrains.kotlin.fir.resolve.createKPropertyType
|
||||
import org.jetbrains.kotlin.fir.resolve.firProvider
|
||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
@@ -185,7 +186,7 @@ internal object CheckCallableReferenceExpectedType : CheckerStage() {
|
||||
|
||||
val resultingType: ConeKotlinType = when (val fir = candidate.symbol.fir) {
|
||||
is FirSimpleFunction -> createKFunctionType(fir, resultingReceiverType)
|
||||
is FirProperty -> createKPropertyType(fir)
|
||||
is FirProperty -> createKPropertyType(fir, resultingReceiverType)
|
||||
else -> ConeKotlinErrorType("Unknown callable kind: ${fir::class}")
|
||||
}.let(candidate.substitutor::substituteOrSelf)
|
||||
|
||||
@@ -210,8 +211,14 @@ internal object CheckCallableReferenceExpectedType : CheckerStage() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun createKPropertyType(fir: FirProperty): ConeKotlinType {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
private fun createKPropertyType(
|
||||
property: FirProperty,
|
||||
receiverType: ConeKotlinType?
|
||||
): ConeKotlinType {
|
||||
val propertyType = property.returnTypeRef.coneTypeSafe<ConeKotlinType>() ?: ConeKotlinErrorType("No type for of $property")
|
||||
return createKPropertyType(
|
||||
receiverType, propertyType
|
||||
)
|
||||
}
|
||||
|
||||
private fun createKFunctionType(
|
||||
|
||||
+4
-4
@@ -16,7 +16,7 @@ FILE: noAmbiguityBetweenTopLevelAndMemberProperty.kt
|
||||
public get(): R|kotlin/String|
|
||||
|
||||
}
|
||||
public final val someProperty0: <ERROR TYPE REF: Inapplicable(INAPPLICABLE): [/property, /property]> = <Inapplicable(INAPPLICABLE): [/property, /property]>#(::subject#)
|
||||
public get(): <ERROR TYPE REF: Inapplicable(INAPPLICABLE): [/property, /property]>
|
||||
public final val someProperty1: <ERROR TYPE REF: Inapplicable(INAPPLICABLE): [/property, /property]> = <Inapplicable(INAPPLICABLE): [/property, /property]>#(Q|O|::subject#)
|
||||
public get(): <ERROR TYPE REF: Inapplicable(INAPPLICABLE): [/property, /property]>
|
||||
public final val someProperty0: R|kotlin/Int| = R|/property|<R|kotlin/String|>(::R|/subject|)
|
||||
public get(): R|kotlin/Int|
|
||||
public final val someProperty1: R|kotlin/String| = R|/property|<R|O|, R|kotlin/String|>(Q|O|::R|/O.subject|)
|
||||
public get(): R|kotlin/String|
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
class A {
|
||||
val bar: Int = 1
|
||||
}
|
||||
|
||||
val bar = 1
|
||||
|
||||
val A.baz: Int get() = 1
|
||||
|
||||
fun foo1(x: () -> Int) {}
|
||||
fun foo2(x: (A) -> Int) {}
|
||||
|
||||
fun <R> foo3(x: () -> R) {}
|
||||
fun <T, R> foo4(x: (T) -> R) {}
|
||||
|
||||
fun main() {
|
||||
foo1(::bar)
|
||||
foo2(A::bar)
|
||||
foo2(A::baz)
|
||||
|
||||
foo3(::bar)
|
||||
foo4(A::bar)
|
||||
foo4(A::baz)
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
FILE: properties.kt
|
||||
public final class A : R|kotlin/Any| {
|
||||
public constructor(): R|A| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public final val bar: R|kotlin/Int| = Int(1)
|
||||
public get(): R|kotlin/Int|
|
||||
|
||||
}
|
||||
public final val bar: R|kotlin/Int| = Int(1)
|
||||
public get(): R|kotlin/Int|
|
||||
public final val R|A|.baz: R|kotlin/Int|
|
||||
public get(): R|kotlin/Int| {
|
||||
^ Int(1)
|
||||
}
|
||||
public final fun foo1(x: R|kotlin/Function0<kotlin/Int>|): R|kotlin/Unit| {
|
||||
}
|
||||
public final fun foo2(x: R|kotlin/Function1<A, kotlin/Int>|): R|kotlin/Unit| {
|
||||
}
|
||||
public final fun <R> foo3(x: R|kotlin/Function0<R>|): R|kotlin/Unit| {
|
||||
}
|
||||
public final fun <T, R> foo4(x: R|kotlin/Function1<T, R>|): R|kotlin/Unit| {
|
||||
}
|
||||
public final fun main(): R|kotlin/Unit| {
|
||||
R|/foo1|(::R|/bar|)
|
||||
R|/foo2|(Q|A|::R|/A.bar|)
|
||||
R|/foo2|(Q|A|::R|/baz|)
|
||||
R|/foo3|<R|kotlin/Int|>(::R|/bar|)
|
||||
R|/foo4|<R|A|, R|kotlin/Int|>(Q|A|::R|/A.bar|)
|
||||
R|/foo4|<R|A|, R|kotlin/Int|>(Q|A|::R|/baz|)
|
||||
}
|
||||
+1
-1
@@ -23,5 +23,5 @@ FILE: extensionPropertyInLambda.kt
|
||||
R|/C.C|<R|kotlin/String|>(String(abc)).R|/y|
|
||||
}
|
||||
)
|
||||
R|/use|(R|/C.C|<R|kotlin/String|>(String(abc))::R|/y|)
|
||||
R|/use|(R|/C.C|<R|kotlin/String|>(String(abc))::R|/y<kotlin/String>|)
|
||||
}
|
||||
|
||||
+5
@@ -90,6 +90,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
|
||||
runTest("compiler/fir/resolve/testData/diagnostics/callableReferences/manyOuterCandidates.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("properties.kt")
|
||||
public void testProperties() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/diagnostics/callableReferences/properties.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("simpleClassReceiver.kt")
|
||||
public void testSimpleClassReceiver() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/diagnostics/callableReferences/simpleClassReceiver.kt");
|
||||
|
||||
Reference in New Issue
Block a user