[FIR] Transform qualified access / callable refs type arguments properly

This commit is contained in:
Mikhail Glukhikh
2020-01-24 10:43:31 +03:00
parent 483ce8bf04
commit 7721eaab23
7 changed files with 36 additions and 20 deletions
@@ -14,10 +14,9 @@ import org.jetbrains.kotlin.fir.declarations.FirTypeAlias
import org.jetbrains.kotlin.fir.declarations.expandedConeType
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.references.FirNamedReference
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.ConeStarProjection
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
import org.jetbrains.kotlin.types.Variance
sealed class DoubleColonLHS(val type: ConeKotlinType) {
/**
@@ -153,7 +152,22 @@ class FirDoubleColonExpressionResolver(
val type = ConeClassLikeTypeImpl(
firClass.symbol.toLookupTag(),
Array(firClass.typeParameters.size) { ConeStarProjection },
Array(firClass.typeParameters.size) { index ->
val typeArgument = expression.typeArguments.getOrNull(index)
if (typeArgument == null) ConeStarProjection
else when (typeArgument) {
is FirTypeProjectionWithVariance -> {
val coneType = typeArgument.typeRef.coneTypeSafe<ConeKotlinType>()
if (coneType == null) ConeStarProjection
else when (typeArgument.variance) {
Variance.INVARIANT -> coneType
Variance.IN_VARIANCE -> ConeKotlinTypeProjectionIn(coneType)
Variance.OUT_VARIANCE -> ConeKotlinTypeProjectionOut(coneType)
}
}
else -> ConeStarProjection
}
},
isNullable = false // TODO: Use org.jetbrains.kotlin.psi.KtDoubleColonExpression.getHasQuestionMarks
)
@@ -64,6 +64,8 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) :
data: ResolutionMode
): CompositeTransformResult<FirStatement> {
qualifiedAccessExpression.annotations.forEach { it.accept(this, data) }
qualifiedAccessExpression.transformTypeArguments(transformer, ResolutionMode.ContextIndependent)
var result = when (val callee = qualifiedAccessExpression.calleeReference) {
is FirExplicitThisReference -> {
val labelName = callee.labelName
@@ -9,5 +9,5 @@ class A<T>(val t: T) {
fun bar() {
val x = A<String>::foo
<!INAPPLICABLE_CANDIDATE!>checkSubtype<!><KFunction1<A<String>, String>>(x)
checkSubtype<KFunction1<A<String>, String>>(x)
}
@@ -8,8 +8,8 @@ class A<T>(val t: T) {
fun bar() {
val x = A<String>::foo
<!INAPPLICABLE_CANDIDATE!>checkSubtype<!><KProperty1<A<String>, String>>(x)
<!INAPPLICABLE_CANDIDATE!>checkSubtype<!><KProperty1<A<String>, Any?>>(x)
checkSubtype<KProperty1<A<String>, String>>(x)
checkSubtype<KProperty1<A<String>, Any?>>(x)
val y = A<*>::foo
checkSubtype<KProperty1<A<*>, Any?>>(y)
@@ -12,5 +12,5 @@ fun <V, T : V?> G<T>.foo(vararg values: V2<V?>) = build()
fun forReference(ref: Any?) {}
fun test() {
<!INAPPLICABLE_CANDIDATE!>forReference<!>(<!UNRESOLVED_REFERENCE!>G<Int?>::foo<!>)
forReference(<!UNRESOLVED_REFERENCE!>G<Int?>::foo<!>)
}
@@ -34,20 +34,20 @@ FILE fqName:<root> fileName:/genericMember.kt
public open fun toString (): kotlin.String declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
PROPERTY name:test1 visibility:public modality:FINAL [val]
FIELD PROPERTY_BACKING_FIELD name:test1 type:kotlin.reflect.KFunction1<<root>.A<*>, kotlin.Unit> visibility:private [final,static]
FIELD PROPERTY_BACKING_FIELD name:test1 type:kotlin.reflect.KFunction1<<root>.A<kotlin.String>, kotlin.Unit> visibility:private [final,static]
EXPRESSION_BODY
FUNCTION_REFERENCE 'public final fun foo (): kotlin.Unit declared in <root>.A' type=kotlin.reflect.KFunction1<<root>.A<*>, kotlin.Unit> origin=null reflectionTarget=<same>
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test1> visibility:public modality:FINAL <> () returnType:kotlin.reflect.KFunction1<<root>.A<*>, kotlin.Unit>
FUNCTION_REFERENCE 'public final fun foo (): kotlin.Unit declared in <root>.A' type=kotlin.reflect.KFunction1<<root>.A<kotlin.String>, kotlin.Unit> origin=null reflectionTarget=<same>
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test1> visibility:public modality:FINAL <> () returnType:kotlin.reflect.KFunction1<<root>.A<kotlin.String>, kotlin.Unit>
correspondingProperty: PROPERTY name:test1 visibility:public modality:FINAL [val]
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun <get-test1> (): kotlin.reflect.KFunction1<<root>.A<*>, kotlin.Unit> declared in <root>'
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test1 type:kotlin.reflect.KFunction1<<root>.A<*>, kotlin.Unit> visibility:private [final,static]' type=kotlin.reflect.KFunction1<<root>.A<*>, kotlin.Unit> origin=null
RETURN type=kotlin.Nothing from='public final fun <get-test1> (): kotlin.reflect.KFunction1<<root>.A<kotlin.String>, kotlin.Unit> declared in <root>'
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test1 type:kotlin.reflect.KFunction1<<root>.A<kotlin.String>, kotlin.Unit> visibility:private [final,static]' type=kotlin.reflect.KFunction1<<root>.A<kotlin.String>, kotlin.Unit> origin=null
PROPERTY name:test2 visibility:public modality:FINAL [val]
FIELD PROPERTY_BACKING_FIELD name:test2 type:kotlin.reflect.KProperty1<<root>.A<*>, kotlin.Int> visibility:private [final,static]
FIELD PROPERTY_BACKING_FIELD name:test2 type:kotlin.reflect.KProperty1<<root>.A<kotlin.String>, kotlin.Int> visibility:private [final,static]
EXPRESSION_BODY
PROPERTY_REFERENCE 'public final bar: kotlin.Int [val]' field='FIELD PROPERTY_BACKING_FIELD name:bar type:kotlin.Int visibility:private [final]' getter='public final fun <get-bar> (): kotlin.Int declared in <root>.A' setter=null type=kotlin.reflect.KProperty1<<root>.A<*>, kotlin.Int> origin=null
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test2> visibility:public modality:FINAL <> () returnType:kotlin.reflect.KProperty1<<root>.A<*>, kotlin.Int>
PROPERTY_REFERENCE 'public final bar: kotlin.Int [val]' field='FIELD PROPERTY_BACKING_FIELD name:bar type:kotlin.Int visibility:private [final]' getter='public final fun <get-bar> (): kotlin.Int declared in <root>.A' setter=null type=kotlin.reflect.KProperty1<<root>.A<kotlin.String>, kotlin.Int> origin=null
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test2> visibility:public modality:FINAL <> () returnType:kotlin.reflect.KProperty1<<root>.A<kotlin.String>, kotlin.Int>
correspondingProperty: PROPERTY name:test2 visibility:public modality:FINAL [val]
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun <get-test2> (): kotlin.reflect.KProperty1<<root>.A<*>, kotlin.Int> declared in <root>'
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test2 type:kotlin.reflect.KProperty1<<root>.A<*>, kotlin.Int> visibility:private [final,static]' type=kotlin.reflect.KProperty1<<root>.A<*>, kotlin.Int> origin=null
RETURN type=kotlin.Nothing from='public final fun <get-test2> (): kotlin.reflect.KProperty1<<root>.A<kotlin.String>, kotlin.Int> declared in <root>'
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test2 type:kotlin.reflect.KProperty1<<root>.A<kotlin.String>, kotlin.Int> visibility:private [final,static]' type=kotlin.reflect.KProperty1<<root>.A<kotlin.String>, kotlin.Int> origin=null
@@ -68,7 +68,7 @@ FILE fqName:<root> fileName:/genericPropertyRef.kt
FIELD DELEGATE name:additionalText$delegate type:<root>.DVal visibility:private [final,static]
EXPRESSION_BODY
CONSTRUCTOR_CALL 'public constructor <init> (kmember: kotlin.Any) [primary] declared in <root>.DVal' type=<root>.DVal origin=null
kmember: PROPERTY_REFERENCE 'public final text: kotlin.String? [var]' field='FIELD PROPERTY_BACKING_FIELD name:text type:kotlin.String? visibility:private' getter='public final fun <get-text> (): kotlin.String? declared in <root>.Value' setter='public final fun <set-text> (<set-?>: kotlin.String?): kotlin.Unit declared in <root>.Value' type=kotlin.reflect.KMutableProperty1<<root>.Value<*>, kotlin.String?> origin=null
kmember: PROPERTY_REFERENCE 'public final text: kotlin.String? [var]' field='FIELD PROPERTY_BACKING_FIELD name:text type:kotlin.String? visibility:private' getter='public final fun <get-text> (): kotlin.String? declared in <root>.Value' setter='public final fun <set-text> (<set-?>: kotlin.String?): kotlin.Unit declared in <root>.Value' type=kotlin.reflect.KMutableProperty1<<root>.Value<T of <uninitialized parent>>, kotlin.String?> origin=null
FUN DELEGATED_PROPERTY_ACCESSOR name:<get-additionalText> visibility:public modality:FINAL <> () returnType:kotlin.Int
correspondingProperty: PROPERTY name:additionalText visibility:public modality:FINAL [delegated,val]
BLOCK_BODY
@@ -81,7 +81,7 @@ FILE fqName:<root> fileName:/genericPropertyRef.kt
FIELD DELEGATE name:additionalValue$delegate type:<root>.DVal visibility:private [final,static]
EXPRESSION_BODY
CONSTRUCTOR_CALL 'public constructor <init> (kmember: kotlin.Any) [primary] declared in <root>.DVal' type=<root>.DVal origin=null
kmember: PROPERTY_REFERENCE 'public final value: kotlin.Any? [var]' field=null getter='public final fun <get-value> (): kotlin.Any? declared in <root>.Value' setter='public final fun <set-value> (<set-?>: kotlin.Any?): kotlin.Unit declared in <root>.Value' type=kotlin.reflect.KMutableProperty1<<root>.Value<*>, kotlin.Any?> origin=null
kmember: PROPERTY_REFERENCE 'public final value: T of <uninitialized parent> [var]' field=null getter='public final fun <get-value> (): T of <uninitialized parent> declared in <root>.Value' setter='public final fun <set-value> (<set-?>: T of <uninitialized parent>): kotlin.Unit declared in <root>.Value' type=kotlin.reflect.KMutableProperty1<<root>.Value<T of <uninitialized parent>>, T of <uninitialized parent>> origin=null
FUN DELEGATED_PROPERTY_ACCESSOR name:<get-additionalValue> visibility:public modality:FINAL <> () returnType:kotlin.Int
correspondingProperty: PROPERTY name:additionalValue visibility:public modality:FINAL [delegated,val]
BLOCK_BODY