Do not depend on ReflectionTypes from upstream Kotlin

ReflectionTypes was incorrectly copied to common backend in
https://github.com/JetBrains/kotlin/commit/27365dc4bed8833880dc7bd0fc0189fed5ff6fed.
In fact, the copied class references `kProperty*Impl` types which are
only available in kotlin-native's runtime [1], thus using them in the
common Kotlin would lead to all kinds of confusion.

The next step is to remove ReflectionTypes in the main Kotlin project
(will be done later), remove the unneeded override
Context.reflectionTypes, and rename reflectionTypes0 -> reflectionTypes.

[1] Types with the same name are also declared in kotlin-reflect, but
the JVM backend still can't reference them because generated JVM
bytecode can only depend on kotlin-stdlib
This commit is contained in:
Alexander Udalov
2018-10-02 16:51:09 +02:00
committed by Igor Chevdar
parent 71a601d87e
commit ab550196e9
4 changed files with 72 additions and 19 deletions
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.backend.konan
import llvm.LLVMDumpModule import llvm.LLVMDumpModule
import llvm.LLVMModuleRef import llvm.LLVMModuleRef
import org.jetbrains.kotlin.backend.common.DumpIrTreeWithDescriptorsVisitor import org.jetbrains.kotlin.backend.common.DumpIrTreeWithDescriptorsVisitor
import org.jetbrains.kotlin.backend.common.ReflectionTypes
import org.jetbrains.kotlin.backend.common.validateIrModule import org.jetbrains.kotlin.backend.common.validateIrModule
import org.jetbrains.kotlin.backend.konan.descriptors.* import org.jetbrains.kotlin.backend.konan.descriptors.*
import org.jetbrains.kotlin.backend.konan.ir.KonanIr import org.jetbrains.kotlin.backend.konan.ir.KonanIr
@@ -49,7 +48,6 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitClassReceiver import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitClassReceiver
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor
import org.jetbrains.kotlin.serialization.deserialization.getName import org.jetbrains.kotlin.serialization.deserialization.getName
import org.jetbrains.kotlin.types.KotlinType
import java.lang.System.out import java.lang.System.out
import kotlin.LazyThreadSafetyMode.PUBLICATION import kotlin.LazyThreadSafetyMode.PUBLICATION
import kotlin.reflect.KProperty import kotlin.reflect.KProperty
@@ -309,9 +307,15 @@ internal class Context(config: KonanConfig) : KonanBackendContext(config) {
fun <T> getValue(member: LazyMember<T>): T = fun <T> getValue(member: LazyMember<T>): T =
@Suppress("UNCHECKED_CAST") (lazyValues.getOrPut(member, { member.initializer(this) }) as T) @Suppress("UNCHECKED_CAST") (lazyValues.getOrPut(member, { member.initializer(this) }) as T)
override val reflectionTypes: ReflectionTypes by lazy(PUBLICATION) { @Deprecated("Use reflectionTypes0 instead.", ReplaceWith("this.reflectionTypes0"))
ReflectionTypes(moduleDescriptor, KonanFqNames.internalPackageName) override val reflectionTypes: org.jetbrains.kotlin.backend.common.ReflectionTypes
get() = throw UnsupportedOperationException("This method will be removed soon")
// TODO: rename to reflectionTypes after updating the Kotlin compiler
val reflectionTypes0: KonanReflectionTypes by lazy(PUBLICATION) {
KonanReflectionTypes(moduleDescriptor, KonanFqNames.internalPackageName)
} }
private val vtableBuilders = mutableMapOf<IrClass, ClassVtablesBuilder>() private val vtableBuilders = mutableMapOf<IrClass, ClassVtablesBuilder>()
fun getVtableBuilder(classDescriptor: IrClass) = vtableBuilders.getOrPut(classDescriptor) { fun getVtableBuilder(classDescriptor: IrClass) = vtableBuilders.getOrPut(classDescriptor) {
@@ -0,0 +1,50 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the LICENSE file.
*/
package org.jetbrains.kotlin.backend.konan
import org.jetbrains.kotlin.builtins.KOTLIN_REFLECT_FQ_NAME
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import kotlin.reflect.KProperty
class KonanReflectionTypes(module: ModuleDescriptor, internalPackage: FqName) {
private val kotlinReflectScope: MemberScope by lazy(LazyThreadSafetyMode.PUBLICATION) {
module.getPackage(KOTLIN_REFLECT_FQ_NAME).memberScope
}
private val internalScope: MemberScope by lazy(LazyThreadSafetyMode.PUBLICATION) {
module.getPackage(internalPackage).memberScope
}
private fun find(memberScope: MemberScope, className: String): ClassDescriptor {
val name = Name.identifier(className)
return memberScope.getContributedClassifier(name, NoLookupLocation.FROM_REFLECTION) as ClassDescriptor
}
private class ClassLookup(val memberScope: MemberScope) {
operator fun getValue(types: KonanReflectionTypes, property: KProperty<*>): ClassDescriptor {
return types.find(memberScope, property.name.capitalize())
}
}
fun getKFunction(n: Int): ClassDescriptor = find(kotlinReflectScope, "KFunction$n")
val kProperty0: ClassDescriptor by ClassLookup(kotlinReflectScope)
val kFunctionImpl: ClassDescriptor by ClassLookup(internalScope)
val kProperty0Impl: ClassDescriptor by ClassLookup(internalScope)
val kProperty1Impl: ClassDescriptor by ClassLookup(internalScope)
val kProperty2Impl: ClassDescriptor by ClassLookup(internalScope)
val kMutableProperty0Impl: ClassDescriptor by ClassLookup(internalScope)
val kMutableProperty1Impl: ClassDescriptor by ClassLookup(internalScope)
val kMutableProperty2Impl: ClassDescriptor by ClassLookup(internalScope)
val kLocalDelegatedPropertyImpl: ClassDescriptor by ClassLookup(internalScope)
val kLocalDelegatedMutablePropertyImpl: ClassDescriptor by ClassLookup(internalScope)
}
@@ -414,23 +414,23 @@ internal class KonanSymbols(context: Context, val symbolTable: SymbolTable, val
val isInitializedPropertyDescriptor = builtInsPackage("kotlin") val isInitializedPropertyDescriptor = builtInsPackage("kotlin")
.getContributedVariables(Name.identifier("isInitialized"), NoLookupLocation.FROM_BACKEND).single { .getContributedVariables(Name.identifier("isInitialized"), NoLookupLocation.FROM_BACKEND).single {
it.extensionReceiverParameter.let { it.extensionReceiverParameter.let {
it != null && TypeUtils.getClassDescriptor(it.type) == context.reflectionTypes.kProperty0 it != null && TypeUtils.getClassDescriptor(it.type) == context.reflectionTypes0.kProperty0
} && !it.isExpect } && !it.isExpect
} }
val isInitializedGetterDescriptor = isInitializedPropertyDescriptor.getter!! val isInitializedGetterDescriptor = isInitializedPropertyDescriptor.getter!!
val kFunctionImpl = symbolTable.referenceClass(context.reflectionTypes.kFunctionImpl) val kFunctionImpl = symbolTable.referenceClass(context.reflectionTypes0.kFunctionImpl)
val kProperty0Impl = symbolTable.referenceClass(context.reflectionTypes.kProperty0Impl) val kProperty0Impl = symbolTable.referenceClass(context.reflectionTypes0.kProperty0Impl)
val kProperty1Impl = symbolTable.referenceClass(context.reflectionTypes.kProperty1Impl) val kProperty1Impl = symbolTable.referenceClass(context.reflectionTypes0.kProperty1Impl)
val kProperty2Impl = symbolTable.referenceClass(context.reflectionTypes.kProperty2Impl) val kProperty2Impl = symbolTable.referenceClass(context.reflectionTypes0.kProperty2Impl)
val kMutableProperty0Impl = symbolTable.referenceClass(context.reflectionTypes.kMutableProperty0Impl) val kMutableProperty0Impl = symbolTable.referenceClass(context.reflectionTypes0.kMutableProperty0Impl)
val kMutableProperty1Impl = symbolTable.referenceClass(context.reflectionTypes.kMutableProperty1Impl) val kMutableProperty1Impl = symbolTable.referenceClass(context.reflectionTypes0.kMutableProperty1Impl)
val kMutableProperty2Impl = symbolTable.referenceClass(context.reflectionTypes.kMutableProperty2Impl) val kMutableProperty2Impl = symbolTable.referenceClass(context.reflectionTypes0.kMutableProperty2Impl)
val kLocalDelegatedPropertyImpl = symbolTable.referenceClass(context.reflectionTypes.kLocalDelegatedPropertyImpl) val kLocalDelegatedPropertyImpl = symbolTable.referenceClass(context.reflectionTypes0.kLocalDelegatedPropertyImpl)
val kLocalDelegatedMutablePropertyImpl = symbolTable.referenceClass(context.reflectionTypes.kLocalDelegatedMutablePropertyImpl) val kLocalDelegatedMutablePropertyImpl = symbolTable.referenceClass(context.reflectionTypes0.kLocalDelegatedMutablePropertyImpl)
val getClassTypeInfo = internalFunction("getClassTypeInfo") val getClassTypeInfo = internalFunction("getClassTypeInfo")
val getObjectTypeInfo = internalFunction("getObjectTypeInfo") val getObjectTypeInfo = internalFunction("getObjectTypeInfo")
@@ -471,7 +471,7 @@ internal class KonanSymbols(context: Context, val symbolTable: SymbolTable, val
.map { symbolTable.referenceClass(builtIns.getFunction(it)) } .map { symbolTable.referenceClass(builtIns.getFunction(it)) }
val kFunctions = (0 .. KONAN_FUNCTION_INTERFACES_MAX_PARAMETERS) val kFunctions = (0 .. KONAN_FUNCTION_INTERFACES_MAX_PARAMETERS)
.map { symbolTable.referenceClass(context.reflectionTypes.getKFunction(it)) } .map { symbolTable.referenceClass(context.reflectionTypes0.getKFunction(it)) }
fun getKFunctionType(returnType: IrType, parameterTypes: List<IrType>): IrType { fun getKFunctionType(returnType: IrType, parameterTypes: List<IrType>): IrType {
val kFunctionClassSymbol = kFunctions[parameterTypes.size] val kFunctionClassSymbol = kFunctions[parameterTypes.size]
@@ -47,7 +47,6 @@ import org.jetbrains.kotlin.types.TypeProjectionImpl
import org.jetbrains.kotlin.types.replace import org.jetbrains.kotlin.types.replace
internal class PropertyDelegationLowering(val context: KonanBackendContext) : FileLoweringPass { internal class PropertyDelegationLowering(val context: KonanBackendContext) : FileLoweringPass {
private val reflectionTypes = context.reflectionTypes
private var tempIndex = 0 private var tempIndex = 0
private fun getKPropertyImplConstructor(receiverTypes: List<IrType>, private fun getKPropertyImplConstructor(receiverTypes: List<IrType>,
@@ -300,9 +299,9 @@ internal class PropertyDelegationLowering(val context: KonanBackendContext) : Fi
val arguments = type.arguments val arguments = type.arguments
val expectedClassDescriptor = when (arguments.size) { val expectedClassDescriptor = when (arguments.size) {
0 -> return false 0 -> return false
1 -> reflectionTypes.kMutableProperty0 1 -> context.reflectionTypes0.kMutableProperty0
2 -> reflectionTypes.kMutableProperty1 2 -> context.reflectionTypes0.kMutableProperty1
3 -> reflectionTypes.kMutableProperty2 3 -> context.reflectionTypes0.kMutableProperty2
else -> throw AssertionError("More than 2 receivers is not allowed") else -> throw AssertionError("More than 2 receivers is not allowed")
} }
return type == expectedClassDescriptor.defaultType.replace(arguments) return type == expectedClassDescriptor.defaultType.replace(arguments)