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.descriptors.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||||
import org.jetbrains.kotlin.ir.types.isUnit
|
import org.jetbrains.kotlin.ir.types.isUnit
|
||||||
import org.jetbrains.kotlin.metadata.konan.KonanProtoBuf
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
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
|
import org.jetbrains.kotlin.types.SimpleType
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -81,17 +77,9 @@ internal fun IrSimpleFunction.resolveFakeOverride(): IrSimpleFunction {
|
|||||||
return realSupers.first { it.modality != Modality.ABSTRACT }
|
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.
|
// TODO: don't forget to remove descriptor access here.
|
||||||
internal val FunctionDescriptor.isIntrinsic: Boolean
|
internal val FunctionDescriptor.isIntrinsic: Boolean
|
||||||
get() = this.descriptor.annotations.hasAnnotation(intrinsicAnnotation)
|
get() = this.descriptor.isIntrinsic
|
||||||
|
|
||||||
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()
|
|
||||||
|
|
||||||
internal val DeclarationDescriptor.isFrozen: Boolean
|
internal val DeclarationDescriptor.isFrozen: Boolean
|
||||||
get() = this.descriptor.isFrozen
|
get() = this.descriptor.isFrozen
|
||||||
@@ -239,23 +227,4 @@ tailrec internal fun DeclarationDescriptor.findPackage(): PackageFragmentDescrip
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun FunctionDescriptor.isComparisonDescriptor(map: Map<SimpleType, IrSimpleFunction>): Boolean =
|
fun FunctionDescriptor.isComparisonDescriptor(map: Map<SimpleType, IrSimpleFunction>): Boolean =
|
||||||
this in map.values
|
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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+58
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.backend.konan.descriptors
|
package org.jetbrains.kotlin.backend.konan.descriptors
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.atMostOne
|
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.backend.konan.serialization.isExported
|
||||||
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor
|
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor
|
||||||
import org.jetbrains.kotlin.builtins.getFunctionalClassKind
|
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.builtins.konan.KonanBuiltIns
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
import org.jetbrains.kotlin.descriptors.impl.FunctionDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.FunctionDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.metadata.konan.KonanProtoBuf
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorFactory
|
import org.jetbrains.kotlin.resolve.DescriptorFactory
|
||||||
import org.jetbrains.kotlin.resolve.OverridingUtil
|
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.fqNameSafe
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
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.KotlinType
|
||||||
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -207,3 +214,54 @@ internal fun FunctionDescriptorImpl.initialize(
|
|||||||
modality,
|
modality,
|
||||||
visibility
|
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
|
package org.jetbrains.kotlin.backend.konan.llvm
|
||||||
|
|
||||||
import llvm.LLVMTypeRef
|
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.descriptors.isAbstract
|
||||||
import org.jetbrains.kotlin.backend.konan.irasdescriptors.*
|
import org.jetbrains.kotlin.backend.konan.irasdescriptors.*
|
||||||
import org.jetbrains.kotlin.backend.konan.isInlined
|
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.konan.library.uniqueName
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
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.
|
// 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 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 cnameAnnotation = FqName("kotlin.native.CName")
|
||||||
|
|
||||||
private val exportForCppRuntimeAnnotation = FqName("kotlin.native.internal.ExportForCppRuntime")
|
private val exportForCppRuntimeAnnotation = FqName("kotlin.native.internal.ExportForCppRuntime")
|
||||||
@@ -211,17 +207,13 @@ internal val FunctionDescriptor.symbolName: String
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isExternal) {
|
if (isExternal) {
|
||||||
this.descriptor.annotations.findAnnotation(symbolNameAnnotation)?.let {
|
this.descriptor.externalSymbolOrThrow()?.let {
|
||||||
return getStringValue(it)!!
|
return 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.annotations.findAnnotation(exportForCppRuntimeAnnotation)?.let {
|
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
|
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?
|
// TODO: bring here dependencies of this method?
|
||||||
internal fun RuntimeAware.getLlvmFunctionType(function: FunctionDescriptor): LLVMTypeRef {
|
internal fun RuntimeAware.getLlvmFunctionType(function: FunctionDescriptor): LLVMTypeRef {
|
||||||
val original = function.original
|
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?) {
|
private fun exportTypeInfoIfRequired(classDesc: ClassDescriptor, typeInfoGlobal: LLVMValueRef?) {
|
||||||
val annot = classDesc.descriptor.annotations.findAnnotation(EXPORT_TYPE_INFO_FQ_NAME)
|
val annot = classDesc.descriptor.annotations.findAnnotation(EXPORT_TYPE_INFO_FQ_NAME)
|
||||||
if (annot != null) {
|
if (annot != null) {
|
||||||
val name = getStringValue(annot)!!
|
val name = getAnnotationValue(annot)!!
|
||||||
// TODO: use LLVMAddAlias.
|
// TODO: use LLVMAddAlias.
|
||||||
val global = addGlobal(name, pointerType(runtime.typeInfoType), isExported = true)
|
val global = addGlobal(name, pointerType(runtime.typeInfoType), isExported = true)
|
||||||
LLVMSetInitializer(global, typeInfoGlobal)
|
LLVMSetInitializer(global, typeInfoGlobal)
|
||||||
|
|||||||
+3
-7
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.backend.konan.serialization
|
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.descriptors.isExpectMember
|
||||||
import org.jetbrains.kotlin.backend.konan.getInlinedClass
|
import org.jetbrains.kotlin.backend.konan.getInlinedClass
|
||||||
import org.jetbrains.kotlin.backend.konan.getObjCMethodInfo
|
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 symbolNameAnnotation = FqName("kotlin.native.SymbolName")
|
||||||
|
|
||||||
private val intrinsicAnnotation = FqName("kotlin.native.internal.Intrinsic")
|
|
||||||
|
|
||||||
private val exportForCppRuntimeAnnotation = FqName("kotlin.native.internal.ExportForCppRuntime")
|
private val exportForCppRuntimeAnnotation = FqName("kotlin.native.internal.ExportForCppRuntime")
|
||||||
|
|
||||||
private val cnameAnnotation = FqName("kotlin.native.internal.CName")
|
private val cnameAnnotation = FqName("kotlin.native.internal.CName")
|
||||||
@@ -249,11 +248,8 @@ private val FunctionDescriptor.uniqueName: String
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.isExternal) {
|
if (this.isExternal) {
|
||||||
this.annotations.findAnnotation(symbolNameAnnotation)?.let {
|
externalSymbolOrThrow()?.let {
|
||||||
return getStringValue(it)!!
|
return it
|
||||||
}
|
|
||||||
if (!annotations.hasAnnotation(intrinsicAnnotation)) {
|
|
||||||
throw Error("external function $this must have @SymbolName annotation")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: check that only external function has @SymbolName.
|
// TODO: check that only external function has @SymbolName.
|
||||||
|
|||||||
Reference in New Issue
Block a user