Implemented KType, KCallable.returnType

This commit is contained in:
Igor Chevdar
2018-08-14 16:58:33 +03:00
parent 146eac0010
commit 29c03b258a
9 changed files with 168 additions and 35 deletions
@@ -353,6 +353,8 @@ internal class KonanSymbols(context: Context, val symbolTable: SymbolTable, val
val getObjectTypeInfo = internalFunction("getObjectTypeInfo")
val kClassImpl = internalClass("KClassImpl")
val kClassImplConstructor by lazy { kClassImpl.constructors.single() }
val kTypeImpl = internalClass("KTypeImpl")
val kTypeImplForGenerics = internalClass("KTypeImplForGenerics")
val listOfInternal = internalFunction("listOfInternal")
@@ -43,9 +43,7 @@ import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrDelegatingConstructorCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrInstanceInitializerCallImpl
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
import org.jetbrains.kotlin.ir.types.*
@@ -169,18 +167,19 @@ internal class CallableReferenceLowering(val context: Context): FileLoweringPass
private val kFunctionImplSymbol = context.ir.symbols.kFunctionImpl
private val kFunctionImplConstructorSymbol = kFunctionImplSymbol.constructors.single()
fun build(): BuiltFunctionReference {
val startOffset = functionReference.startOffset
val endOffset = functionReference.endOffset
val returnType = irFunction.returnType
val superTypes = mutableListOf(kFunctionImplSymbol.typeWith(returnType))
val superTypes = mutableListOf(kFunctionImplSymbol.typeWith(irFunction.returnType))
val numberOfParameters = unboundFunctionParameters.size
val functionIrClass = context.ir.symbols.kFunctions[numberOfParameters].owner
val functionParameterTypes = unboundFunctionParameters.map { it.type }
val functionClassTypeParameters = functionParameterTypes + returnType
val functionClassTypeParameters = functionParameterTypes + irFunction.returnType
superTypes += functionIrClass.symbol.typeWith(functionClassTypeParameters)
var suspendFunctionIrClass: IrClass? = null
@@ -256,8 +255,6 @@ internal class CallableReferenceLowering(val context: Context): FileLoweringPass
private fun createConstructorBuilder()
= object : SymbolWithIrBuilder<IrConstructorSymbol, IrConstructor>() {
private val kFunctionImplConstructorSymbol = kFunctionImplSymbol.constructors.single()
override fun buildSymbol() = IrConstructorSymbolImpl(
ClassConstructorDescriptorImpl.create(
/* containingDeclaration = */ functionReferenceClassDescriptor,
@@ -278,7 +275,6 @@ internal class CallableReferenceLowering(val context: Context): FileLoweringPass
override fun buildIr(): IrConstructor {
val symbols = this@CallableReferenceLowering.context.ir.symbols
val irBuiltIns = context.irBuiltIns
argumentToPropertiesMap = boundFunctionParameters.associate {
@@ -318,6 +314,7 @@ internal class CallableReferenceLowering(val context: Context): FileLoweringPass
val needReceiver = boundFunctionParameters.singleOrNull()?.descriptor is ReceiverParameterDescriptor
val receiver = if (needReceiver) irGet(valueParameters.single()) else irNull()
putValueArgument(3, receiver)
putValueArgument(4, irKType(this@CallableReferenceLowering.context, irFunction.returnType))
}
+IrInstanceInitializerCallImpl(startOffset, endOffset, functionReferenceClass.symbol, irBuiltIns.unitType)
// Save all arguments to fields.
@@ -36,7 +36,10 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrLocalDelegatedPropertyReference
import org.jetbrains.kotlin.ir.expressions.IrPropertyReference
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.toKotlinType
import org.jetbrains.kotlin.ir.types.typeWith
@@ -271,10 +274,11 @@ internal class PropertyDelegationLowering(val context: KonanBackendContext) : Fi
isMutable = setterCallableReference != null)
val initializer = irCall(symbol.owner, constructorTypeArguments).apply {
putValueArgument(0, irString(propertyDescriptor.name.asString()))
putValueArgument(1, irKType(this@PropertyDelegationLowering.context, returnType))
if (getterCallableReference != null)
putValueArgument(1, getterCallableReference)
putValueArgument(2, getterCallableReference)
if (setterCallableReference != null)
putValueArgument(2, setterCallableReference)
putValueArgument(3, setterCallableReference)
}
+initializer
}
@@ -291,6 +295,7 @@ internal class PropertyDelegationLowering(val context: KonanBackendContext) : Fi
isMutable = false)
val initializer = irCall(symbol.owner, constructorTypeArguments).apply {
putValueArgument(0, irString(propertyDescriptor.name.asString()))
putValueArgument(1, irKType(this@PropertyDelegationLowering.context, propertyType))
}
return initializer
}
@@ -323,3 +328,26 @@ internal class PropertyDelegationLowering(val context: KonanBackendContext) : Fi
}
}
internal fun IrBuilderWithScope.irKType(context: KonanBackendContext, type: IrType): IrExpression {
val kTypeImplSymbol = context.ir.symbols.kTypeImpl
val kTypeImplForGenericsSymbol = context.ir.symbols.kTypeImplForGenerics
val kClassImplConstructorSymbol = context.ir.symbols.kClassImplConstructor
val kTypeImplConstructorSymbol = kTypeImplSymbol.constructors.single()
val kTypeImplForGenericsConstructorSymbol = kTypeImplForGenericsSymbol.constructors.single()
val getClassTypeInfoSymbol = context.ir.symbols.getClassTypeInfo
return if (type.classifierOrNull !is IrClassSymbol) {
// IrTypeParameterSymbol
irCall(kTypeImplForGenericsConstructorSymbol)
} else {
val returnKClass = irCall(kClassImplConstructorSymbol).apply {
putValueArgument(0, irCall(getClassTypeInfoSymbol, listOf(type)))
}
irCall(kTypeImplConstructorSymbol).apply {
putValueArgument(0, returnKClass)
putValueArgument(1, irBoolean(type.isMarkedNullable()))
}
}
}
@@ -47,6 +47,10 @@ internal class KClassImpl<T : Any>(private val typeInfo: NativePtr) : KClass<T>
other is KClassImpl<*> && this.typeInfo == other.typeInfo
override fun hashCode(): Int = typeInfo.hashCode()
override fun toString(): String {
return "class " + (qualifiedName ?: simpleName ?: "<anonymous>")
}
}
@ExportForCompiler
@@ -17,9 +17,11 @@
package kotlin.native.internal
import kotlin.reflect.KFunction
import kotlin.reflect.KType
@FixmeReflection
open class KFunctionImpl<out R>(override val name: String, val fqName: String, val bound: Boolean, val receiver: Any?): KFunction<R> {
open class KFunctionImpl<out R>(override val name: String, val fqName: String, val bound: Boolean, val receiver: Any?,
override val returnType: KType): KFunction<R> {
override fun equals(other: Any?): Boolean {
if (other !is KFunctionImpl<*>) return false
return fqName == other.fqName && bound == other.bound && receiver == other.receiver
@@ -16,16 +16,11 @@
package kotlin.native.internal
import kotlin.reflect.KProperty0
import kotlin.reflect.KProperty1
import kotlin.reflect.KProperty2
import kotlin.reflect.KMutableProperty0
import kotlin.reflect.KMutableProperty1
import kotlin.reflect.KMutableProperty2
import kotlin.UnsupportedOperationException
import kotlin.reflect.*
@FixmeReflection
open class KProperty0Impl<out R>(override val name: String, val getter: () -> R): KProperty0<R> {
open class KProperty0Impl<out R>(override val name: String, override val returnType: KType, val getter: () -> R): KProperty0<R> {
override fun get(): R {
return getter()
}
@@ -49,7 +44,7 @@ open class KProperty0Impl<out R>(override val name: String, val getter: () -> R)
}
@FixmeReflection
open class KProperty1Impl<T, out R>(override val name: String, val getter: (T) -> R): KProperty1<T, R> {
open class KProperty1Impl<T, out R>(override val name: String, override val returnType: KType, val getter: (T) -> R): KProperty1<T, R> {
override fun get(p1: T): R {
return getter(p1)
}
@@ -73,7 +68,7 @@ open class KProperty1Impl<T, out R>(override val name: String, val getter: (T) -
}
@FixmeReflection
open class KProperty2Impl<T1, T2, out R>(override val name: String, val getter: (T1, T2) -> R): KProperty2<T1, T2, R> {
open class KProperty2Impl<T1, T2, out R>(override val name: String, override val returnType: KType, val getter: (T1, T2) -> R): KProperty2<T1, T2, R> {
override fun get(p1: T1, p2: T2): R {
return getter(p1, p2)
}
@@ -97,8 +92,8 @@ open class KProperty2Impl<T1, T2, out R>(override val name: String, val getter:
}
@FixmeReflection
class KMutableProperty0Impl<R>(name: String, getter: () -> R, val setter: (R) -> Unit)
: KProperty0Impl<R>(name, getter), KMutableProperty0<R> {
class KMutableProperty0Impl<R>(name: String, returnType: KType, getter: () -> R, val setter: (R) -> Unit)
: KProperty0Impl<R>(name, returnType, getter), KMutableProperty0<R> {
override fun set(value: R): Unit {
setter(value)
}
@@ -119,8 +114,8 @@ class KMutableProperty0Impl<R>(name: String, getter: () -> R, val setter: (R) ->
}
@FixmeReflection
class KMutableProperty1Impl<T, R>(name: String, getter: (T) -> R, val setter: (T, R) -> Unit)
: KProperty1Impl<T, R>(name, getter), KMutableProperty1<T, R> {
class KMutableProperty1Impl<T, R>(name: String, returnType: KType, getter: (T) -> R, val setter: (T, R) -> Unit)
: KProperty1Impl<T, R>(name, returnType, getter), KMutableProperty1<T, R> {
override fun set(receiver: T, value: R): Unit {
setter(receiver, value)
}
@@ -141,8 +136,8 @@ class KMutableProperty1Impl<T, R>(name: String, getter: (T) -> R, val setter: (T
}
@FixmeReflection
class KMutableProperty2Impl<T1, T2, R>(name: String, getter: (T1, T2) -> R, val setter: (T1, T2, R) -> Unit)
: KProperty2Impl<T1, T2, R>(name, getter), KMutableProperty2<T1, T2, R> {
class KMutableProperty2Impl<T1, T2, R>(name: String, returnType: KType, getter: (T1, T2) -> R, val setter: (T1, T2, R) -> Unit)
: KProperty2Impl<T1, T2, R>(name, returnType, getter), KMutableProperty2<T1, T2, R> {
override fun set(receiver1: T1, receiver2: T2, value: R): Unit {
setter(receiver1, receiver2, value)
}
@@ -162,7 +157,7 @@ class KMutableProperty2Impl<T1, T2, R>(name: String, getter: (T1, T2) -> R, val
}
}
open class KLocalDelegatedPropertyImpl<out R>(override val name: String): KProperty0<R> {
open class KLocalDelegatedPropertyImpl<out R>(override val name: String, override val returnType: KType): KProperty0<R> {
override fun get(): R {
throw UnsupportedOperationException("Not supported for local property reference.")
}
@@ -175,7 +170,7 @@ open class KLocalDelegatedPropertyImpl<out R>(override val name: String): KPrope
}
}
class KLocalDelegatedMutablePropertyImpl<R>(name: String): KLocalDelegatedPropertyImpl<R>(name), KMutableProperty0<R> {
class KLocalDelegatedMutablePropertyImpl<R>(name: String, returnType: KType): KLocalDelegatedPropertyImpl<R>(name, returnType), KMutableProperty0<R> {
override fun set(value: R): Unit {
throw UnsupportedOperationException("Not supported for local property reference.")
}
@@ -0,0 +1,43 @@
/*
* Copyright 2010-2018 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.native.internal
import kotlin.reflect.KClassifier
import kotlin.reflect.KType
internal class KTypeImpl(override val classifier: KClassifier?, override val isMarkedNullable: Boolean) : KType {
override fun equals(other: Any?) =
other is KTypeImpl && classifier == other.classifier && isMarkedNullable == other.isMarkedNullable
override fun hashCode(): Int {
return (classifier?.hashCode() ?: 0) * 31 + if (isMarkedNullable) 1 else 0
}
}
internal class KTypeImplForGenerics : KType {
override val classifier: KClassifier?
get() = error("Generic types are not yet supported in reflection")
override val isMarkedNullable: Boolean
get() = error("Generic types are not yet supported in reflection")
override fun equals(other: Any?) =
error("Generic types are not yet supported in reflection")
override fun hashCode(): Int =
error("Generic types are not yet supported in reflection")
}
@@ -39,12 +39,12 @@ public interface KCallable<out R> : KAnnotatedElement {
// * they come first in the list in that order.
// */
// public val parameters: List<KParameter>
//
// /**
// * The type of values returned by this callable.
// */
// public val returnType: KType
//
/**
* The type of values returned by this callable.
*/
public val returnType: KType
// /**
// * The list of type parameters of this callable.
// */
@@ -0,0 +1,62 @@
/*
* Copyright 2010-2017 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 a type. Type is usually either a class with optional type arguments,
* or a type parameter of some declaration, plus nullability.
*/
public interface KType {
/**
* The declaration of the classifier used in this type.
* For example, in the type `List<String>` the classifier would be the [KClass] instance for [List].
*
* Returns `null` if this type is not denotable in Kotlin, for example if it is an intersection type.
*/
@SinceKotlin("1.1")
public val classifier: KClassifier?
/**
* Type arguments passed for the parameters of the classifier in this type.
* For example, in the type `Array<out Number>` the only type argument is `out Number`.
*
* In case this type is based on an inner class, the returned list contains the type arguments provided for the innermost class first,
* then its outer class, and so on.
* For example, in the type `Outer<A, B>.Inner<C, D>` the returned list is `[C, D, A, B]`.
*/
// @SinceKotlin("1.1")
// public val arguments: List<KTypeProjection>
/**
* `true` if this type was marked nullable in the source code.
*
* For Kotlin types, it means that `null` value is allowed to be represented by this type.
* In practice it means that the type was declared with a question mark at the end.
* For non-Kotlin types, it means the type or the symbol which was declared with this type
* is annotated with a runtime-retained nullability annotation such as [javax.annotation.Nullable].
*
* Note that even if [isMarkedNullable] is false, values of the type can still be `null`.
* This may happen if it is a type of the type parameter with a nullable upper bound:
*
* ```
* fun <T> foo(t: T) {
* // isMarkedNullable == false for t's type, but t can be null here when T = "Any?"
* }
* ```
*/
public val isMarkedNullable: Boolean
}