diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/DoubleColonExpressionResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/DoubleColonExpressionResolver.kt index bd6d3380f66..c1aabaa3432 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/DoubleColonExpressionResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/DoubleColonExpressionResolver.kt @@ -92,7 +92,8 @@ class DoubleColonExpressionResolver( val type = result?.type if (type != null && !type.isError) { checkClassLiteral(c, expression, result) - val kClassType = reflectionTypes.getKClassType(Annotations.EMPTY, type) + val variance = if (result is DoubleColonLHS.Expression && !result.isObject) Variance.OUT_VARIANCE else Variance.INVARIANT + val kClassType = reflectionTypes.getKClassType(Annotations.EMPTY, type, variance) val dataFlowInfo = (result as? DoubleColonLHS.Expression)?.dataFlowInfo ?: c.dataFlowInfo return dataFlowAnalyzer.checkType(createTypeInfo(kClassType, dataFlowInfo), expression, c) } diff --git a/compiler/testData/diagnostics/tests/callableReference/bound/expectedType.kt b/compiler/testData/diagnostics/tests/callableReference/bound/expectedType.kt index 689c3b8c4c0..2babceacb13 100644 --- a/compiler/testData/diagnostics/tests/callableReference/bound/expectedType.kt +++ b/compiler/testData/diagnostics/tests/callableReference/bound/expectedType.kt @@ -7,6 +7,8 @@ fun test(s: String) { val g: () -> String = s::toString val h: (Any?) -> Boolean = s::equals - val k: KClass = s::class + val k: KClass = s::class val l: KClass<*> = s::class + val m: KClass = String::class + val n: KClass = Unit::class } diff --git a/compiler/testData/diagnostics/tests/callableReference/bound/reservedExpressionSyntax.txt b/compiler/testData/diagnostics/tests/callableReference/bound/reservedExpressionSyntax.txt index e6fa2b8eb6f..697eea68622 100644 --- a/compiler/testData/diagnostics/tests/callableReference/bound/reservedExpressionSyntax.txt +++ b/compiler/testData/diagnostics/tests/callableReference/bound/reservedExpressionSyntax.txt @@ -21,9 +21,9 @@ package test { public final fun kotlin.collections.List.testCallable2(): () -> kotlin.Unit public final fun kotlin.collections.List.testCallable3(): () -> kotlin.Unit public final fun kotlin.collections.List.testCallable4(): () -> kotlin.Unit - public final fun kotlin.collections.List.testClassLiteral1(): kotlin.reflect.KClass - public final fun kotlin.collections.List.testClassLiteral2(): kotlin.reflect.KClass - public final fun kotlin.collections.List.testClassLiteral3(): kotlin.reflect.KClass + public final fun kotlin.collections.List.testClassLiteral1(): kotlin.reflect.KClass + public final fun kotlin.collections.List.testClassLiteral2(): kotlin.reflect.KClass + public final fun kotlin.collections.List.testClassLiteral3(): kotlin.reflect.KClass public final fun kotlin.collections.List.testUnresolved1(): [ERROR : Error function type] public final fun kotlin.collections.List.testUnresolved2(): kotlin.reflect.KFunction0 public final fun kotlin.collections.List.testUnresolved3(): kotlin.reflect.KFunction0 diff --git a/compiler/testData/diagnostics/tests/callableReference/sam.txt b/compiler/testData/diagnostics/tests/callableReference/sam.txt index cc45939c336..893d509e159 100644 --- a/compiler/testData/diagnostics/tests/callableReference/sam.txt +++ b/compiler/testData/diagnostics/tests/callableReference/sam.txt @@ -8,11 +8,11 @@ public fun f5(): kotlin.reflect.KClass> public fun f6(): kotlin.reflect.KFunction2, @kotlin.ParameterName(name = "t") kotlin.Nothing!, kotlin.Unit> public fun f7(): kotlin.reflect.KClass> public fun f8(): kotlin.reflect.KFunction2, @kotlin.ParameterName(name = "t") kotlin.String!, kotlin.Unit> -public fun g1(): kotlin.reflect.KClass +public fun g1(): kotlin.reflect.KClass public fun g2(): kotlin.reflect.KFunction0 -public fun g3(): kotlin.reflect.KClass +public fun g3(): kotlin.reflect.KClass public fun g4(): kotlin.reflect.KFunction0 -public fun g5(): kotlin.reflect.KClass> +public fun g5(): kotlin.reflect.KClass> public fun g6(): kotlin.reflect.KFunction1<@kotlin.ParameterName(name = "t") kotlin.String!, kotlin.Unit> -public fun g7(): kotlin.reflect.KClass> +public fun g7(): kotlin.reflect.KClass> public fun g8(): kotlin.reflect.KFunction1<@kotlin.ParameterName(name = "t") kotlin.String!, kotlin.Unit> diff --git a/compiler/testData/diagnostics/tests/classLiteral/classAndObjectLiteralType.kt b/compiler/testData/diagnostics/tests/classLiteral/classAndObjectLiteralType.kt new file mode 100644 index 00000000000..5b84d1aa74f --- /dev/null +++ b/compiler/testData/diagnostics/tests/classLiteral/classAndObjectLiteralType.kt @@ -0,0 +1,16 @@ +import kotlin.reflect.KClass + +abstract class Base(val klass: KClass) + +class DerivedClass : Base(DerivedClass::class) + +object DerivedObject : Base(DerivedObject::class) + +enum class TestEnum { + TEST_ENTRY +} + +val test1: KClass = DerivedClass::class +val test2: KClass = DerivedObject::class +val test3: KClass = TestEnum::class +val test4: KClass = TestEnum.TEST_ENTRY::class \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/classLiteral/classAndObjectLiteralType.txt b/compiler/testData/diagnostics/tests/classLiteral/classAndObjectLiteralType.txt new file mode 100644 index 00000000000..c9a69adfa8e --- /dev/null +++ b/compiler/testData/diagnostics/tests/classLiteral/classAndObjectLiteralType.txt @@ -0,0 +1,49 @@ +package + +public val test1: kotlin.reflect.KClass +public val test2: kotlin.reflect.KClass +public val test3: kotlin.reflect.KClass +public val test4: kotlin.reflect.KClass + +public abstract class Base { + public constructor Base(/*0*/ klass: kotlin.reflect.KClass) + public final val klass: kotlin.reflect.KClass + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class DerivedClass : Base { + public constructor DerivedClass() + public final override /*1*/ /*fake_override*/ val klass: kotlin.reflect.KClass + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public object DerivedObject : Base { + private constructor DerivedObject() + public final override /*1*/ /*fake_override*/ val klass: kotlin.reflect.KClass + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final enum class TestEnum : kotlin.Enum { + enum entry TEST_ENTRY + + private constructor TestEnum() + public final override /*1*/ /*fake_override*/ val name: kotlin.String + public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int + protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any + public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: TestEnum): kotlin.Int + public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit + public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class! + public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + // Static members + public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): TestEnum + public final /*synthesized*/ fun values(): kotlin.Array +} diff --git a/compiler/testData/diagnostics/tests/classLiteral/classLiteralType.kt b/compiler/testData/diagnostics/tests/classLiteral/classLiteralType.kt index 1ca87eac20c..72f02445a6c 100644 --- a/compiler/testData/diagnostics/tests/classLiteral/classLiteralType.kt +++ b/compiler/testData/diagnostics/tests/classLiteral/classLiteralType.kt @@ -3,7 +3,13 @@ import kotlin.reflect.KClass class A class B +val listOfString: List = null!! +val arrayOfString: Array = null!! + val a1 : KClass<*> = A::class val a2 : KClass = A::class val a3 : KClass = A::class val a4 : B = A::class + +val a5 : KClass> = listOfString::class +val a6 : KClass> = arrayOfString::class diff --git a/compiler/testData/diagnostics/tests/classLiteral/classLiteralType.txt b/compiler/testData/diagnostics/tests/classLiteral/classLiteralType.txt index 284c04bd17b..8547f6bfea0 100644 --- a/compiler/testData/diagnostics/tests/classLiteral/classLiteralType.txt +++ b/compiler/testData/diagnostics/tests/classLiteral/classLiteralType.txt @@ -4,6 +4,10 @@ public val a1: kotlin.reflect.KClass<*> public val a2: kotlin.reflect.KClass public val a3: kotlin.reflect.KClass public val a4: B +public val a5: kotlin.reflect.KClass> +public val a6: kotlin.reflect.KClass> +public val arrayOfString: kotlin.Array +public val listOfString: kotlin.collections.List public final class A { public constructor A() diff --git a/compiler/testData/diagnostics/tests/classLiteral/integerValueType.kt b/compiler/testData/diagnostics/tests/classLiteral/integerValueType.kt index 22c4e201359..056cd23e846 100644 --- a/compiler/testData/diagnostics/tests/classLiteral/integerValueType.kt +++ b/compiler/testData/diagnostics/tests/classLiteral/integerValueType.kt @@ -2,7 +2,7 @@ import kotlin.reflect.KClass -fun f(x: KClass) {} +fun f(x: KClass) {} fun test() { f(42::class) diff --git a/compiler/testData/diagnostics/tests/classLiteral/integerValueType.txt b/compiler/testData/diagnostics/tests/classLiteral/integerValueType.txt index a9be99b1874..3d80e4c2567 100644 --- a/compiler/testData/diagnostics/tests/classLiteral/integerValueType.txt +++ b/compiler/testData/diagnostics/tests/classLiteral/integerValueType.txt @@ -1,4 +1,4 @@ package -public fun f(/*0*/ x: kotlin.reflect.KClass): kotlin.Unit +public fun f(/*0*/ x: kotlin.reflect.KClass): kotlin.Unit public fun test(): kotlin.Unit diff --git a/compiler/testData/diagnostics/tests/sourceCompatibility/noBoundCallableReferences/boundClassLiteral.txt b/compiler/testData/diagnostics/tests/sourceCompatibility/noBoundCallableReferences/boundClassLiteral.txt index 46b7daf7888..79ecd843f9f 100644 --- a/compiler/testData/diagnostics/tests/sourceCompatibility/noBoundCallableReferences/boundClassLiteral.txt +++ b/compiler/testData/diagnostics/tests/sourceCompatibility/noBoundCallableReferences/boundClassLiteral.txt @@ -1,9 +1,9 @@ package -public val fail1: kotlin.reflect.KClass +public val fail1: kotlin.reflect.KClass public val fail2: kotlin.reflect.KClass -public val fail3: kotlin.reflect.KClass -public val fail4: kotlin.reflect.KClass +public val fail3: kotlin.reflect.KClass +public val fail4: kotlin.reflect.KClass public val ok1: kotlin.reflect.KClass public val ok2: kotlin.reflect.KClass public val ok3: kotlin.reflect.KClass diff --git a/compiler/testData/ir/irText/expressions/classReference.txt b/compiler/testData/ir/irText/expressions/classReference.txt index de35b64ab18..93f03f21cc0 100644 --- a/compiler/testData/ir/irText/expressions/classReference.txt +++ b/compiler/testData/ir/irText/expressions/classReference.txt @@ -9,12 +9,12 @@ FILE /classReference.kt TYPE_OP origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit CLASS_REFERENCE 'A' type=kotlin.reflect.KClass TYPE_OP origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit - GET_CLASS type=kotlin.reflect.KClass + GET_CLASS type=kotlin.reflect.KClass CALL 'constructor A()' type=A origin=null TYPE_OP origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit CALL '() on KClass: Class' type=java.lang.Class origin=GET_PROPERTY $receiver: CLASS_REFERENCE 'A' type=kotlin.reflect.KClass TYPE_OP origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit - CALL '() on KClass: Class' type=java.lang.Class origin=GET_PROPERTY - $receiver: GET_CLASS type=kotlin.reflect.KClass + CALL '() on KClass: Class' type=java.lang.Class origin=GET_PROPERTY + $receiver: GET_CLASS type=kotlin.reflect.KClass CALL 'constructor A()' type=A origin=null diff --git a/compiler/testData/ir/irText/expressions/reflectionLiterals.txt b/compiler/testData/ir/irText/expressions/reflectionLiterals.txt index 3a11a605245..12543c2d4be 100644 --- a/compiler/testData/ir/irText/expressions/reflectionLiterals.txt +++ b/compiler/testData/ir/irText/expressions/reflectionLiterals.txt @@ -24,15 +24,15 @@ FILE /reflectionLiterals.kt BLOCK_BODY RETURN type=kotlin.Nothing from='(): KClass' GET_FIELD 'test1: KClass' type=kotlin.reflect.KClass origin=null - PROPERTY public val test2: kotlin.reflect.KClass - FIELD PROPERTY_BACKING_FIELD public val test2: kotlin.reflect.KClass + PROPERTY public val test2: kotlin.reflect.KClass + FIELD PROPERTY_BACKING_FIELD public val test2: kotlin.reflect.KClass EXPRESSION_BODY - GET_CLASS type=kotlin.reflect.KClass + GET_CLASS type=kotlin.reflect.KClass CALL '(): Int' type=kotlin.Int origin=GET_PROPERTY - FUN DEFAULT_PROPERTY_ACCESSOR public fun (): kotlin.reflect.KClass + FUN DEFAULT_PROPERTY_ACCESSOR public fun (): kotlin.reflect.KClass BLOCK_BODY - RETURN type=kotlin.Nothing from='(): KClass' - GET_FIELD 'test2: KClass' type=kotlin.reflect.KClass origin=null + RETURN type=kotlin.Nothing from='(): KClass' + GET_FIELD 'test2: KClass' type=kotlin.reflect.KClass origin=null PROPERTY public val test3: kotlin.reflect.KFunction1 FIELD PROPERTY_BACKING_FIELD public val test3: kotlin.reflect.KFunction1 EXPRESSION_BODY diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index 465761667b6..7641a76c775 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -2998,6 +2998,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("classAndObjectLiteralType.kt") + public void testClassAndObjectLiteralType() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/classLiteral/classAndObjectLiteralType.kt"); + doTest(fileName); + } + @TestMetadata("classLiteralType.kt") public void testClassLiteralType() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/classLiteral/classLiteralType.kt"); diff --git a/core/descriptors/src/org/jetbrains/kotlin/builtins/ReflectionTypes.kt b/core/descriptors/src/org/jetbrains/kotlin/builtins/ReflectionTypes.kt index 7a67a9d9b0c..302fe997d4e 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/builtins/ReflectionTypes.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/builtins/ReflectionTypes.kt @@ -59,13 +59,13 @@ class ReflectionTypes(module: ModuleDescriptor) { val kMutableProperty0: ClassDescriptor by ClassLookup val kMutableProperty1: ClassDescriptor by ClassLookup - fun getKClassType(annotations: Annotations, type: KotlinType): KotlinType { + fun getKClassType(annotations: Annotations, type: KotlinType, variance: Variance): KotlinType { val descriptor = kClass if (ErrorUtils.isError(descriptor)) { return descriptor.defaultType } - val arguments = listOf(TypeProjectionImpl(Variance.INVARIANT, type)) + val arguments = listOf(TypeProjectionImpl(variance, type)) return KotlinTypeFactory.simpleNotNullType(annotations, descriptor, arguments) } diff --git a/js/js.translator/testData/box/reflection/kClassIsInstance.kt b/js/js.translator/testData/box/reflection/kClassIsInstance.kt index a6be9ac4445..41d0a709ea3 100644 --- a/js/js.translator/testData/box/reflection/kClassIsInstance.kt +++ b/js/js.translator/testData/box/reflection/kClassIsInstance.kt @@ -2,7 +2,7 @@ package foo import kotlin.reflect.KClass -fun check(k: KClass, instance: B, nonInstance: Any) { +fun check(k: KClass<*>, instance: Any, nonInstance: Any) { assertTrue(k.isInstance(instance)) assertFalse(k.isInstance(nonInstance)) assertFalse(k.isInstance(null))