Refactor annotation checks, fix regression. (#2285)
This commit is contained in:
+2
-33
@@ -17,11 +17,7 @@ import org.jetbrains.kotlin.backend.konan.isInlined
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.types.isUnit
|
||||
import org.jetbrains.kotlin.metadata.konan.KonanProtoBuf
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor
|
||||
import org.jetbrains.kotlin.serialization.konan.KonanPackageFragment
|
||||
import org.jetbrains.kotlin.types.SimpleType
|
||||
|
||||
/**
|
||||
@@ -81,17 +77,9 @@ internal fun IrSimpleFunction.resolveFakeOverride(): IrSimpleFunction {
|
||||
return realSupers.first { it.modality != Modality.ABSTRACT }
|
||||
}
|
||||
|
||||
private val intrinsicAnnotation = FqName("kotlin.native.internal.Intrinsic")
|
||||
private val frozenAnnotation = FqName("kotlin.native.internal.Frozen")
|
||||
|
||||
// TODO: don't forget to remove descriptor access here.
|
||||
internal val FunctionDescriptor.isIntrinsic: Boolean
|
||||
get() = this.descriptor.annotations.hasAnnotation(intrinsicAnnotation)
|
||||
|
||||
internal val org.jetbrains.kotlin.descriptors.DeclarationDescriptor.isFrozen: Boolean
|
||||
get() = this.annotations.hasAnnotation(frozenAnnotation) ||
|
||||
// RTTI is used for non-reference type box:
|
||||
this is org.jetbrains.kotlin.descriptors.ClassDescriptor && !this.defaultType.binaryTypeIsReference()
|
||||
get() = this.descriptor.isIntrinsic
|
||||
|
||||
internal val DeclarationDescriptor.isFrozen: Boolean
|
||||
get() = this.descriptor.isFrozen
|
||||
@@ -239,23 +227,4 @@ tailrec internal fun DeclarationDescriptor.findPackage(): PackageFragmentDescrip
|
||||
}
|
||||
|
||||
fun FunctionDescriptor.isComparisonDescriptor(map: Map<SimpleType, IrSimpleFunction>): Boolean =
|
||||
this in map.values
|
||||
|
||||
private fun sourceByIndex(descriptor: CallableMemberDescriptor, index: Int): SourceFile {
|
||||
val fragment = descriptor.findPackage() as KonanPackageFragment
|
||||
return fragment.sourceFileMap.sourceFile(index)
|
||||
}
|
||||
|
||||
fun CallableMemberDescriptor.findSourceFile(): SourceFile {
|
||||
val source = this.source.containingFile
|
||||
if (source != SourceFile.NO_SOURCE_FILE)
|
||||
return source
|
||||
return when {
|
||||
this is DeserializedSimpleFunctionDescriptor && proto.hasExtension(KonanProtoBuf.functionFile) -> sourceByIndex(
|
||||
this, proto.getExtension(KonanProtoBuf.functionFile))
|
||||
this is DeserializedPropertyDescriptor && proto.hasExtension(KonanProtoBuf.propertyFile) ->
|
||||
sourceByIndex(
|
||||
this, proto.getExtension(KonanProtoBuf.propertyFile))
|
||||
else -> TODO()
|
||||
}
|
||||
}
|
||||
this in map.values
|
||||
+58
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.backend.konan.descriptors
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.atMostOne
|
||||
import org.jetbrains.kotlin.backend.konan.binaryTypeIsReference
|
||||
import org.jetbrains.kotlin.backend.konan.serialization.isExported
|
||||
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor
|
||||
import org.jetbrains.kotlin.builtins.getFunctionalClassKind
|
||||
@@ -15,15 +16,21 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.FunctionDescriptorImpl
|
||||
import org.jetbrains.kotlin.metadata.konan.KonanProtoBuf
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.DescriptorFactory
|
||||
import org.jetbrains.kotlin.resolve.OverridingUtil
|
||||
import org.jetbrains.kotlin.resolve.constants.StringValue
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor
|
||||
import org.jetbrains.kotlin.serialization.konan.KonanPackageFragment
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty
|
||||
|
||||
|
||||
/**
|
||||
@@ -207,3 +214,54 @@ internal fun FunctionDescriptorImpl.initialize(
|
||||
modality,
|
||||
visibility
|
||||
)
|
||||
|
||||
private fun sourceByIndex(descriptor: CallableMemberDescriptor, index: Int): SourceFile {
|
||||
val fragment = descriptor.findPackage() as KonanPackageFragment
|
||||
return fragment.sourceFileMap.sourceFile(index)
|
||||
}
|
||||
|
||||
fun CallableMemberDescriptor.findSourceFile(): SourceFile {
|
||||
val source = this.source.containingFile
|
||||
if (source != SourceFile.NO_SOURCE_FILE)
|
||||
return source
|
||||
return when {
|
||||
this is DeserializedSimpleFunctionDescriptor && proto.hasExtension(KonanProtoBuf.functionFile) -> sourceByIndex(
|
||||
this, proto.getExtension(KonanProtoBuf.functionFile))
|
||||
this is DeserializedPropertyDescriptor && proto.hasExtension(KonanProtoBuf.propertyFile) ->
|
||||
sourceByIndex(
|
||||
this, proto.getExtension(KonanProtoBuf.propertyFile))
|
||||
else -> TODO()
|
||||
}
|
||||
}
|
||||
|
||||
private val intrinsicAnnotation = FqName("kotlin.native.internal.Intrinsic")
|
||||
private val symbolNameAnnotation = FqName("kotlin.native.SymbolName")
|
||||
private val objCMethodAnnotation = FqName("kotlinx.cinterop.ObjCMethod")
|
||||
private val frozenAnnotation = FqName("kotlin.native.internal.Frozen")
|
||||
|
||||
internal val DeclarationDescriptor.isFrozen: Boolean
|
||||
get() = this.annotations.hasAnnotation(frozenAnnotation) ||
|
||||
// RTTI is used for non-reference type box:
|
||||
this is org.jetbrains.kotlin.descriptors.ClassDescriptor && !this.defaultType.binaryTypeIsReference()
|
||||
|
||||
internal val FunctionDescriptor.isIntrinsic: Boolean
|
||||
get() = this.annotations.hasAnnotation(intrinsicAnnotation)
|
||||
|
||||
// TODO: coalesce all our annotation value getters into fewer functions.
|
||||
fun getAnnotationValue(annotation: AnnotationDescriptor): String? {
|
||||
return annotation.allValueArguments.values.ifNotEmpty {
|
||||
val stringValue = single() as? StringValue
|
||||
stringValue?.value
|
||||
}
|
||||
}
|
||||
|
||||
fun CallableMemberDescriptor.externalSymbolOrThrow(): String? {
|
||||
this.annotations.findAnnotation(symbolNameAnnotation)?.let {
|
||||
return getAnnotationValue(it)!!
|
||||
}
|
||||
if (this.annotations.hasAnnotation(intrinsicAnnotation)) return null
|
||||
|
||||
if (this.annotations.hasAnnotation(objCMethodAnnotation)) return null
|
||||
|
||||
throw Error("external function ${this} must have @SymbolName, @Intrinsic or @ObjCMethod annotation")
|
||||
}
|
||||
|
||||
+5
-20
@@ -6,7 +6,8 @@
|
||||
package org.jetbrains.kotlin.backend.konan.llvm
|
||||
|
||||
import llvm.LLVMTypeRef
|
||||
import org.jetbrains.kotlin.backend.common.ir.ir2string
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.externalSymbolOrThrow
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.getAnnotationValue
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.isAbstract
|
||||
import org.jetbrains.kotlin.backend.konan.irasdescriptors.*
|
||||
import org.jetbrains.kotlin.backend.konan.isInlined
|
||||
@@ -23,8 +24,6 @@ import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.konan.library.uniqueName
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.constants.StringValue
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty
|
||||
|
||||
|
||||
// This file describes the ABI for Kotlin descriptors of exported declarations.
|
||||
@@ -105,9 +104,6 @@ internal tailrec fun DeclarationDescriptor.isExported(): Boolean {
|
||||
|
||||
private val symbolNameAnnotation = FqName("kotlin.native.SymbolName")
|
||||
|
||||
private val intrinsicAnnotation = FqName("kotlin.native.internal.Intrinsic")
|
||||
private val objCMethodAnnotation = FqName("kotlinx.cinterop.ObjCMethod")
|
||||
|
||||
private val cnameAnnotation = FqName("kotlin.native.CName")
|
||||
|
||||
private val exportForCppRuntimeAnnotation = FqName("kotlin.native.internal.ExportForCppRuntime")
|
||||
@@ -211,17 +207,13 @@ internal val FunctionDescriptor.symbolName: String
|
||||
}
|
||||
|
||||
if (isExternal) {
|
||||
this.descriptor.annotations.findAnnotation(symbolNameAnnotation)?.let {
|
||||
return getStringValue(it)!!
|
||||
}
|
||||
if (!this.descriptor.annotations.hasAnnotation(intrinsicAnnotation) &&
|
||||
!this.descriptor.annotations.hasAnnotation(objCMethodAnnotation)) {
|
||||
throw Error("external function ${this.descriptor} must have @SymbolName, @Intrinsic or @ObjCMethod annotation")
|
||||
this.descriptor.externalSymbolOrThrow()?.let {
|
||||
return it
|
||||
}
|
||||
}
|
||||
|
||||
this.descriptor.annotations.findAnnotation(exportForCppRuntimeAnnotation)?.let {
|
||||
val name = getStringValue(it) ?: this.name.asString()
|
||||
val name = getAnnotationValue(it) ?: this.name.asString()
|
||||
return name // no wrapping currently required
|
||||
}
|
||||
|
||||
@@ -242,13 +234,6 @@ internal val IrField.symbolName: String
|
||||
|
||||
}
|
||||
|
||||
internal fun getStringValue(annotation: AnnotationDescriptor): String? {
|
||||
return annotation.allValueArguments.values.ifNotEmpty {
|
||||
val stringValue = single() as? StringValue
|
||||
stringValue?.value
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: bring here dependencies of this method?
|
||||
internal fun RuntimeAware.getLlvmFunctionType(function: FunctionDescriptor): LLVMTypeRef {
|
||||
val original = function.original
|
||||
|
||||
+1
-1
@@ -91,7 +91,7 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
|
||||
private fun exportTypeInfoIfRequired(classDesc: ClassDescriptor, typeInfoGlobal: LLVMValueRef?) {
|
||||
val annot = classDesc.descriptor.annotations.findAnnotation(EXPORT_TYPE_INFO_FQ_NAME)
|
||||
if (annot != null) {
|
||||
val name = getStringValue(annot)!!
|
||||
val name = getAnnotationValue(annot)!!
|
||||
// TODO: use LLVMAddAlias.
|
||||
val global = addGlobal(name, pointerType(runtime.typeInfoType), isExported = true)
|
||||
LLVMSetInitializer(global, typeInfoGlobal)
|
||||
|
||||
+3
-7
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.konan.serialization
|
||||
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.externalSymbolOrThrow
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.isExpectMember
|
||||
import org.jetbrains.kotlin.backend.konan.getInlinedClass
|
||||
import org.jetbrains.kotlin.backend.konan.getObjCMethodInfo
|
||||
@@ -156,8 +157,6 @@ internal tailrec fun DeclarationDescriptor.isExported(): Boolean {
|
||||
|
||||
private val symbolNameAnnotation = FqName("kotlin.native.SymbolName")
|
||||
|
||||
private val intrinsicAnnotation = FqName("kotlin.native.internal.Intrinsic")
|
||||
|
||||
private val exportForCppRuntimeAnnotation = FqName("kotlin.native.internal.ExportForCppRuntime")
|
||||
|
||||
private val cnameAnnotation = FqName("kotlin.native.internal.CName")
|
||||
@@ -249,11 +248,8 @@ private val FunctionDescriptor.uniqueName: String
|
||||
}
|
||||
|
||||
if (this.isExternal) {
|
||||
this.annotations.findAnnotation(symbolNameAnnotation)?.let {
|
||||
return getStringValue(it)!!
|
||||
}
|
||||
if (!annotations.hasAnnotation(intrinsicAnnotation)) {
|
||||
throw Error("external function $this must have @SymbolName annotation")
|
||||
externalSymbolOrThrow()?.let {
|
||||
return it
|
||||
}
|
||||
}
|
||||
// TODO: check that only external function has @SymbolName.
|
||||
|
||||
Reference in New Issue
Block a user