[FIR] Fix callable references to fields / parameters / etc.

Before this commit, only references to functions & properties
were possible, now fields & parameters are also supported
This commit is contained in:
Mikhail Glukhikh
2020-01-22 11:50:57 +03:00
parent c37394ec83
commit 2086c34cb9
12 changed files with 57 additions and 29 deletions
@@ -194,7 +194,7 @@ internal object CheckCallableReferenceExpectedType : CheckerStage() {
val resultingType: ConeKotlinType = when (fir) { val resultingType: ConeKotlinType = when (fir) {
is FirFunction -> createKFunctionType(fir, resultingReceiverType, returnTypeRef) is FirFunction -> createKFunctionType(fir, resultingReceiverType, returnTypeRef)
is FirProperty -> createKPropertyType(fir, resultingReceiverType, returnTypeRef) is FirVariable<*> -> createKPropertyType(fir, resultingReceiverType, returnTypeRef)
else -> ConeKotlinErrorType("Unknown callable kind: ${fir::class}") else -> ConeKotlinErrorType("Unknown callable kind: ${fir::class}")
}.let(candidate.substitutor::substituteOrSelf) }.let(candidate.substitutor::substituteOrSelf)
@@ -234,13 +234,13 @@ internal object CheckCallableReferenceExpectedType : CheckerStage() {
} }
private fun createKPropertyType( private fun createKPropertyType(
property: FirProperty, propertyOrField: FirVariable<*>,
receiverType: ConeKotlinType?, receiverType: ConeKotlinType?,
returnTypeRef: FirResolvedTypeRef returnTypeRef: FirResolvedTypeRef
): ConeKotlinType { ): ConeKotlinType {
val propertyType = returnTypeRef.coneTypeSafe<ConeKotlinType>() ?: ConeKotlinErrorType("No type for of $property") val propertyType = returnTypeRef.coneTypeSafe<ConeKotlinType>() ?: ConeKotlinErrorType("No type for of $propertyOrField")
return createKPropertyType( return createKPropertyType(
receiverType, propertyType, isMutable = property.isVar receiverType, propertyType, isMutable = propertyOrField.isVar
) )
} }
@@ -0,0 +1,13 @@
// FILE: JavaClass.java
public class JavaClass {
public static String staticField;
public String nonStaticField;
}
// FILE: test.kt
fun test() {
val staticReference = JavaClass::staticField
val nonStaticReference = JavaClass::nonStaticField
}
@@ -0,0 +1,5 @@
FILE: test.kt
public final fun test(): R|kotlin/Unit| {
lval staticReference: R|kotlin/reflect/KMutableProperty1<JavaClass, ft<kotlin/String, kotlin/String?>!>| = Q|JavaClass|::R|/JavaClass.staticField|
lval nonStaticReference: R|kotlin/reflect/KMutableProperty1<JavaClass, ft<kotlin/String, kotlin/String?>!>| = Q|JavaClass|::R|/JavaClass.nonStaticField|
}
@@ -504,6 +504,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
runTest("compiler/fir/resolve/testData/resolve/expresssions/innerQualifier.kt"); runTest("compiler/fir/resolve/testData/resolve/expresssions/innerQualifier.kt");
} }
@TestMetadata("javaFieldCallable.kt")
public void testJavaFieldCallable() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/expresssions/javaFieldCallable.kt");
}
@TestMetadata("lambda.kt") @TestMetadata("lambda.kt")
public void testLambda() throws Exception { public void testLambda() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/expresssions/lambda.kt"); runTest("compiler/fir/resolve/testData/resolve/expresssions/lambda.kt");
@@ -504,6 +504,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
runTest("compiler/fir/resolve/testData/resolve/expresssions/innerQualifier.kt"); runTest("compiler/fir/resolve/testData/resolve/expresssions/innerQualifier.kt");
} }
@TestMetadata("javaFieldCallable.kt")
public void testJavaFieldCallable() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/expresssions/javaFieldCallable.kt");
}
@TestMetadata("lambda.kt") @TestMetadata("lambda.kt")
public void testLambda() throws Exception { public void testLambda() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/expresssions/lambda.kt"); runTest("compiler/fir/resolve/testData/resolve/expresssions/lambda.kt");
@@ -17,10 +17,10 @@ public class JavaClass {
import kotlin.reflect.* import kotlin.reflect.*
fun test() { fun test() {
val pubFinRef: KProperty1<JavaClass, Int> = <!UNRESOLVED_REFERENCE!>JavaClass::publicFinal<!> val pubFinRef: KProperty1<JavaClass, Int> = JavaClass::publicFinal
val pubMutRef: KMutableProperty1<JavaClass, Long> = <!UNRESOLVED_REFERENCE!>JavaClass::publicMutable<!> val pubMutRef: KMutableProperty1<JavaClass, Long> = JavaClass::publicMutable
val protFinRef: KProperty1<JavaClass, Double> = <!UNRESOLVED_REFERENCE!>JavaClass::protectedFinal<!> val protFinRef: KProperty1<JavaClass, Double> = JavaClass::protectedFinal
val protMutRef: KMutableProperty1<JavaClass, Char> = <!UNRESOLVED_REFERENCE!>JavaClass::protectedMutable<!> val protMutRef: KMutableProperty1<JavaClass, Char> = JavaClass::protectedMutable
val privFinRef: KProperty1<JavaClass, String?> = <!UNRESOLVED_REFERENCE!>JavaClass::privateFinal<!> val privFinRef: KProperty1<JavaClass, String?> = <!UNRESOLVED_REFERENCE!>JavaClass::privateFinal<!>
val privMutRef: KMutableProperty1<JavaClass, Any?> = <!UNRESOLVED_REFERENCE!>JavaClass::privateMutable<!> val privMutRef: KMutableProperty1<JavaClass, Any?> = <!UNRESOLVED_REFERENCE!>JavaClass::privateMutable<!>
} }
@@ -19,10 +19,10 @@ import JavaClass.*
import kotlin.reflect.* import kotlin.reflect.*
fun test() { fun test() {
val pubFinRef: KProperty0<String> = <!UNRESOLVED_REFERENCE!>::publicFinal<!> val pubFinRef: KProperty0<String> = ::publicFinal
val pubMutRef: KMutableProperty0<Any?> = <!UNRESOLVED_REFERENCE!>::publicMutable<!> val pubMutRef: KMutableProperty0<Any?> = ::publicMutable
val protFinRef: KProperty<Double> = <!UNRESOLVED_REFERENCE!>::protectedFinal<!> val protFinRef: KProperty<Double> = ::protectedFinal
val protMutRef: KMutableProperty<Char> = <!UNRESOLVED_REFERENCE!>::protectedMutable<!> val protMutRef: KMutableProperty<Char> = ::protectedMutable
val privFinRef: KProperty<JavaClass?> = <!UNRESOLVED_REFERENCE!>::privateFinal<!> val privFinRef: KProperty<JavaClass?> = <!UNRESOLVED_REFERENCE!>::privateFinal<!>
val privMutRef: KMutableProperty<Throwable?> = <!UNRESOLVED_REFERENCE!>::privateMutable<!> val privMutRef: KMutableProperty<Throwable?> = <!UNRESOLVED_REFERENCE!>::privateMutable<!>
} }
@@ -3,7 +3,7 @@
fun eat(value: Any) {} fun eat(value: Any) {}
fun test(param: String) { fun test(param: String) {
val a = <!UNRESOLVED_REFERENCE!>::param<!> val a = ::param
val local = "local" val local = "local"
val b = ::local val b = ::local
@@ -22,6 +22,6 @@ fun main(c: CollectionWithSize) {
CompressionType.ZIP.<!AMBIGUITY!>name<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><Double>() } CompressionType.ZIP.<!AMBIGUITY!>name<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><Double>() }
c.<!AMBIGUITY!>size<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><String>() } c.<!AMBIGUITY!>size<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><String>() }
CompressionType.ZIP::name checkType { <!UNRESOLVED_REFERENCE!>_<!><kotlin.reflect.KProperty0<Double>>() } <!UNRESOLVED_REFERENCE!>CompressionType.ZIP::name<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><kotlin.reflect.KProperty0<Double>>() }
c::size checkType { <!UNRESOLVED_REFERENCE!>_<!><kotlin.reflect.KProperty0<String>>() } <!UNRESOLVED_REFERENCE!>c::size<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><kotlin.reflect.KProperty0<String>>() }
} }
@@ -23,6 +23,6 @@ fun main(c: CollectionWithSize) {
CompressionType.ZIP.<!AMBIGUITY!>name<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><Double>() } CompressionType.ZIP.<!AMBIGUITY!>name<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><Double>() }
c.<!AMBIGUITY!>size<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><String>() } c.<!AMBIGUITY!>size<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><String>() }
CompressionType.ZIP::name checkType { <!UNRESOLVED_REFERENCE!>_<!><kotlin.reflect.KProperty0<Double>>() } <!UNRESOLVED_REFERENCE!>CompressionType.ZIP::name<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><kotlin.reflect.KProperty0<Double>>() }
c::size checkType { <!UNRESOLVED_REFERENCE!>_<!><kotlin.reflect.KProperty0<String>>() } <!UNRESOLVED_REFERENCE!>c::size<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><kotlin.reflect.KProperty0<String>>() }
} }
@@ -22,6 +22,6 @@ fun main(c: CollectionWithSize) {
CompressionType.ZIP.<!AMBIGUITY!>name<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><Double>() } CompressionType.ZIP.<!AMBIGUITY!>name<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><Double>() }
c.<!AMBIGUITY!>size<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><String>() } c.<!AMBIGUITY!>size<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><String>() }
CompressionType.ZIP::name checkType { <!UNRESOLVED_REFERENCE!>_<!><kotlin.reflect.KProperty0<Double>>() } <!UNRESOLVED_REFERENCE!>CompressionType.ZIP::name<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><kotlin.reflect.KProperty0<Double>>() }
c::size checkType { <!UNRESOLVED_REFERENCE!>_<!><kotlin.reflect.KProperty0<String>>() } <!UNRESOLVED_REFERENCE!>c::size<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><kotlin.reflect.KProperty0<String>>() }
} }
@@ -250,23 +250,23 @@ FILE fqName:<root> fileName:/propertyReferences.kt
RETURN type=kotlin.Nothing from='public final fun <get-test_constVal> (): kotlin.reflect.KProperty0<kotlin.Int> declared in <root>' RETURN type=kotlin.Nothing from='public final fun <get-test_constVal> (): kotlin.reflect.KProperty0<kotlin.Int> declared in <root>'
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test_constVal type:kotlin.reflect.KProperty0<kotlin.Int> visibility:private [final,static]' type=kotlin.reflect.KProperty0<kotlin.Int> origin=null GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test_constVal type:kotlin.reflect.KProperty0<kotlin.Int> visibility:private [final,static]' type=kotlin.reflect.KProperty0<kotlin.Int> origin=null
PROPERTY name:test_J_CONST visibility:public modality:FINAL [val] PROPERTY name:test_J_CONST visibility:public modality:FINAL [val]
FIELD PROPERTY_BACKING_FIELD name:test_J_CONST type:IrErrorType visibility:private [final,static] FIELD PROPERTY_BACKING_FIELD name:test_J_CONST type:kotlin.reflect.KProperty1<<root>.J, kotlin.Int> visibility:private [final,static]
EXPRESSION_BODY EXPRESSION_BODY
ERROR_CALL 'Unsupported callable reference: Q|J|::<Unresolved name: CONST>#' type=IrErrorType ERROR_CALL 'Unsupported callable reference: Q|J|::R|/J.CONST|' type=kotlin.reflect.KProperty1<<root>.J, kotlin.Int>
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test_J_CONST> visibility:public modality:FINAL <> () returnType:IrErrorType FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test_J_CONST> visibility:public modality:FINAL <> () returnType:kotlin.reflect.KProperty1<<root>.J, kotlin.Int>
correspondingProperty: PROPERTY name:test_J_CONST visibility:public modality:FINAL [val] correspondingProperty: PROPERTY name:test_J_CONST visibility:public modality:FINAL [val]
BLOCK_BODY BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun <get-test_J_CONST> (): IrErrorType declared in <root>' RETURN type=kotlin.Nothing from='public final fun <get-test_J_CONST> (): kotlin.reflect.KProperty1<<root>.J, kotlin.Int> declared in <root>'
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test_J_CONST type:IrErrorType visibility:private [final,static]' type=IrErrorType origin=null GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test_J_CONST type:kotlin.reflect.KProperty1<<root>.J, kotlin.Int> visibility:private [final,static]' type=kotlin.reflect.KProperty1<<root>.J, kotlin.Int> origin=null
PROPERTY name:test_J_nonConst visibility:public modality:FINAL [val] PROPERTY name:test_J_nonConst visibility:public modality:FINAL [val]
FIELD PROPERTY_BACKING_FIELD name:test_J_nonConst type:IrErrorType visibility:private [final,static] FIELD PROPERTY_BACKING_FIELD name:test_J_nonConst type:kotlin.reflect.KMutableProperty1<<root>.J, kotlin.Int> visibility:private [final,static]
EXPRESSION_BODY EXPRESSION_BODY
ERROR_CALL 'Unsupported callable reference: Q|J|::<Unresolved name: nonConst>#' type=IrErrorType ERROR_CALL 'Unsupported callable reference: Q|J|::R|/J.nonConst|' type=kotlin.reflect.KMutableProperty1<<root>.J, kotlin.Int>
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test_J_nonConst> visibility:public modality:FINAL <> () returnType:IrErrorType FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test_J_nonConst> visibility:public modality:FINAL <> () returnType:kotlin.reflect.KMutableProperty1<<root>.J, kotlin.Int>
correspondingProperty: PROPERTY name:test_J_nonConst visibility:public modality:FINAL [val] correspondingProperty: PROPERTY name:test_J_nonConst visibility:public modality:FINAL [val]
BLOCK_BODY BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun <get-test_J_nonConst> (): IrErrorType declared in <root>' RETURN type=kotlin.Nothing from='public final fun <get-test_J_nonConst> (): kotlin.reflect.KMutableProperty1<<root>.J, kotlin.Int> declared in <root>'
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test_J_nonConst type:IrErrorType visibility:private [final,static]' type=IrErrorType origin=null GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test_J_nonConst type:kotlin.reflect.KMutableProperty1<<root>.J, kotlin.Int> visibility:private [final,static]' type=kotlin.reflect.KMutableProperty1<<root>.J, kotlin.Int> origin=null
PROPERTY name:test_varWithPrivateSet visibility:public modality:FINAL [val] PROPERTY name:test_varWithPrivateSet visibility:public modality:FINAL [val]
FIELD PROPERTY_BACKING_FIELD name:test_varWithPrivateSet type:kotlin.reflect.KMutableProperty1<<root>.C, kotlin.Int> visibility:private [final,static] FIELD PROPERTY_BACKING_FIELD name:test_varWithPrivateSet type:kotlin.reflect.KMutableProperty1<<root>.C, kotlin.Int> visibility:private [final,static]
EXPRESSION_BODY EXPRESSION_BODY