Reflection: add KVariance, KTypeParameter.{variance,upperBounds,equals,hashCode}

This commit is contained in:
Alexander Udalov
2016-07-22 15:34:54 +03:00
parent 127e7ab5b7
commit 170ea4dead
9 changed files with 272 additions and 3 deletions
+20 -3
View File
@@ -70,23 +70,37 @@ public sealed class KTypeProjection {
*/
public abstract val type: KType?
/**
* The use-site variance specified in the projection, or `null` if this is a star projection.
*/
public abstract val variance: KVariance?
/**
* Invariant projection of a type. Invariant projection is just the type itself, without any use-site variance modifiers applied to it.
* For example, in the type `Set<String>`, `String` is an invariant projection of the type represented by the class `String`.
*/
public data class Invariant(override val type: KType) : KTypeProjection()
public data class Invariant(override val type: KType) : KTypeProjection() {
override val variance: KVariance?
get() = KVariance.INVARIANT
}
/**
* Contravariant projection of a type, denoted by the `in` modifier applied to a type.
* For example, in the type `MutableList<in Number>`, `in Number` is a contravariant projection of the type of class `Number`.
*/
public data class In(override val type: KType) : KTypeProjection()
public data class In(override val type: KType) : KTypeProjection() {
override val variance: KVariance?
get() = KVariance.IN
}
/**
* Covariant projection of a type, denoted by the `out` modifier applied to a type.
* For example, in the type `Array<out Number>`, `out Number` is a covariant projection of the type of class `Number`.
*/
public data class Out(override val type: KType) : KTypeProjection()
public data class Out(override val type: KType) : KTypeProjection() {
override val variance: KVariance?
get() = KVariance.OUT
}
/**
* Star projection, denoted by the `*` character.
@@ -97,5 +111,8 @@ public sealed class KTypeProjection {
public object Star : KTypeProjection() {
override val type: KType?
get() = null
override val variance: KVariance?
get() = null
}
}
@@ -26,4 +26,18 @@ public interface KTypeParameter : KClassifier {
* The name of this type parameter as it was declared in the source code.
*/
public val name: String
/**
* Upper bounds, or generic constraints imposed on this type parameter.
* See the [Kotlin language documentation](https://kotlinlang.org/docs/reference/generics.html#upper-bounds)
* for more information.
*/
public val upperBounds: List<KType>
/**
* Declaration-site variance of this type parameter.
* See the [Kotlin language documentation](https://kotlinlang.org/docs/reference/generics.html#declaration-site-variance)
* for more information.
*/
public val variance: KVariance
}
@@ -0,0 +1,44 @@
/*
* Copyright 2010-2016 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 kotlin.reflect
/**
* Represents variance applied to a type parameter on the declaration site (*declaration-site variance*),
* or to a type in a projection (*use-site variance*).
*
* See the [Kotlin language documentation](https://kotlinlang.org/docs/reference/generics.html#variance)
* for more information.
*
* @see [KTypeParameter.variance]
* @see [KTypeProjection]
*/
enum class KVariance {
/**
* The affected type parameter or type is *invariant*, which means it has no variance applied to it.
*/
INVARIANT,
/**
* The affected type parameter or type is *contravariant*. Denoted by the `in` modifier in the source code.
*/
IN,
/**
* The affected type parameter or type is *covariant*. Denoted by the `out` modifier in the source code.
*/
OUT,
}
@@ -17,9 +17,32 @@
package kotlin.reflect.jvm.internal
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.types.Variance
import kotlin.reflect.KType
import kotlin.reflect.KTypeParameter
import kotlin.reflect.KVariance
internal class KTypeParameterImpl(override val descriptor: TypeParameterDescriptor) : KTypeParameter, KClassifierImpl {
override val name: String
get() = descriptor.name.asString()
override val upperBounds: List<KType>
get() = descriptor.upperBounds.map { kotlinType ->
KTypeImpl(kotlinType) {
TODO("Java type is not yet supported for type parameters: $descriptor")
}
}
override val variance: KVariance
get() = when (descriptor.variance) {
Variance.INVARIANT -> KVariance.INVARIANT
Variance.IN_VARIANCE -> KVariance.IN
Variance.OUT_VARIANCE -> KVariance.OUT
}
override fun equals(other: Any?) =
other is KTypeParameterImpl && descriptor == other.descriptor
override fun hashCode() =
descriptor.hashCode()
}