diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/AnnotationCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/AnnotationCodegen.java index 4aae15f4c66..a1ce2f7b177 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/AnnotationCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/AnnotationCodegen.java @@ -284,7 +284,16 @@ public abstract class AnnotationCodegen { @Override public Void visitJavaClassValue(JavaClassValue value, Void data) { - annotationVisitor.visit(name, typeMapper.mapType(value.getValue())); + return visitClassOfType(value.getValue()); + } + + @Override + public Void visitKClassValue(KClassValue value, Void data) { + return visitClassOfType(value.getValue()); + } + + private Void visitClassOfType(@NotNull JetType type) { + annotationVisitor.visit(name, typeMapper.mapType(type)); return null; } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompileTimeConstantUtils.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompileTimeConstantUtils.java index a54e2fe0204..2187d6d074b 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompileTimeConstantUtils.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompileTimeConstantUtils.java @@ -79,6 +79,7 @@ public class CompileTimeConstantUtils { if (isEnumClass(typeDescriptor) || isAnnotationClass(typeDescriptor) || isJavaLangClass(typeDescriptor) || + KotlinBuiltIns.isKClass(typeDescriptor) || KotlinBuiltIns.isPrimitiveArray(parameterType) || KotlinBuiltIns.isPrimitiveType(parameterType) || builtIns.getStringType().equals(parameterType)) { @@ -97,6 +98,7 @@ public class CompileTimeConstantUtils { return isEnumClass(arrayTypeDescriptor) || isAnnotationClass(arrayTypeDescriptor) || isJavaLangClass(arrayTypeDescriptor) || + KotlinBuiltIns.isKClass(arrayTypeDescriptor) || builtIns.getStringType().equals(arrayType); } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/constants/evaluate/ConstantExpressionEvaluator.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/constants/evaluate/ConstantExpressionEvaluator.kt index d24904e5755..2c1294b86cb 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/constants/evaluate/ConstantExpressionEvaluator.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/constants/evaluate/ConstantExpressionEvaluator.kt @@ -395,6 +395,12 @@ public class ConstantExpressionEvaluator private (val trace: BindingTrace) : Jet return null } + override fun visitClassLiteralExpression(expression: JetClassLiteralExpression, expectedType: JetType?): CompileTimeConstant<*>? { + val jetType = trace.get(BindingContext.EXPRESSION_TYPE, expression) + if (jetType.isError()) return null + return KClassValue(jetType) + } + private fun resolveArguments(valueArguments: List, expectedType: JetType): List> { val constants = arrayListOf>() for (argument in valueArguments) { diff --git a/compiler/serialization/src/org/jetbrains/kotlin/serialization/AnnotationSerializer.kt b/compiler/serialization/src/org/jetbrains/kotlin/serialization/AnnotationSerializer.kt index c20a83242e6..348add51bcb 100644 --- a/compiler/serialization/src/org/jetbrains/kotlin/serialization/AnnotationSerializer.kt +++ b/compiler/serialization/src/org/jetbrains/kotlin/serialization/AnnotationSerializer.kt @@ -104,6 +104,11 @@ public object AnnotationSerializer { throw UnsupportedOperationException("Class literal annotation arguments are not yet supported: $value") } + override fun visitKClassValue(value: KClassValue?, data: Unit?) { + // TODO: support class literals + throw UnsupportedOperationException("Class literal annotation arguments are not yet supported: $value") + } + override fun visitLongValue(value: LongValue, data: Unit) { setType(Type.LONG) setIntValue(value.getValue()) diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassArrayInAnnotationsInVariance.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassArrayInAnnotationsInVariance.kt new file mode 100644 index 00000000000..fe6eb6cf697 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassArrayInAnnotationsInVariance.kt @@ -0,0 +1,27 @@ +import kotlin.reflect.KClass + +open class A +class B1 : A() +class B2 : A() + +annotation class Ann1(val arg: Array>) + +Ann1(array(A::class)) +class MyClass1 + +Ann1(array(Any::class)) +class MyClass1a + +Ann1(array(B1::class)) +class MyClass2 + +annotation class Ann2(val arg: Array>) + +Ann2(array(A::class)) +class MyClass3 + +Ann2(array(B1::class)) +class MyClass4 + +Ann2(array(B2::class)) +class MyClass5 diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassArrayInAnnotationsInVariance.txt b/compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassArrayInAnnotationsInVariance.txt new file mode 100644 index 00000000000..fcef8bc12f3 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassArrayInAnnotationsInVariance.txt @@ -0,0 +1,80 @@ +package + +internal open class A { + public constructor A() + 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 +} + +internal final annotation class Ann1 : kotlin.Annotation { + public constructor Ann1(/*0*/ arg: kotlin.Array>) + internal final val arg: kotlin.Array> + 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 +} + +internal final annotation class Ann2 : kotlin.Annotation { + public constructor Ann2(/*0*/ arg: kotlin.Array>) + internal final val arg: kotlin.Array> + 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 +} + +internal final class B1 : A { + public constructor B1() + 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 +} + +internal final class B2 : A { + public constructor B2() + 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 +} + +Ann1(arg = {A::class}: kotlin.Array>) internal final class MyClass1 { + public constructor MyClass1() + 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 +} + +Ann1(arg = {kotlin.Any::class}: kotlin.Array>) internal final class MyClass1a { + public constructor MyClass1a() + 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 +} + +Ann1(arg = {B1::class}: kotlin.Array) internal final class MyClass2 { + public constructor MyClass2() + 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 +} + +Ann2(arg = {A::class}: kotlin.Array>) internal final class MyClass3 { + public constructor MyClass3() + 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 +} + +Ann2(arg = {B1::class}: kotlin.Array>) internal final class MyClass4 { + public constructor MyClass4() + 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 +} + +Ann2(arg = {B2::class}: kotlin.Array) internal final class MyClass5 { + public constructor MyClass5() + 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 +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassArrayInAnnotationsOutVariance.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassArrayInAnnotationsOutVariance.kt new file mode 100644 index 00000000000..69443c27db0 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassArrayInAnnotationsOutVariance.kt @@ -0,0 +1,27 @@ +import kotlin.reflect.KClass + +open class A +class B1 : A() +class B2 : A() + +annotation class Ann1(val arg: Array>) + +Ann1(array(A::class)) +class MyClass1 + +Ann1(array(Any::class)) +class MyClass1a + +Ann1(array(B1::class)) +class MyClass2 + +annotation class Ann2(val arg: Array>) + +Ann2(array(A::class)) +class MyClass3 + +Ann2(array(B1::class)) +class MyClass4 + +Ann2(array(B2::class)) +class MyClass5 diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassArrayInAnnotationsOutVariance.txt b/compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassArrayInAnnotationsOutVariance.txt new file mode 100644 index 00000000000..fa9773731bb --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassArrayInAnnotationsOutVariance.txt @@ -0,0 +1,80 @@ +package + +internal open class A { + public constructor A() + 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 +} + +internal final annotation class Ann1 : kotlin.Annotation { + public constructor Ann1(/*0*/ arg: kotlin.Array>) + internal final val arg: kotlin.Array> + 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 +} + +internal final annotation class Ann2 : kotlin.Annotation { + public constructor Ann2(/*0*/ arg: kotlin.Array>) + internal final val arg: kotlin.Array> + 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 +} + +internal final class B1 : A { + public constructor B1() + 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 +} + +internal final class B2 : A { + public constructor B2() + 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 +} + +Ann1(arg = {A::class}: kotlin.Array>) internal final class MyClass1 { + public constructor MyClass1() + 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 +} + +Ann1(arg = {kotlin.Any::class}: kotlin.Array) internal final class MyClass1a { + public constructor MyClass1a() + 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 +} + +Ann1(arg = {B1::class}: kotlin.Array>) internal final class MyClass2 { + public constructor MyClass2() + 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 +} + +Ann2(arg = {A::class}: kotlin.Array) internal final class MyClass3 { + public constructor MyClass3() + 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 +} + +Ann2(arg = {B1::class}: kotlin.Array>) internal final class MyClass4 { + public constructor MyClass4() + 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 +} + +Ann2(arg = {B2::class}: kotlin.Array) internal final class MyClass5 { + public constructor MyClass5() + 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 +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassInAnnotation.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassInAnnotation.kt new file mode 100644 index 00000000000..9b33739135b --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassInAnnotation.kt @@ -0,0 +1,20 @@ +import kotlin.reflect.KClass + +annotation class Ann1(val arg: KClass<*>) +annotation class Ann2(vararg val arg: KClass<*>) +annotation class Ann3(val arg: Array>) + +class A1 +class A2 + +Ann1(A1::class) +Ann2(A1::class, A2::class) +Ann3(array(A1::class, A2::class)) +class MyClass1 + +Ann1(A3::class) +class MyClass2 + +val x = A1::class +Ann1(x) +class MyClass3 diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassInAnnotation.txt b/compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassInAnnotation.txt new file mode 100644 index 00000000000..f7444a13c9f --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassInAnnotation.txt @@ -0,0 +1,62 @@ +package + +internal val x: kotlin.reflect.KClass + +internal final class A1 { + public constructor A1() + 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 +} + +internal final class A2 { + public constructor A2() + 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 +} + +internal final annotation class Ann1 : kotlin.Annotation { + public constructor Ann1(/*0*/ arg: kotlin.reflect.KClass<*>) + internal final val arg: 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 +} + +internal final annotation class Ann2 : kotlin.Annotation { + public constructor Ann2(/*0*/ vararg arg: kotlin.reflect.KClass<*> /*kotlin.Array>*/) + internal final val arg: kotlin.Array> + 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 +} + +internal final annotation class Ann3 : kotlin.Annotation { + public constructor Ann3(/*0*/ arg: kotlin.Array>) + internal final val arg: kotlin.Array> + 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 +} + +Ann1(arg = A1::class: kotlin.reflect.KClass) Ann2(arg = {A1::class, A2::class}: kotlin.Array>) Ann3(arg = {A1::class, A2::class}: kotlin.Array>) internal final class MyClass1 { + public constructor MyClass1() + 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 +} + +Ann1() internal final class MyClass2 { + public constructor MyClass2() + 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 +} + +Ann1() internal final class MyClass3 { + public constructor MyClass3() + 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 +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassInAnnotationsInVariance.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassInAnnotationsInVariance.kt new file mode 100644 index 00000000000..72bd2f0bb99 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassInAnnotationsInVariance.kt @@ -0,0 +1,27 @@ +import kotlin.reflect.KClass + +open class A +class B1 : A() +class B2 : A() + +annotation class Ann1(val arg: KClass) + +Ann1(A::class) +class MyClass1 + +Ann1(Any::class) +class MyClass1a + +Ann1(B1::class) +class MyClass2 + +annotation class Ann2(val arg: KClass) + +Ann2(A::class) +class MyClass3 + +Ann2(B1::class) +class MyClass4 + +Ann2(B2::class) +class MyClass5 diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassInAnnotationsInVariance.txt b/compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassInAnnotationsInVariance.txt new file mode 100644 index 00000000000..cab51658641 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassInAnnotationsInVariance.txt @@ -0,0 +1,80 @@ +package + +internal open class A { + public constructor A() + 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 +} + +internal final annotation class Ann1 : kotlin.Annotation { + public constructor Ann1(/*0*/ arg: kotlin.reflect.KClass) + internal final val arg: 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 +} + +internal final annotation class Ann2 : kotlin.Annotation { + public constructor Ann2(/*0*/ arg: kotlin.reflect.KClass) + internal final val arg: 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 +} + +internal final class B1 : A { + public constructor B1() + 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 +} + +internal final class B2 : A { + public constructor B2() + 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 +} + +Ann1(arg = A::class: kotlin.reflect.KClass) internal final class MyClass1 { + public constructor MyClass1() + 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 +} + +Ann1(arg = kotlin.Any::class: kotlin.reflect.KClass) internal final class MyClass1a { + public constructor MyClass1a() + 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 +} + +Ann1(arg = B1::class: kotlin.reflect.KClass) internal final class MyClass2 { + public constructor MyClass2() + 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 +} + +Ann2(arg = A::class: kotlin.reflect.KClass) internal final class MyClass3 { + public constructor MyClass3() + 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 +} + +Ann2(arg = B1::class: kotlin.reflect.KClass) internal final class MyClass4 { + public constructor MyClass4() + 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 +} + +Ann2(arg = B2::class: kotlin.reflect.KClass) internal final class MyClass5 { + public constructor MyClass5() + 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 +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassInAnnotationsOutVariance.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassInAnnotationsOutVariance.kt new file mode 100644 index 00000000000..717c67ca2aa --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassInAnnotationsOutVariance.kt @@ -0,0 +1,27 @@ +import kotlin.reflect.KClass + +open class A +class B1 : A() +class B2 : A() + +annotation class Ann1(val arg: KClass) + +Ann1(A::class) +class MyClass1 + +Ann1(Any::class) +class MyClass1a + +Ann1(B1::class) +class MyClass2 + +annotation class Ann2(val arg: KClass) + +Ann2(A::class) +class MyClass3 + +Ann2(B1::class) +class MyClass4 + +Ann2(B2::class) +class MyClass5 diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassInAnnotationsOutVariance.txt b/compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassInAnnotationsOutVariance.txt new file mode 100644 index 00000000000..a147794db52 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassInAnnotationsOutVariance.txt @@ -0,0 +1,80 @@ +package + +internal open class A { + public constructor A() + 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 +} + +internal final annotation class Ann1 : kotlin.Annotation { + public constructor Ann1(/*0*/ arg: kotlin.reflect.KClass) + internal final val arg: 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 +} + +internal final annotation class Ann2 : kotlin.Annotation { + public constructor Ann2(/*0*/ arg: kotlin.reflect.KClass) + internal final val arg: 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 +} + +internal final class B1 : A { + public constructor B1() + 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 +} + +internal final class B2 : A { + public constructor B2() + 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 +} + +Ann1(arg = A::class: kotlin.reflect.KClass) internal final class MyClass1 { + public constructor MyClass1() + 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 +} + +Ann1(arg = kotlin.Any::class: kotlin.reflect.KClass) internal final class MyClass1a { + public constructor MyClass1a() + 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 +} + +Ann1(arg = B1::class: kotlin.reflect.KClass) internal final class MyClass2 { + public constructor MyClass2() + 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 +} + +Ann2(arg = A::class: kotlin.reflect.KClass) internal final class MyClass3 { + public constructor MyClass3() + 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 +} + +Ann2(arg = B1::class: kotlin.reflect.KClass) internal final class MyClass4 { + public constructor MyClass4() + 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 +} + +Ann2(arg = B2::class: kotlin.reflect.KClass) internal final class MyClass5 { + public constructor MyClass5() + 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 +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassInvariantTP.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassInvariantTP.kt new file mode 100644 index 00000000000..6aa0b87f366 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassInvariantTP.kt @@ -0,0 +1,23 @@ +import kotlin.reflect.KClass + +open class A +class B : A() + +annotation class Ann1(val arg: KClass) + +Ann1(A::class) +class MyClass1 + +Ann1(Any::class) +class MyClass1a + +Ann1(B::class) +class MyClass2 + +annotation class Ann2(val arg: KClass) + +Ann2(A::class) +class MyClass3 + +Ann2(B::class) +class MyClass4 diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassInvariantTP.txt b/compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassInvariantTP.txt new file mode 100644 index 00000000000..2901b0c2941 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassInvariantTP.txt @@ -0,0 +1,66 @@ +package + +internal open class A { + public constructor A() + 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 +} + +internal final annotation class Ann1 : kotlin.Annotation { + public constructor Ann1(/*0*/ arg: kotlin.reflect.KClass) + internal final val arg: 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 +} + +internal final annotation class Ann2 : kotlin.Annotation { + public constructor Ann2(/*0*/ arg: kotlin.reflect.KClass) + internal final val arg: 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 +} + +internal final class B : A { + public constructor B() + 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 +} + +Ann1(arg = A::class: kotlin.reflect.KClass) internal final class MyClass1 { + public constructor MyClass1() + 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 +} + +Ann1(arg = kotlin.Any::class: kotlin.reflect.KClass) internal final class MyClass1a { + public constructor MyClass1a() + 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 +} + +Ann1(arg = B::class: kotlin.reflect.KClass) internal final class MyClass2 { + public constructor MyClass2() + 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 +} + +Ann2(arg = A::class: kotlin.reflect.KClass) internal final class MyClass3 { + public constructor MyClass3() + 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 +} + +Ann2(arg = B::class: kotlin.reflect.KClass) internal final class MyClass4 { + public constructor MyClass4() + 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 +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassOutArrayInAnnotationsOutVariance.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassOutArrayInAnnotationsOutVariance.kt new file mode 100644 index 00000000000..948fc6161b0 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassOutArrayInAnnotationsOutVariance.kt @@ -0,0 +1,7 @@ +import kotlin.reflect.KClass + +open class A +class B1 : A() +class B2 : A() + +annotation class Ann1(val arg: Array>) diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassOutArrayInAnnotationsOutVariance.txt b/compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassOutArrayInAnnotationsOutVariance.txt new file mode 100644 index 00000000000..57bb6dcede5 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassOutArrayInAnnotationsOutVariance.txt @@ -0,0 +1,30 @@ +package + +internal open class A { + public constructor A() + 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 +} + +internal final annotation class Ann1 : kotlin.Annotation { + public constructor Ann1(/*0*/ arg: kotlin.Array>) + internal final val arg: kotlin.Array> + 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 +} + +internal final class B1 : A { + public constructor B1() + 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 +} + +internal final class B2 : A { + public constructor B2() + 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 +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestWithStdLibGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestWithStdLibGenerated.java index 9fb36669d9b..17a84bbb46d 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestWithStdLibGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestWithStdLibGenerated.java @@ -202,6 +202,57 @@ public class JetDiagnosticsTestWithStdLibGenerated extends AbstractJetDiagnostic } } + @TestMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/kClass") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class KClass extends AbstractJetDiagnosticsTestWithStdLib { + public void testAllFilesPresentInKClass() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/annotations/kClass"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("kClassArrayInAnnotationsInVariance.kt") + public void testKClassArrayInAnnotationsInVariance() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassArrayInAnnotationsInVariance.kt"); + doTest(fileName); + } + + @TestMetadata("kClassArrayInAnnotationsOutVariance.kt") + public void testKClassArrayInAnnotationsOutVariance() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassArrayInAnnotationsOutVariance.kt"); + doTest(fileName); + } + + @TestMetadata("kClassInAnnotation.kt") + public void testKClassInAnnotation() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassInAnnotation.kt"); + doTest(fileName); + } + + @TestMetadata("kClassInAnnotationsInVariance.kt") + public void testKClassInAnnotationsInVariance() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassInAnnotationsInVariance.kt"); + doTest(fileName); + } + + @TestMetadata("kClassInAnnotationsOutVariance.kt") + public void testKClassInAnnotationsOutVariance() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassInAnnotationsOutVariance.kt"); + doTest(fileName); + } + + @TestMetadata("kClassInvariantTP.kt") + public void testKClassInvariantTP() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassInvariantTP.kt"); + doTest(fileName); + } + + @TestMetadata("kClassOutArrayInAnnotationsOutVariance.kt") + public void testKClassOutArrayInAnnotationsOutVariance() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/kClass/kClassOutArrayInAnnotationsOutVariance.kt"); + doTest(fileName); + } + } + @TestMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/platformStatic") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java b/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java index d79279617c0..f7ad0e1d3d3 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java +++ b/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java @@ -161,6 +161,8 @@ public class KotlinBuiltIns { public final FqName tailRecursive = fqName("tailRecursive"); public final FqName noinline = fqName("noinline"); + public final FqNameUnsafe kClass = new FqName("kotlin.reflect.KClass").toUnsafe(); + public final Set primitiveTypes; public final Set primitiveArrays; { @@ -853,6 +855,10 @@ public class KotlinBuiltIns { return type != null && isNotNullConstructedFromGivenClass(type, FQ_NAMES.string); } + public static boolean isKClass(@NotNull ClassDescriptor descriptor) { + return FQ_NAMES.kClass.equals(DescriptorUtils.getFqName(descriptor)); + } + public static boolean isNonPrimitiveArray(@NotNull ClassDescriptor descriptor) { return FQ_NAMES.array.equals(DescriptorUtils.getFqName(descriptor)); } diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/AnnotationArgumentVisitor.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/AnnotationArgumentVisitor.java index 17665a4ec69..c1d2acf49a8 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/AnnotationArgumentVisitor.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/annotations/AnnotationArgumentVisitor.java @@ -51,5 +51,7 @@ public interface AnnotationArgumentVisitor { R visitJavaClassValue(JavaClassValue value, D data); + R visitKClassValue(KClassValue value, D data); + R visitNumberTypeValue(IntegerValueTypeConstant value, D data); } diff --git a/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererImpl.java b/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererImpl.java index a03ad6a509a..7900db42f7f 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererImpl.java +++ b/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererImpl.java @@ -31,10 +31,7 @@ import org.jetbrains.kotlin.name.FqNameBase; import org.jetbrains.kotlin.name.FqNameUnsafe; import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.resolve.DescriptorUtils; -import org.jetbrains.kotlin.resolve.constants.AnnotationValue; -import org.jetbrains.kotlin.resolve.constants.ArrayValue; -import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant; -import org.jetbrains.kotlin.resolve.constants.JavaClassValue; +import org.jetbrains.kotlin.resolve.constants.*; import org.jetbrains.kotlin.types.*; import org.jetbrains.kotlin.types.ErrorUtils.UninferredParameterTypeConstructor; import org.jetbrains.kotlin.types.error.MissingDependencyErrorClass; @@ -614,6 +611,11 @@ public class DescriptorRendererImpl implements DescriptorRenderer { public String visitJavaClassValue(JavaClassValue value, Void data) { return renderType(value.getValue()) + ".class"; } + + @Override + public String visitKClassValue(KClassValue value, Void data) { + return renderType(value.getValue()) + "::class"; + } }, null ); diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/constants/KClassValue.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/constants/KClassValue.kt new file mode 100644 index 00000000000..563f1b680bb --- /dev/null +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/constants/KClassValue.kt @@ -0,0 +1,29 @@ +/* + * Copyright 2010-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.resolve.constants + +import org.jetbrains.kotlin.builtins.KotlinBuiltIns +import org.jetbrains.kotlin.descriptors.annotations.AnnotationArgumentVisitor +import org.jetbrains.kotlin.types.JetType + + +public class KClassValue(type: JetType) : CompileTimeConstant(type, true, false, false) { + override fun getType(kotlinBuiltIns: KotlinBuiltIns) = value + override fun getValue(): JetType = value.getArguments().single().getType() + + override fun accept(visitor: AnnotationArgumentVisitor, data: D) = visitor.visitKClassValue(this, data) +}