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.LLVMModuleRef
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.konan.descriptors.*
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.serialization.deserialization.descriptors.DeserializedClassDescriptor
import org.jetbrains.kotlin.serialization.deserialization.getName
import org.jetbrains.kotlin.types.KotlinType
import java.lang.System.out
import kotlin.LazyThreadSafetyMode.PUBLICATION
import kotlin.reflect.KProperty
@@ -309,9 +307,15 @@ internal class Context(config: KonanConfig) : KonanBackendContext(config) {
fun <T> getValue(member: LazyMember<T>): T =
@Suppress("UNCHECKED_CAST") (lazyValues.getOrPut(member, { member.initializer(this) }) as T)
override val reflectionTypes: ReflectionTypes by lazy(PUBLICATION) {
ReflectionTypes(moduleDescriptor, KonanFqNames.internalPackageName)
@Deprecated("Use reflectionTypes0 instead.", ReplaceWith("this.reflectionTypes0"))
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>()
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")
.getContributedVariables(Name.identifier("isInitialized"), NoLookupLocation.FROM_BACKEND).single {
it.extensionReceiverParameter.let {
it != null && TypeUtils.getClassDescriptor(it.type) == context.reflectionTypes.kProperty0
it != null && TypeUtils.getClassDescriptor(it.type) == context.reflectionTypes0.kProperty0
} && !it.isExpect
}
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 kProperty1Impl = symbolTable.referenceClass(context.reflectionTypes.kProperty1Impl)
val kProperty2Impl = symbolTable.referenceClass(context.reflectionTypes.kProperty2Impl)
val kMutableProperty0Impl = symbolTable.referenceClass(context.reflectionTypes.kMutableProperty0Impl)
val kMutableProperty1Impl = symbolTable.referenceClass(context.reflectionTypes.kMutableProperty1Impl)
val kMutableProperty2Impl = symbolTable.referenceClass(context.reflectionTypes.kMutableProperty2Impl)
val kProperty0Impl = symbolTable.referenceClass(context.reflectionTypes0.kProperty0Impl)
val kProperty1Impl = symbolTable.referenceClass(context.reflectionTypes0.kProperty1Impl)
val kProperty2Impl = symbolTable.referenceClass(context.reflectionTypes0.kProperty2Impl)
val kMutableProperty0Impl = symbolTable.referenceClass(context.reflectionTypes0.kMutableProperty0Impl)
val kMutableProperty1Impl = symbolTable.referenceClass(context.reflectionTypes0.kMutableProperty1Impl)
val kMutableProperty2Impl = symbolTable.referenceClass(context.reflectionTypes0.kMutableProperty2Impl)
val kLocalDelegatedPropertyImpl = symbolTable.referenceClass(context.reflectionTypes.kLocalDelegatedPropertyImpl)
val kLocalDelegatedMutablePropertyImpl = symbolTable.referenceClass(context.reflectionTypes.kLocalDelegatedMutablePropertyImpl)
val kLocalDelegatedPropertyImpl = symbolTable.referenceClass(context.reflectionTypes0.kLocalDelegatedPropertyImpl)
val kLocalDelegatedMutablePropertyImpl = symbolTable.referenceClass(context.reflectionTypes0.kLocalDelegatedMutablePropertyImpl)
val getClassTypeInfo = internalFunction("getClassTypeInfo")
val getObjectTypeInfo = internalFunction("getObjectTypeInfo")
@@ -471,7 +471,7 @@ internal class KonanSymbols(context: Context, val symbolTable: SymbolTable, val
.map { symbolTable.referenceClass(builtIns.getFunction(it)) }
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 {
val kFunctionClassSymbol = kFunctions[parameterTypes.size]
@@ -47,7 +47,6 @@ import org.jetbrains.kotlin.types.TypeProjectionImpl
import org.jetbrains.kotlin.types.replace
internal class PropertyDelegationLowering(val context: KonanBackendContext) : FileLoweringPass {
private val reflectionTypes = context.reflectionTypes
private var tempIndex = 0
private fun getKPropertyImplConstructor(receiverTypes: List<IrType>,
@@ -300,9 +299,9 @@ internal class PropertyDelegationLowering(val context: KonanBackendContext) : Fi
val arguments = type.arguments
val expectedClassDescriptor = when (arguments.size) {
0 -> return false
1 -> reflectionTypes.kMutableProperty0
2 -> reflectionTypes.kMutableProperty1
3 -> reflectionTypes.kMutableProperty2
1 -> context.reflectionTypes0.kMutableProperty0
2 -> context.reflectionTypes0.kMutableProperty1
3 -> context.reflectionTypes0.kMutableProperty2
else -> throw AssertionError("More than 2 receivers is not allowed")
}
return type == expectedClassDescriptor.defaultType.replace(arguments)