From 7721eaab2315a4ec39c8b88762d18ae46d80f7b2 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Fri, 24 Jan 2020 10:43:31 +0300 Subject: [PATCH] [FIR] Transform qualified access / callable refs type arguments properly --- .../FirDoubleColonExpressionResolver.kt | 22 +++++++++++++++---- .../FirExpressionsResolveTransformer.kt | 2 ++ .../function/genericClassFromTopLevel.fir.kt | 2 +- .../property/genericClass.fir.kt | 4 ++-- .../inference/regressions/kt32862_both.fir.kt | 2 +- .../callableReferences/genericMember.fir.txt | 20 ++++++++--------- .../expressions/genericPropertyRef.fir.txt | 4 ++-- 7 files changed, 36 insertions(+), 20 deletions(-) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirDoubleColonExpressionResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirDoubleColonExpressionResolver.kt index bad3d2e143a..339e814e708 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirDoubleColonExpressionResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirDoubleColonExpressionResolver.kt @@ -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() + 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 ) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt index c241879eebf..429a0e15205 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt @@ -64,6 +64,8 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) : data: ResolutionMode ): CompositeTransformResult { 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 diff --git a/compiler/testData/diagnostics/tests/callableReference/function/genericClassFromTopLevel.fir.kt b/compiler/testData/diagnostics/tests/callableReference/function/genericClassFromTopLevel.fir.kt index 3ebdabd9df1..4127983d232 100644 --- a/compiler/testData/diagnostics/tests/callableReference/function/genericClassFromTopLevel.fir.kt +++ b/compiler/testData/diagnostics/tests/callableReference/function/genericClassFromTopLevel.fir.kt @@ -9,5 +9,5 @@ class A(val t: T) { fun bar() { val x = A::foo - checkSubtype, String>>(x) + checkSubtype, String>>(x) } diff --git a/compiler/testData/diagnostics/tests/callableReference/property/genericClass.fir.kt b/compiler/testData/diagnostics/tests/callableReference/property/genericClass.fir.kt index 709df31402c..3c1181248c1 100644 --- a/compiler/testData/diagnostics/tests/callableReference/property/genericClass.fir.kt +++ b/compiler/testData/diagnostics/tests/callableReference/property/genericClass.fir.kt @@ -8,8 +8,8 @@ class A(val t: T) { fun bar() { val x = A::foo - checkSubtype, String>>(x) - checkSubtype, Any?>>(x) + checkSubtype, String>>(x) + checkSubtype, Any?>>(x) val y = A<*>::foo checkSubtype, Any?>>(y) diff --git a/compiler/testData/diagnostics/tests/inference/regressions/kt32862_both.fir.kt b/compiler/testData/diagnostics/tests/inference/regressions/kt32862_both.fir.kt index b2a0a2a1c64..5f41403ca68 100644 --- a/compiler/testData/diagnostics/tests/inference/regressions/kt32862_both.fir.kt +++ b/compiler/testData/diagnostics/tests/inference/regressions/kt32862_both.fir.kt @@ -12,5 +12,5 @@ fun G.foo(vararg values: V2) = build() fun forReference(ref: Any?) {} fun test() { - forReference(G::foo) + forReference(G::foo) } diff --git a/compiler/testData/ir/irText/expressions/callableReferences/genericMember.fir.txt b/compiler/testData/ir/irText/expressions/callableReferences/genericMember.fir.txt index cc40327b553..25c560ae4c5 100644 --- a/compiler/testData/ir/irText/expressions/callableReferences/genericMember.fir.txt +++ b/compiler/testData/ir/irText/expressions/callableReferences/genericMember.fir.txt @@ -34,20 +34,20 @@ FILE fqName: fileName:/genericMember.kt public open fun toString (): kotlin.String declared in kotlin.Any $this: VALUE_PARAMETER name: type:kotlin.Any PROPERTY name:test1 visibility:public modality:FINAL [val] - FIELD PROPERTY_BACKING_FIELD name:test1 type:kotlin.reflect.KFunction1<.A<*>, kotlin.Unit> visibility:private [final,static] + FIELD PROPERTY_BACKING_FIELD name:test1 type:kotlin.reflect.KFunction1<.A, kotlin.Unit> visibility:private [final,static] EXPRESSION_BODY - FUNCTION_REFERENCE 'public final fun foo (): kotlin.Unit declared in .A' type=kotlin.reflect.KFunction1<.A<*>, kotlin.Unit> origin=null reflectionTarget= - FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:kotlin.reflect.KFunction1<.A<*>, kotlin.Unit> + FUNCTION_REFERENCE 'public final fun foo (): kotlin.Unit declared in .A' type=kotlin.reflect.KFunction1<.A, kotlin.Unit> origin=null reflectionTarget= + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:kotlin.reflect.KFunction1<.A, kotlin.Unit> correspondingProperty: PROPERTY name:test1 visibility:public modality:FINAL [val] BLOCK_BODY - RETURN type=kotlin.Nothing from='public final fun (): kotlin.reflect.KFunction1<.A<*>, kotlin.Unit> declared in ' - GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test1 type:kotlin.reflect.KFunction1<.A<*>, kotlin.Unit> visibility:private [final,static]' type=kotlin.reflect.KFunction1<.A<*>, kotlin.Unit> origin=null + RETURN type=kotlin.Nothing from='public final fun (): kotlin.reflect.KFunction1<.A, kotlin.Unit> declared in ' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test1 type:kotlin.reflect.KFunction1<.A, kotlin.Unit> visibility:private [final,static]' type=kotlin.reflect.KFunction1<.A, kotlin.Unit> origin=null PROPERTY name:test2 visibility:public modality:FINAL [val] - FIELD PROPERTY_BACKING_FIELD name:test2 type:kotlin.reflect.KProperty1<.A<*>, kotlin.Int> visibility:private [final,static] + FIELD PROPERTY_BACKING_FIELD name:test2 type:kotlin.reflect.KProperty1<.A, 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 (): kotlin.Int declared in .A' setter=null type=kotlin.reflect.KProperty1<.A<*>, kotlin.Int> origin=null - FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:kotlin.reflect.KProperty1<.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 (): kotlin.Int declared in .A' setter=null type=kotlin.reflect.KProperty1<.A, kotlin.Int> origin=null + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:kotlin.reflect.KProperty1<.A, kotlin.Int> correspondingProperty: PROPERTY name:test2 visibility:public modality:FINAL [val] BLOCK_BODY - RETURN type=kotlin.Nothing from='public final fun (): kotlin.reflect.KProperty1<.A<*>, kotlin.Int> declared in ' - GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test2 type:kotlin.reflect.KProperty1<.A<*>, kotlin.Int> visibility:private [final,static]' type=kotlin.reflect.KProperty1<.A<*>, kotlin.Int> origin=null + RETURN type=kotlin.Nothing from='public final fun (): kotlin.reflect.KProperty1<.A, kotlin.Int> declared in ' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test2 type:kotlin.reflect.KProperty1<.A, kotlin.Int> visibility:private [final,static]' type=kotlin.reflect.KProperty1<.A, kotlin.Int> origin=null diff --git a/compiler/testData/ir/irText/expressions/genericPropertyRef.fir.txt b/compiler/testData/ir/irText/expressions/genericPropertyRef.fir.txt index cc2f1b6fcc8..da2d6fe16f0 100644 --- a/compiler/testData/ir/irText/expressions/genericPropertyRef.fir.txt +++ b/compiler/testData/ir/irText/expressions/genericPropertyRef.fir.txt @@ -68,7 +68,7 @@ FILE fqName: fileName:/genericPropertyRef.kt FIELD DELEGATE name:additionalText$delegate type:.DVal visibility:private [final,static] EXPRESSION_BODY CONSTRUCTOR_CALL 'public constructor (kmember: kotlin.Any) [primary] declared in .DVal' type=.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 (): kotlin.String? declared in .Value' setter='public final fun (: kotlin.String?): kotlin.Unit declared in .Value' type=kotlin.reflect.KMutableProperty1<.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 (): kotlin.String? declared in .Value' setter='public final fun (: kotlin.String?): kotlin.Unit declared in .Value' type=kotlin.reflect.KMutableProperty1<.Value>, kotlin.String?> origin=null FUN DELEGATED_PROPERTY_ACCESSOR name: 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: fileName:/genericPropertyRef.kt FIELD DELEGATE name:additionalValue$delegate type:.DVal visibility:private [final,static] EXPRESSION_BODY CONSTRUCTOR_CALL 'public constructor (kmember: kotlin.Any) [primary] declared in .DVal' type=.DVal origin=null - kmember: PROPERTY_REFERENCE 'public final value: kotlin.Any? [var]' field=null getter='public final fun (): kotlin.Any? declared in .Value' setter='public final fun (: kotlin.Any?): kotlin.Unit declared in .Value' type=kotlin.reflect.KMutableProperty1<.Value<*>, kotlin.Any?> origin=null + kmember: PROPERTY_REFERENCE 'public final value: T of [var]' field=null getter='public final fun (): T of declared in .Value' setter='public final fun (: T of ): kotlin.Unit declared in .Value' type=kotlin.reflect.KMutableProperty1<.Value>, T of > origin=null FUN DELEGATED_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:kotlin.Int correspondingProperty: PROPERTY name:additionalValue visibility:public modality:FINAL [delegated,val] BLOCK_BODY