[FIR] Transform qualified access / callable refs type arguments properly
This commit is contained in:
+18
-4
@@ -14,10 +14,9 @@ import org.jetbrains.kotlin.fir.declarations.FirTypeAlias
|
|||||||
import org.jetbrains.kotlin.fir.declarations.expandedConeType
|
import org.jetbrains.kotlin.fir.declarations.expandedConeType
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.types.ConeStarProjection
|
|
||||||
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
|
||||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||||
|
import org.jetbrains.kotlin.types.Variance
|
||||||
|
|
||||||
sealed class DoubleColonLHS(val type: ConeKotlinType) {
|
sealed class DoubleColonLHS(val type: ConeKotlinType) {
|
||||||
/**
|
/**
|
||||||
@@ -153,7 +152,22 @@ class FirDoubleColonExpressionResolver(
|
|||||||
|
|
||||||
val type = ConeClassLikeTypeImpl(
|
val type = ConeClassLikeTypeImpl(
|
||||||
firClass.symbol.toLookupTag(),
|
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
|
isNullable = false // TODO: Use org.jetbrains.kotlin.psi.KtDoubleColonExpression.getHasQuestionMarks
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+2
@@ -64,6 +64,8 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) :
|
|||||||
data: ResolutionMode
|
data: ResolutionMode
|
||||||
): CompositeTransformResult<FirStatement> {
|
): CompositeTransformResult<FirStatement> {
|
||||||
qualifiedAccessExpression.annotations.forEach { it.accept(this, data) }
|
qualifiedAccessExpression.annotations.forEach { it.accept(this, data) }
|
||||||
|
qualifiedAccessExpression.transformTypeArguments(transformer, ResolutionMode.ContextIndependent)
|
||||||
|
|
||||||
var result = when (val callee = qualifiedAccessExpression.calleeReference) {
|
var result = when (val callee = qualifiedAccessExpression.calleeReference) {
|
||||||
is FirExplicitThisReference -> {
|
is FirExplicitThisReference -> {
|
||||||
val labelName = callee.labelName
|
val labelName = callee.labelName
|
||||||
|
|||||||
Vendored
+1
-1
@@ -9,5 +9,5 @@ class A<T>(val t: T) {
|
|||||||
fun bar() {
|
fun bar() {
|
||||||
val x = A<String>::foo
|
val x = A<String>::foo
|
||||||
|
|
||||||
<!INAPPLICABLE_CANDIDATE!>checkSubtype<!><KFunction1<A<String>, String>>(x)
|
checkSubtype<KFunction1<A<String>, String>>(x)
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -8,8 +8,8 @@ class A<T>(val t: T) {
|
|||||||
|
|
||||||
fun bar() {
|
fun bar() {
|
||||||
val x = A<String>::foo
|
val x = A<String>::foo
|
||||||
<!INAPPLICABLE_CANDIDATE!>checkSubtype<!><KProperty1<A<String>, String>>(x)
|
checkSubtype<KProperty1<A<String>, String>>(x)
|
||||||
<!INAPPLICABLE_CANDIDATE!>checkSubtype<!><KProperty1<A<String>, Any?>>(x)
|
checkSubtype<KProperty1<A<String>, Any?>>(x)
|
||||||
|
|
||||||
val y = A<*>::foo
|
val y = A<*>::foo
|
||||||
checkSubtype<KProperty1<A<*>, Any?>>(y)
|
checkSubtype<KProperty1<A<*>, Any?>>(y)
|
||||||
|
|||||||
+1
-1
@@ -12,5 +12,5 @@ fun <V, T : V?> G<T>.foo(vararg values: V2<V?>) = build()
|
|||||||
fun forReference(ref: Any?) {}
|
fun forReference(ref: Any?) {}
|
||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
<!INAPPLICABLE_CANDIDATE!>forReference<!>(<!UNRESOLVED_REFERENCE!>G<Int?>::foo<!>)
|
forReference(<!UNRESOLVED_REFERENCE!>G<Int?>::foo<!>)
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-10
@@ -34,20 +34,20 @@ FILE fqName:<root> fileName:/genericMember.kt
|
|||||||
public open fun toString (): kotlin.String declared in kotlin.Any
|
public open fun toString (): kotlin.String declared in kotlin.Any
|
||||||
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||||
PROPERTY name:test1 visibility:public modality:FINAL [val]
|
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
|
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>
|
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.Unit>
|
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]
|
correspondingProperty: PROPERTY name:test1 visibility:public modality:FINAL [val]
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
RETURN type=kotlin.Nothing from='public final fun <get-test1> (): kotlin.reflect.KFunction1<<root>.A<*>, kotlin.Unit> declared in <root>'
|
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.Unit> visibility:private [final,static]' type=kotlin.reflect.KFunction1<<root>.A<*>, kotlin.Unit> origin=null
|
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]
|
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
|
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
|
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.Int>
|
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]
|
correspondingProperty: PROPERTY name:test2 visibility:public modality:FINAL [val]
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
RETURN type=kotlin.Nothing from='public final fun <get-test2> (): kotlin.reflect.KProperty1<<root>.A<*>, kotlin.Int> declared in <root>'
|
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.Int> visibility:private [final,static]' type=kotlin.reflect.KProperty1<<root>.A<*>, kotlin.Int> origin=null
|
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]
|
FIELD DELEGATE name:additionalText$delegate type:<root>.DVal visibility:private [final,static]
|
||||||
EXPRESSION_BODY
|
EXPRESSION_BODY
|
||||||
CONSTRUCTOR_CALL 'public constructor <init> (kmember: kotlin.Any) [primary] declared in <root>.DVal' type=<root>.DVal origin=null
|
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
|
FUN DELEGATED_PROPERTY_ACCESSOR name:<get-additionalText> visibility:public modality:FINAL <> () returnType:kotlin.Int
|
||||||
correspondingProperty: PROPERTY name:additionalText visibility:public modality:FINAL [delegated,val]
|
correspondingProperty: PROPERTY name:additionalText visibility:public modality:FINAL [delegated,val]
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
@@ -81,7 +81,7 @@ FILE fqName:<root> fileName:/genericPropertyRef.kt
|
|||||||
FIELD DELEGATE name:additionalValue$delegate type:<root>.DVal visibility:private [final,static]
|
FIELD DELEGATE name:additionalValue$delegate type:<root>.DVal visibility:private [final,static]
|
||||||
EXPRESSION_BODY
|
EXPRESSION_BODY
|
||||||
CONSTRUCTOR_CALL 'public constructor <init> (kmember: kotlin.Any) [primary] declared in <root>.DVal' type=<root>.DVal origin=null
|
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
|
FUN DELEGATED_PROPERTY_ACCESSOR name:<get-additionalValue> visibility:public modality:FINAL <> () returnType:kotlin.Int
|
||||||
correspondingProperty: PROPERTY name:additionalValue visibility:public modality:FINAL [delegated,val]
|
correspondingProperty: PROPERTY name:additionalValue visibility:public modality:FINAL [delegated,val]
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
|
|||||||
Reference in New Issue
Block a user