[K/N] Modularise :kotlin-native:native.backend to extract objc header generation (2/2)

^KT-63905 Fixed
This commit is contained in:
Sebastian Sellmair
2023-11-29 11:41:56 +01:00
committed by Space Team
parent ae9f3d66c2
commit 0713866c1e
37 changed files with 601 additions and 458 deletions
+6 -2
View File
@@ -344,7 +344,11 @@ val projectsUsedInIntelliJKotlinPlugin =
":kotlin-gradle-statistics", ":kotlin-gradle-statistics",
":jps:jps-common", ":jps:jps-common",
) + ) +
if (kotlinBuildProperties.isKotlinNativeEnabled) arrayOf(":kotlin-native:backend.native") else emptyArray() arrayOf(
":native:base",
":native:objcexport-header-generator",
":compiler:ir.serialization.native"
)
extra["projectsUsedInIntelliJKotlinPlugin"] = projectsUsedInIntelliJKotlinPlugin extra["projectsUsedInIntelliJKotlinPlugin"] = projectsUsedInIntelliJKotlinPlugin
@@ -415,7 +419,7 @@ extra["compilerArtifactsForIde"] = listOfNotNull(
":prepare:ide-plugin-dependencies:assignment-compiler-plugin-for-ide", ":prepare:ide-plugin-dependencies:assignment-compiler-plugin-for-ide",
":prepare:ide-plugin-dependencies:parcelize-compiler-plugin-for-ide", ":prepare:ide-plugin-dependencies:parcelize-compiler-plugin-for-ide",
":prepare:ide-plugin-dependencies:lombok-compiler-plugin-for-ide", ":prepare:ide-plugin-dependencies:lombok-compiler-plugin-for-ide",
":prepare:ide-plugin-dependencies:kotlin-backend-native-for-ide".takeIf { kotlinBuildProperties.isKotlinNativeEnabled }, ":prepare:ide-plugin-dependencies:kotlin-objcexport-header-generator-for-ide",
":prepare:ide-plugin-dependencies:kotlin-compiler-tests-for-ide", ":prepare:ide-plugin-dependencies:kotlin-compiler-tests-for-ide",
":prepare:ide-plugin-dependencies:kotlin-compiler-testdata-for-ide", ":prepare:ide-plugin-dependencies:kotlin-compiler-testdata-for-ide",
":prepare:ide-plugin-dependencies:low-level-api-fir-for-ide", ":prepare:ide-plugin-dependencies:low-level-api-fir-for-ide",
+3 -34
View File
@@ -29,12 +29,6 @@ sourceSets {
cli_bc { cli_bc {
kotlin.srcDir 'cli.bc/src' kotlin.srcDir 'cli.bc/src'
} }
test {
kotlin {
srcDir 'functionalTest/src'
}
}
} }
compileCompilerKotlin { compileCompilerKotlin {
@@ -43,6 +37,7 @@ compileCompilerKotlin {
'-opt-in=kotlin.RequiresOptIn', '-opt-in=kotlin.RequiresOptIn',
"-opt-in=kotlinx.cinterop.BetaInteropApi", "-opt-in=kotlinx.cinterop.BetaInteropApi",
"-opt-in=kotlinx.cinterop.ExperimentalForeignApi", "-opt-in=kotlinx.cinterop.ExperimentalForeignApi",
"-opt-in=org.jetbrains.kotlin.backend.konan.InternalKotlinNativeApi",
'-Xskip-prerelease-check'] '-Xskip-prerelease-check']
} }
@@ -159,6 +154,8 @@ dependencies {
kotlin_script_runtime_jar project(":kotlin-script-runtime") kotlin_script_runtime_jar project(":kotlin-script-runtime")
compilerApi project(":kotlin-native:utilities:basic-utils") compilerApi project(":kotlin-native:utilities:basic-utils")
compilerApi project(":native:objcexport-header-generator")
compilerApi project(":native:base")
compilerImplementation project(":kotlin-compiler") compilerImplementation project(":kotlin-compiler")
compilerApi project(":native:kotlin-native-utils") compilerApi project(":native:kotlin-native-utils")
@@ -187,11 +184,6 @@ dependencies {
cli_bcApi sourceSets.compiler.output cli_bcApi sourceSets.compiler.output
cli_bcApiElements sourceSets.cli_bc.output cli_bcApiElements sourceSets.cli_bc.output
testImplementation(project(path: ":compiler:tests-common", configuration: "tests-jar"))
testImplementation(libs.junit.jupiter.api)
testImplementation(libs.junit.jupiter.params)
testRuntimeOnly(libs.junit.jupiter.engine)
} }
classes.dependsOn 'compilerClasses', 'cli_bcClasses' classes.dependsOn 'compilerClasses', 'cli_bcClasses'
@@ -252,26 +244,3 @@ RepoArtifacts.sourcesJar(project) {
} }
RepoArtifacts.javadocJar(project) RepoArtifacts.javadocJar(project)
/*
Configure 'test' task
*/
TasksKt.projectTest(project, JUnitMode.JUnit5)
tasks {
test {
useJUnitPlatform()
dependsOn ':kotlin-native:dist'
systemProperty("org.jetbrains.kotlin.native.home", distDir.canonicalPath)
workingDir(rootProject.projectDir)
}
}
kotlin {
target {
compilations {
test.associateWith(compiler)
}
}
}
@@ -0,0 +1,93 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.backend.konan
import org.jetbrains.kotlin.backend.konan.ir.getSuperClassNotAny
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrProperty
import org.jetbrains.kotlin.ir.declarations.inlineClassRepresentation
import org.jetbrains.kotlin.ir.declarations.isSingleFieldValueClass
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
import org.jetbrains.kotlin.ir.symbols.IrScriptSymbol
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.classifierOrFail
import org.jetbrains.kotlin.ir.types.isNullable
import org.jetbrains.kotlin.ir.types.makeNullable
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.utils.atMostOne
fun IrType.getInlinedClassNative(): IrClass? = IrTypeInlineClassesSupport.getInlinedClass(this)
fun IrType.isInlinedNative(): Boolean = IrTypeInlineClassesSupport.isInlined(this)
fun IrClass.isInlined(): Boolean = IrTypeInlineClassesSupport.isInlined(this)
fun IrClass.isNativePrimitiveType() = IrTypeInlineClassesSupport.isTopLevelClass(this) &&
KonanPrimitiveType.byFqNameParts[packageFqName]?.get(name) != null
fun IrType.computePrimitiveBinaryTypeOrNull(): PrimitiveBinaryType? =
this.computeBinaryType().primitiveBinaryTypeOrNull()
fun IrType.computeBinaryType(): BinaryType<IrClass> = IrTypeInlineClassesSupport.computeBinaryType(this)
fun IrClass.inlinedClassIsNullable(): Boolean = this.defaultType.makeNullable().getInlinedClassNative() == this // TODO: optimize
fun IrClass.isUsedAsBoxClass(): Boolean = IrTypeInlineClassesSupport.isUsedAsBoxClass(this)
fun IrType.binaryTypeIsReference(): Boolean = this.computePrimitiveBinaryTypeOrNull() == null
internal inline fun <R> IrType.unwrapToPrimitiveOrReference(
eachInlinedClass: (inlinedClass: IrClass, nullable: Boolean) -> Unit,
ifPrimitive: (primitiveType: KonanPrimitiveType, nullable: Boolean) -> R,
ifReference: (type: IrType) -> R
): R = IrTypeInlineClassesSupport.unwrapToPrimitiveOrReference(this, eachInlinedClass, ifPrimitive, ifReference)
internal object IrTypeInlineClassesSupport : InlineClassesSupport<IrClass, IrType>() {
override fun isNullable(type: IrType): Boolean = type.isNullable()
override fun makeNullable(type: IrType): IrType = type.makeNullable()
override tailrec fun erase(type: IrType): IrClass {
val classifier = type.classifierOrFail
return when (classifier) {
is IrClassSymbol -> classifier.owner
is IrTypeParameterSymbol -> erase(classifier.owner.superTypes.first())
else -> error(classifier)
}
}
override fun computeFullErasure(type: IrType): Sequence<IrClass> = when (val classifier = type.classifierOrFail) {
is IrClassSymbol -> sequenceOf(classifier.owner)
is IrTypeParameterSymbol -> classifier.owner.superTypes.asSequence().flatMap { computeFullErasure(it) }
is IrScriptSymbol -> classifier.unexpectedSymbolKind<IrClassifierSymbol>()
}
override fun hasInlineModifier(clazz: IrClass): Boolean = clazz.isSingleFieldValueClass
override fun getNativePointedSuperclass(clazz: IrClass): IrClass? {
var superClass: IrClass? = clazz
while (superClass != null && InteropFqNames.nativePointed.toSafe() != superClass.fqNameWhenAvailable)
superClass = superClass.getSuperClassNotAny()
return superClass
}
override fun getInlinedClassUnderlyingType(clazz: IrClass): IrType =
clazz.constructors.firstOrNull { it.isPrimary }?.valueParameters?.single()?.type
?: clazz.declarations.filterIsInstance<IrProperty>().atMostOne { it.backingField?.takeUnless { it.isStatic } != null }?.backingField?.type
?: clazz.inlineClassRepresentation!!.underlyingType
override fun getPackageFqName(clazz: IrClass) =
clazz.packageFqName
override fun getName(clazz: IrClass): Name? =
clazz.name
override fun isTopLevelClass(clazz: IrClass): Boolean = clazz.isTopLevel
}
@@ -41,31 +41,6 @@ internal val IrFunction.isTypedIntrinsic: Boolean
internal val IrConstructor.isConstantConstructorIntrinsic: Boolean internal val IrConstructor.isConstantConstructorIntrinsic: Boolean
get() = annotations.hasAnnotation(KonanFqNames.constantConstructorIntrinsic) get() = annotations.hasAnnotation(KonanFqNames.constantConstructorIntrinsic)
internal val arrayTypes = setOf(
"kotlin.Array",
"kotlin.ByteArray",
"kotlin.CharArray",
"kotlin.ShortArray",
"kotlin.IntArray",
"kotlin.LongArray",
"kotlin.FloatArray",
"kotlin.DoubleArray",
"kotlin.BooleanArray",
"kotlin.native.ImmutableBlob",
"kotlin.native.internal.NativePtrArray"
)
internal val arraysWithFixedSizeItems = setOf(
"kotlin.ByteArray",
"kotlin.CharArray",
"kotlin.ShortArray",
"kotlin.IntArray",
"kotlin.LongArray",
"kotlin.FloatArray",
"kotlin.DoubleArray",
"kotlin.BooleanArray"
)
internal val IrClass.isArray: Boolean internal val IrClass.isArray: Boolean
get() = this.fqNameForIrSerialization.asString() in arrayTypes get() = this.fqNameForIrSerialization.asString() in arrayTypes
@@ -1075,10 +1075,10 @@ private fun ObjCExportCodeGenerator.generateObjCImp(
is MethodBridge.ReturnValue.Mapped -> if (LLVMTypeOf(targetResult!!) == llvm.voidType) { is MethodBridge.ReturnValue.Mapped -> if (LLVMTypeOf(targetResult!!) == llvm.voidType) {
returnBridge.bridge.makeNothing(llvm) returnBridge.bridge.makeNothing(llvm)
} else { } else {
when (returnBridge.bridge) { when (val bridge = returnBridge.bridge) {
is ReferenceBridge -> return autoreleaseAndRet(kotlinReferenceToRetainedObjC(targetResult)) is ReferenceBridge -> return autoreleaseAndRet(kotlinReferenceToRetainedObjC(targetResult))
is BlockPointerBridge -> return autoreleaseAndRet(kotlinFunctionToRetainedObjCBlockPointer(returnBridge.bridge, targetResult)) is BlockPointerBridge -> return autoreleaseAndRet(kotlinFunctionToRetainedObjCBlockPointer(bridge, targetResult))
is ValueTypeBridge -> kotlinToObjC(targetResult, returnBridge.bridge.objCValueType) is ValueTypeBridge -> kotlinToObjC(targetResult, bridge.objCValueType)
} }
} }
MethodBridge.ReturnValue.WithError.Success -> llvm.int8(1) // true MethodBridge.ReturnValue.WithError.Success -> llvm.int8(1) // true
@@ -1198,11 +1198,11 @@ private fun ObjCExportCodeGenerator.generateKotlinToObjCBridge(
if (LLVMTypeOf(kotlinValue) == llvm.voidType) { if (LLVMTypeOf(kotlinValue) == llvm.voidType) {
bridge.bridge.makeNothing(llvm) bridge.bridge.makeNothing(llvm)
} else { } else {
when (bridge.bridge) { when (val typeBridge = bridge.bridge) {
is ReferenceBridge -> kotlinReferenceToRetainedObjC(kotlinValue).also { objCReferenceArgsToRelease += it } is ReferenceBridge -> kotlinReferenceToRetainedObjC(kotlinValue).also { objCReferenceArgsToRelease += it }
is BlockPointerBridge -> kotlinFunctionToRetainedObjCBlockPointer(bridge.bridge, kotlinValue) // TODO: use stack-allocated block here. is BlockPointerBridge -> kotlinFunctionToRetainedObjCBlockPointer(typeBridge, kotlinValue) // TODO: use stack-allocated block here.
.also { objCReferenceArgsToRelease += it } .also { objCReferenceArgsToRelease += it }
is ValueTypeBridge -> kotlinToObjC(kotlinValue, bridge.bridge.objCValueType) is ValueTypeBridge -> kotlinToObjC(kotlinValue, typeBridge.objCValueType)
} }
} }
} }
@@ -2006,3 +2006,26 @@ private fun NativeGenerationState.is64BitNSInteger(): Boolean {
} }
return llvm.nsIntegerTypeWidth == 64L return llvm.nsIntegerTypeWidth == 64L
} }
private fun MethodBridge.parametersAssociated(
irFunction: IrFunction
): List<Pair<MethodBridgeParameter, IrValueParameter?>> {
val kotlinParameters = irFunction.allParameters.iterator()
return this.paramBridges.map {
when (it) {
is MethodBridgeValueParameter.Mapped,
MethodBridgeReceiver.Instance,
is MethodBridgeValueParameter.SuspendCompletion ->
it to kotlinParameters.next()
MethodBridgeReceiver.Static, MethodBridgeSelector, MethodBridgeValueParameter.ErrorOutParameter ->
it to null
MethodBridgeReceiver.Factory -> {
kotlinParameters.next()
it to null
}
}
}.also { assert(!kotlinParameters.hasNext()) }
}
@@ -0,0 +1,20 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.backend.konan.llvm.objcexport
import org.jetbrains.kotlin.backend.konan.llvm.LlvmParameterAttribute
import org.jetbrains.kotlin.backend.konan.objcexport.*
internal val ObjCValueType.defaultParameterAttributes: List<LlvmParameterAttribute>
get() = when (this) {
ObjCValueType.BOOL -> listOf(LlvmParameterAttribute.SignExt)
ObjCValueType.UNICHAR -> listOf(LlvmParameterAttribute.ZeroExt)
ObjCValueType.CHAR -> listOf(LlvmParameterAttribute.SignExt)
ObjCValueType.SHORT -> listOf(LlvmParameterAttribute.SignExt)
ObjCValueType.UNSIGNED_CHAR -> listOf(LlvmParameterAttribute.ZeroExt)
ObjCValueType.UNSIGNED_SHORT -> listOf(LlvmParameterAttribute.ZeroExt)
else -> emptyList()
}
@@ -11,14 +11,15 @@ import org.jetbrains.kotlin.backend.konan.driver.PhaseContext
import org.jetbrains.kotlin.backend.konan.llvm.CodeGenerator import org.jetbrains.kotlin.backend.konan.llvm.CodeGenerator
import org.jetbrains.kotlin.backend.konan.llvm.objcexport.ObjCExportBlockCodeGenerator import org.jetbrains.kotlin.backend.konan.llvm.objcexport.ObjCExportBlockCodeGenerator
import org.jetbrains.kotlin.backend.konan.llvm.objcexport.ObjCExportCodeGenerator import org.jetbrains.kotlin.backend.konan.llvm.objcexport.ObjCExportCodeGenerator
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.cli.common.messages.MessageUtil
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.SourceFile
import org.jetbrains.kotlin.konan.exec.Command import org.jetbrains.kotlin.konan.exec.Command
import org.jetbrains.kotlin.konan.file.File import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.file.createTempFile import org.jetbrains.kotlin.konan.file.createTempFile
import org.jetbrains.kotlin.konan.target.CompilerOutputKind import org.jetbrains.kotlin.konan.target.CompilerOutputKind
import org.jetbrains.kotlin.renderer.DescriptorRenderer
import org.jetbrains.kotlin.resolve.source.getPsi
internal class ObjCExportedInterface( internal class ObjCExportedInterface(
val generatedClasses: Set<ClassDescriptor>, val generatedClasses: Set<ClassDescriptor>,
@@ -52,7 +53,7 @@ internal fun produceObjCExportInterface(
val ignoreInterfaceMethodCollisions = config.configuration.getBoolean(BinaryOptions.objcExportIgnoreInterfaceMethodCollisions) val ignoreInterfaceMethodCollisions = config.configuration.getBoolean(BinaryOptions.objcExportIgnoreInterfaceMethodCollisions)
val reportNameCollisions = config.configuration.getBoolean(BinaryOptions.objcExportReportNameCollisions) val reportNameCollisions = config.configuration.getBoolean(BinaryOptions.objcExportReportNameCollisions)
val problemCollector = ObjCExportHeaderGeneratorImpl.ProblemCollector(context) val problemCollector = ObjCExportCompilerProblemCollector(context)
val namer = ObjCExportNamerImpl( val namer = ObjCExportNamerImpl(
moduleDescriptors.toSet(), moduleDescriptors.toSet(),
@@ -66,11 +67,36 @@ internal fun produceObjCExportInterface(
ignoreInterfaceMethodCollisions = ignoreInterfaceMethodCollisions, ignoreInterfaceMethodCollisions = ignoreInterfaceMethodCollisions,
reportNameCollisions = reportNameCollisions, reportNameCollisions = reportNameCollisions,
) )
val headerGenerator = ObjCExportHeaderGeneratorImpl(context, moduleDescriptors, mapper, namer, problemCollector, objcGenerics) val shouldExportKDoc = context.shouldExportKDoc()
val additionalImports = context.config.configuration.getNotNull(KonanConfigKeys.FRAMEWORK_IMPORT_HEADERS)
val headerGenerator = ObjCExportHeaderGenerator.createInstance(
moduleDescriptors, mapper, namer, problemCollector, objcGenerics, shouldExportKDoc = shouldExportKDoc,
additionalImports = additionalImports)
headerGenerator.translateModule() headerGenerator.translateModule()
return headerGenerator.buildInterface() return headerGenerator.buildInterface()
} }
private class ObjCExportCompilerProblemCollector(val context: PhaseContext) : ObjCExportProblemCollector {
override fun reportWarning(text: String) {
context.reportCompilationWarning(text)
}
override fun reportWarning(declaration: DeclarationDescriptor, text: String) {
val psi = (declaration as? DeclarationDescriptorWithSource)?.source?.getPsi()
?: return reportWarning(
"$text\n (at ${DescriptorRenderer.COMPACT_WITH_SHORT_TYPES.render(declaration)})"
)
val location = MessageUtil.psiElementToMessageLocation(psi)
context.messageCollector.report(CompilerMessageSeverity.WARNING, text, location)
}
override fun reportException(throwable: Throwable) {
throw throwable
}
}
/** /**
* Populate framework directory with headers, module and info.plist. * Populate framework directory with headers, module and info.plist.
*/ */
@@ -189,3 +215,6 @@ private fun ObjCExportedInterface.generateWorkaroundForSwiftSR10177(generationSt
// In this case resulting framework will likely be unusable due to compile errors when importing it. // In this case resulting framework will likely be unusable due to compile errors when importing it.
} }
} }
internal val PhaseContext.objCExportTopLevelNamePrefix: String
get() = abbreviate(config.fullExportedNamePrefix)
+2
View File
@@ -165,6 +165,8 @@ dependencies {
distPack project(':kotlin-native:Interop:StubGenerator') distPack project(':kotlin-native:Interop:StubGenerator')
distPack project(':kotlin-native:Interop:Skia') distPack project(':kotlin-native:Interop:Skia')
distPack project(':kotlin-native:backend.native') distPack project(':kotlin-native:backend.native')
distPack project(':native:objcexport-header-generator')
distPack project(':native:base')
distPack project(':kotlin-native:utilities:cli-runner') distPack project(':kotlin-native:utilities:cli-runner')
distPack project(':kotlin-native:utilities:basic-utils') distPack project(':kotlin-native:utilities:basic-utils')
distPack project(':kotlin-native:klib') distPack project(':kotlin-native:klib')
+16
View File
@@ -0,0 +1,16 @@
plugins {
kotlin("jvm")
}
dependencies {
implementation(project(":compiler:cli-base"))
implementation(project(":compiler:cli-common"))
implementation(project(":core:compiler.common.native"))
implementation(project(":core:descriptors"))
}
kotlin {
compilerOptions {
optIn.add("org.jetbrains.kotlin.backend.konan.InternalKotlinNativeApi")
}
}
@@ -1,29 +1,14 @@
/* /*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* that can be found in the LICENSE file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package org.jetbrains.kotlin.backend.konan package org.jetbrains.kotlin.backend.konan
import org.jetbrains.kotlin.utils.atMostOne
import org.jetbrains.kotlin.descriptors.findPackage
import org.jetbrains.kotlin.backend.konan.ir.getSuperClassNotAny
import org.jetbrains.kotlin.builtins.PrimitiveType import org.jetbrains.kotlin.builtins.PrimitiveType
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.descriptors.findPackage
import org.jetbrains.kotlin.ir.declarations.IrProperty
import org.jetbrains.kotlin.ir.declarations.inlineClassRepresentation
import org.jetbrains.kotlin.ir.declarations.isSingleFieldValueClass
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
import org.jetbrains.kotlin.ir.symbols.IrScriptSymbol
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.classifierOrFail
import org.jetbrains.kotlin.ir.types.isNullable
import org.jetbrains.kotlin.ir.types.makeNullable
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.FqNameUnsafe import org.jetbrains.kotlin.name.FqNameUnsafe
@@ -35,12 +20,6 @@ import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.isNullable import org.jetbrains.kotlin.types.isNullable
import org.jetbrains.kotlin.types.typeUtil.makeNullable import org.jetbrains.kotlin.types.typeUtil.makeNullable
fun IrType.getInlinedClassNative(): IrClass? = IrTypeInlineClassesSupport.getInlinedClass(this)
fun IrType.isInlinedNative(): Boolean = IrTypeInlineClassesSupport.isInlined(this)
fun IrClass.isInlined(): Boolean = IrTypeInlineClassesSupport.isInlined(this)
fun IrClass.isNativePrimitiveType() = IrTypeInlineClassesSupport.isTopLevelClass(this) &&
KonanPrimitiveType.byFqNameParts[packageFqName]?.get(name) != null
fun KotlinType.getInlinedClass(): ClassDescriptor? = KotlinTypeInlineClassesSupport.getInlinedClass(this) fun KotlinType.getInlinedClass(): ClassDescriptor? = KotlinTypeInlineClassesSupport.getInlinedClass(this)
@@ -48,35 +27,22 @@ fun ClassDescriptor.isInlined(): Boolean = KotlinTypeInlineClassesSupport.isInli
fun KotlinType.binaryRepresentationIsNullable() = KotlinTypeInlineClassesSupport.representationIsNullable(this) fun KotlinType.binaryRepresentationIsNullable() = KotlinTypeInlineClassesSupport.representationIsNullable(this)
internal inline fun <R> KotlinType.unwrapToPrimitiveOrReference( @InternalKotlinNativeApi
inline fun <R> KotlinType.unwrapToPrimitiveOrReference(
eachInlinedClass: (inlinedClass: ClassDescriptor, nullable: Boolean) -> Unit, eachInlinedClass: (inlinedClass: ClassDescriptor, nullable: Boolean) -> Unit,
ifPrimitive: (primitiveType: KonanPrimitiveType, nullable: Boolean) -> R, ifPrimitive: (primitiveType: KonanPrimitiveType, nullable: Boolean) -> R,
ifReference: (type: KotlinType) -> R ifReference: (type: KotlinType) -> R
): R = KotlinTypeInlineClassesSupport.unwrapToPrimitiveOrReference(this, eachInlinedClass, ifPrimitive, ifReference) ): R = KotlinTypeInlineClassesSupport.unwrapToPrimitiveOrReference(this, eachInlinedClass, ifPrimitive, ifReference)
internal inline fun <R> IrType.unwrapToPrimitiveOrReference(
eachInlinedClass: (inlinedClass: IrClass, nullable: Boolean) -> Unit,
ifPrimitive: (primitiveType: KonanPrimitiveType, nullable: Boolean) -> R,
ifReference: (type: IrType) -> R
): R = IrTypeInlineClassesSupport.unwrapToPrimitiveOrReference(this, eachInlinedClass, ifPrimitive, ifReference)
// TODO: consider renaming to `isReference`. // TODO: consider renaming to `isReference`.
fun KotlinType.binaryTypeIsReference(): Boolean = this.computePrimitiveBinaryTypeOrNull() == null fun KotlinType.binaryTypeIsReference(): Boolean = this.computePrimitiveBinaryTypeOrNull() == null
fun IrType.binaryTypeIsReference(): Boolean = this.computePrimitiveBinaryTypeOrNull() == null
fun KotlinType.computePrimitiveBinaryTypeOrNull(): PrimitiveBinaryType? = fun KotlinType.computePrimitiveBinaryTypeOrNull(): PrimitiveBinaryType? =
this.computeBinaryType().primitiveBinaryTypeOrNull() this.computeBinaryType().primitiveBinaryTypeOrNull()
fun KotlinType.computeBinaryType(): BinaryType<ClassDescriptor> = KotlinTypeInlineClassesSupport.computeBinaryType(this) fun KotlinType.computeBinaryType(): BinaryType<ClassDescriptor> = KotlinTypeInlineClassesSupport.computeBinaryType(this)
fun IrType.computePrimitiveBinaryTypeOrNull(): PrimitiveBinaryType? =
this.computeBinaryType().primitiveBinaryTypeOrNull()
fun IrType.computeBinaryType(): BinaryType<IrClass> = IrTypeInlineClassesSupport.computeBinaryType(this)
fun IrClass.inlinedClassIsNullable(): Boolean = this.defaultType.makeNullable().getInlinedClassNative() == this // TODO: optimize
fun IrClass.isUsedAsBoxClass(): Boolean = IrTypeInlineClassesSupport.isUsedAsBoxClass(this)
/** /**
* Most "underlying" user-visible non-reference type. * Most "underlying" user-visible non-reference type.
* It is visible as inlined to compiler for simplicity. * It is visible as inlined to compiler for simplicity.
@@ -114,14 +80,18 @@ enum class KonanPrimitiveType(val classId: ClassId, val binaryType: BinaryType.P
} }
} }
internal abstract class InlineClassesSupport<Class : Any, Type : Any> { @InternalKotlinNativeApi
protected abstract fun isNullable(type: Type): Boolean abstract class InlineClassesSupport<Class : Any, Type : Any> {
protected abstract fun makeNullable(type: Type): Type @InternalKotlinNativeApi
abstract fun isNullable(type: Type): Boolean
@InternalKotlinNativeApi
abstract fun makeNullable(type: Type): Type
protected abstract fun erase(type: Type): Class protected abstract fun erase(type: Type): Class
protected abstract fun computeFullErasure(type: Type): Sequence<Class> protected abstract fun computeFullErasure(type: Type): Sequence<Class>
protected abstract fun hasInlineModifier(clazz: Class): Boolean protected abstract fun hasInlineModifier(clazz: Class): Boolean
protected abstract fun getNativePointedSuperclass(clazz: Class): Class? protected abstract fun getNativePointedSuperclass(clazz: Class): Class?
protected abstract fun getInlinedClassUnderlyingType(clazz: Class): Type @InternalKotlinNativeApi
abstract fun getInlinedClassUnderlyingType(clazz: Class): Type
protected abstract fun getPackageFqName(clazz: Class): FqName? protected abstract fun getPackageFqName(clazz: Class): FqName?
protected abstract fun getName(clazz: Class): Name? protected abstract fun getName(clazz: Class): Name?
abstract fun isTopLevelClass(clazz: Class): Boolean abstract fun isTopLevelClass(clazz: Class): Boolean
@@ -135,15 +105,17 @@ internal abstract class InlineClassesSupport<Class : Any, Type : Any> {
fun getInlinedClass(type: Type): Class? = fun getInlinedClass(type: Type): Class? =
getInlinedClass(erase(type), isNullable(type)) getInlinedClass(erase(type), isNullable(type))
protected fun getKonanPrimitiveType(clazz: Class): KonanPrimitiveType? = @InternalKotlinNativeApi
fun getKonanPrimitiveType(clazz: Class): KonanPrimitiveType? =
if (isTopLevelClass(clazz)) if (isTopLevelClass(clazz))
KonanPrimitiveType.byFqNameParts[getPackageFqName(clazz)]?.get(getName(clazz)) KonanPrimitiveType.byFqNameParts[getPackageFqName(clazz)]?.get(getName(clazz))
else null else null
protected fun isImplicitInlineClass(clazz: Class): Boolean = @InternalKotlinNativeApi
isTopLevelClass(clazz) && (getKonanPrimitiveType(clazz) != null || fun isImplicitInlineClass(clazz: Class): Boolean =
getName(clazz) == KonanFqNames.nativePtr.shortName() && getPackageFqName(clazz) == KonanFqNames.internalPackageName || isTopLevelClass(clazz) && (getKonanPrimitiveType(clazz) != null ||
getName(clazz) == InteropFqNames.cPointer.shortName() && getPackageFqName(clazz) == InteropFqNames.cPointer.parent().toSafe()) getName(clazz) == KonanFqNames.nativePtr.shortName() && getPackageFqName(clazz) == KonanFqNames.internalPackageName ||
getName(clazz) == InteropFqNames.cPointer.shortName() && getPackageFqName(clazz) == InteropFqNames.cPointer.parent().toSafe())
private fun getInlinedClass(erased: Class, isNullable: Boolean): Class? { private fun getInlinedClass(erased: Class, isNullable: Boolean): Class? {
val inlinedClass = getInlinedClass(erased) ?: return null val inlinedClass = getInlinedClass(erased) ?: return null
@@ -194,7 +166,7 @@ internal abstract class InlineClassesSupport<Class : Any, Type : Any> {
val nullable = isNullable(currentType) val nullable = isNullable(currentType)
getKonanPrimitiveType(inlinedClass)?.let { primitiveType -> getKonanPrimitiveType(inlinedClass)?.let { primitiveType ->
return ifPrimitive(primitiveType, nullable) return ifPrimitive(primitiveType, nullable)
} }
@@ -235,7 +207,8 @@ internal abstract class InlineClassesSupport<Class : Any, Type : Any> {
BinaryType.Reference(computeFullErasure(type), true) BinaryType.Reference(computeFullErasure(type), true)
} }
internal object KotlinTypeInlineClassesSupport : InlineClassesSupport<ClassDescriptor, KotlinType>() { @InternalKotlinNativeApi
object KotlinTypeInlineClassesSupport : InlineClassesSupport<ClassDescriptor, KotlinType>() {
override fun isNullable(type: KotlinType): Boolean = type.isNullable() override fun isNullable(type: KotlinType): Boolean = type.isNullable()
override fun makeNullable(type: KotlinType): KotlinType = type.makeNullable() override fun makeNullable(type: KotlinType): KotlinType = type.makeNullable()
@@ -271,46 +244,3 @@ internal object KotlinTypeInlineClassesSupport : InlineClassesSupport<ClassDescr
override fun isTopLevelClass(clazz: ClassDescriptor): Boolean = clazz.containingDeclaration is PackageFragmentDescriptor override fun isTopLevelClass(clazz: ClassDescriptor): Boolean = clazz.containingDeclaration is PackageFragmentDescriptor
} }
internal object IrTypeInlineClassesSupport : InlineClassesSupport<IrClass, IrType>() {
override fun isNullable(type: IrType): Boolean = type.isNullable()
override fun makeNullable(type: IrType): IrType = type.makeNullable()
override tailrec fun erase(type: IrType): IrClass {
val classifier = type.classifierOrFail
return when (classifier) {
is IrClassSymbol -> classifier.owner
is IrTypeParameterSymbol -> erase(classifier.owner.superTypes.first())
else -> error(classifier)
}
}
override fun computeFullErasure(type: IrType): Sequence<IrClass> = when (val classifier = type.classifierOrFail) {
is IrClassSymbol -> sequenceOf(classifier.owner)
is IrTypeParameterSymbol -> classifier.owner.superTypes.asSequence().flatMap { computeFullErasure(it) }
is IrScriptSymbol -> classifier.unexpectedSymbolKind<IrClassifierSymbol>()
}
override fun hasInlineModifier(clazz: IrClass): Boolean = clazz.isSingleFieldValueClass
override fun getNativePointedSuperclass(clazz: IrClass): IrClass? {
var superClass: IrClass? = clazz
while (superClass != null && InteropFqNames.nativePointed.toSafe() != superClass.fqNameWhenAvailable)
superClass = superClass.getSuperClassNotAny()
return superClass
}
override fun getInlinedClassUnderlyingType(clazz: IrClass): IrType =
clazz.constructors.firstOrNull { it.isPrimary }?.valueParameters?.single()?.type
?: clazz.declarations.filterIsInstance<IrProperty>().atMostOne { it.backingField?.takeUnless { it.isStatic } != null }?.backingField?.type
?: clazz.inlineClassRepresentation!!.underlyingType
override fun getPackageFqName(clazz: IrClass) =
clazz.packageFqName
override fun getName(clazz: IrClass): Name? =
clazz.name
override fun isTopLevelClass(clazz: IrClass): Boolean = clazz.isTopLevel
}
@@ -0,0 +1,17 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.backend.konan
/**
* This annotation is used to mark APIs as 'internal' to Kotlin/Native across modules within kotlin.git.
* Note: Any API with this annotation can be changed and potentially removed at any time.
* It is not safe to depend on any internal Kotlin/Native API outside kotlin.git/kotlin-native
*/
@RequiresOptIn(
"This API is internal to the Kotlin/Native compiler and cannot be used outside of kotlin.git",
level = RequiresOptIn.Level.ERROR
)
annotation class InternalKotlinNativeApi
@@ -1,6 +1,6 @@
/* /*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* that can be found in the LICENSE file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package org.jetbrains.kotlin.backend.konan package org.jetbrains.kotlin.backend.konan
@@ -95,7 +95,8 @@ object InteropFqNames {
private fun FqName.child(nameIdent: String) = child(Name.identifier(nameIdent)) private fun FqName.child(nameIdent: String) = child(Name.identifier(nameIdent))
internal class InteropBuiltIns(builtIns: KonanBuiltIns) { @InternalKotlinNativeApi
class InteropBuiltIns(builtIns: KonanBuiltIns) {
private val packageScope = builtIns.builtInsModule.getPackage(InteropFqNames.packageName).memberScope private val packageScope = builtIns.builtInsModule.getPackage(InteropFqNames.packageName).memberScope
@@ -113,43 +114,3 @@ internal fun MemberScope.getContributedClass(name: String): ClassDescriptor =
private fun MemberScope.getContributedFunctions(name: String) = private fun MemberScope.getContributedFunctions(name: String) =
this.getContributedFunctions(Name.identifier(name), NoLookupLocation.FROM_BUILTINS) this.getContributedFunctions(Name.identifier(name), NoLookupLocation.FROM_BUILTINS)
internal val cKeywords = setOf(
// Actual C keywords.
"auto", "break", "case",
"char", "const", "continue",
"default", "do", "double",
"else", "enum", "extern",
"float", "for", "goto",
"if", "int", "long",
"register", "return",
"short", "signed", "sizeof", "static", "struct", "switch",
"typedef", "union", "unsigned",
"void", "volatile", "while",
// C99-specific.
"_Bool", "_Complex", "_Imaginary", "inline", "restrict",
// C11-specific.
"_Alignas", "_Alignof", "_Atomic", "_Generic", "_Noreturn", "_Static_assert", "_Thread_local",
// Not exactly keywords, but reserved or standard-defined.
"and", "not", "or", "xor",
"bool", "complex", "imaginary",
// C++ keywords not listed above.
"alignas", "alignof", "and_eq", "asm",
"bitand", "bitor", "bool",
"catch", "char16_t", "char32_t", "class", "compl", "constexpr", "const_cast",
"decltype", "delete", "dynamic_cast",
"explicit", "export",
"false", "friend",
"inline",
"mutable",
"namespace", "new", "noexcept", "not_eq", "nullptr",
"operator", "or_eq",
"private", "protected", "public",
"reinterpret_cast",
"static_assert",
"template", "this", "thread_local", "throw", "true", "try", "typeid", "typename",
"using",
"virtual",
"wchar_t",
"xor_eq"
)
@@ -1,6 +1,6 @@
/* /*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* that can be found in the LICENSE file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package org.jetbrains.kotlin.backend.konan package org.jetbrains.kotlin.backend.konan
@@ -9,9 +9,14 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.NativeRuntimeNames import org.jetbrains.kotlin.name.NativeRuntimeNames
internal const val NATIVE_PTR_NAME = "NativePtr" @InternalKotlinNativeApi
internal const val NON_NULL_NATIVE_PTR_NAME = "NonNullNativePtr" const val NATIVE_PTR_NAME = "NativePtr"
internal const val IMMUTABLE_BLOB_OF = "immutableBlobOf"
@InternalKotlinNativeApi
const val NON_NULL_NATIVE_PTR_NAME = "NonNullNativePtr"
@InternalKotlinNativeApi
const val IMMUTABLE_BLOB_OF = "immutableBlobOf"
object KonanFqNames { object KonanFqNames {
val function = FqName("kotlin.Function") val function = FqName("kotlin.Function")
@@ -0,0 +1,48 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.backend.konan
@InternalKotlinNativeApi
val cKeywords = setOf(
// Actual C keywords.
"auto", "break", "case",
"char", "const", "continue",
"default", "do", "double",
"else", "enum", "extern",
"float", "for", "goto",
"if", "int", "long",
"register", "return",
"short", "signed", "sizeof", "static", "struct", "switch",
"typedef", "union", "unsigned",
"void", "volatile", "while",
// C99-specific.
"_Bool", "_Complex", "_Imaginary", "inline", "restrict",
// C11-specific.
"_Alignas", "_Alignof", "_Atomic", "_Generic", "_Noreturn", "_Static_assert", "_Thread_local",
// Not exactly keywords, but reserved or standard-defined.
"and", "not", "or", "xor",
"bool", "complex", "imaginary",
// C++ keywords not listed above.
"alignas", "alignof", "and_eq", "asm",
"bitand", "bitor", "bool",
"catch", "char16_t", "char32_t", "class", "compl", "constexpr", "const_cast",
"decltype", "delete", "dynamic_cast",
"explicit", "export",
"false", "friend",
"inline",
"mutable",
"namespace", "new", "noexcept", "not_eq", "nullptr",
"operator", "or_eq",
"private", "protected", "public",
"reinterpret_cast",
"static_assert",
"template", "this", "thread_local", "throw", "true", "try", "typeid", "typename",
"using",
"virtual",
"wchar_t",
"xor_eq"
)
@@ -1,10 +1,11 @@
/* /*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* that can be found in the LICENSE file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package org.jetbrains.kotlin.backend.konan.descriptors package org.jetbrains.kotlin.backend.konan.descriptors
import org.jetbrains.kotlin.backend.konan.InternalKotlinNativeApi
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
@@ -20,7 +21,8 @@ import org.jetbrains.kotlin.types.typeUtil.isUnit
* *
* TODO: this method is actually a part of resolve and probably duplicates another one * TODO: this method is actually a part of resolve and probably duplicates another one
*/ */
internal fun <T : CallableMemberDescriptor> T.resolveFakeOverride(allowAbstract: Boolean = false): T { @InternalKotlinNativeApi
fun <T : CallableMemberDescriptor> T.resolveFakeOverride(allowAbstract: Boolean = false): T {
if (this.kind.isReal) { if (this.kind.isReal) {
return this return this
} else { } else {
@@ -32,19 +34,24 @@ internal fun <T : CallableMemberDescriptor> T.resolveFakeOverride(allowAbstract:
} }
} }
internal val ClassDescriptor.isArray: Boolean @InternalKotlinNativeApi
val ClassDescriptor.isArray: Boolean
get() = this.fqNameSafe.asString() in arrayTypes get() = this.fqNameSafe.asString() in arrayTypes
internal val ClassDescriptor.isInterface: Boolean @InternalKotlinNativeApi
val ClassDescriptor.isInterface: Boolean
get() = (this.kind == ClassKind.INTERFACE) get() = (this.kind == ClassKind.INTERFACE)
internal fun ClassDescriptor.isUnit() = this.defaultType.isUnit() @InternalKotlinNativeApi
fun ClassDescriptor.isUnit() = this.defaultType.isUnit()
internal fun ClassDescriptor.isNothing() = this.defaultType.isNothing() @InternalKotlinNativeApi
fun ClassDescriptor.isNothing() = this.defaultType.isNothing()
internal val <T : CallableMemberDescriptor> T.allOverriddenDescriptors: List<T> @InternalKotlinNativeApi
val <T : CallableMemberDescriptor> T.allOverriddenDescriptors: List<T>
get() { get() {
val result = mutableListOf<T>() val result = mutableListOf<T>()
fun traverse(descriptor: T) { fun traverse(descriptor: T) {
@@ -56,11 +63,13 @@ internal val <T : CallableMemberDescriptor> T.allOverriddenDescriptors: List<T>
return result return result
} }
internal val ClassDescriptor.contributedMethods: List<FunctionDescriptor> @InternalKotlinNativeApi
get () = unsubstitutedMemberScope.contributedMethods val ClassDescriptor.contributedMethods: List<FunctionDescriptor>
get() = unsubstitutedMemberScope.contributedMethods
internal val MemberScope.contributedMethods: List<FunctionDescriptor> @InternalKotlinNativeApi
get () { val MemberScope.contributedMethods: List<FunctionDescriptor>
get() {
val contributedDescriptors = this.getContributedDescriptors() val contributedDescriptors = this.getContributedDescriptors()
val functions = contributedDescriptors.filterIsInstance<FunctionDescriptor>() val functions = contributedDescriptors.filterIsInstance<FunctionDescriptor>()
@@ -74,15 +83,18 @@ internal val MemberScope.contributedMethods: List<FunctionDescriptor>
fun ClassDescriptor.isAbstract() = this.modality == Modality.SEALED || this.modality == Modality.ABSTRACT fun ClassDescriptor.isAbstract() = this.modality == Modality.SEALED || this.modality == Modality.ABSTRACT
internal val FunctionDescriptor.target: FunctionDescriptor @InternalKotlinNativeApi
val FunctionDescriptor.target: FunctionDescriptor
get() = (if (modality == Modality.ABSTRACT) this else resolveFakeOverride()).original get() = (if (modality == Modality.ABSTRACT) this else resolveFakeOverride()).original
internal fun DeclarationDescriptor.findPackageView(): PackageViewDescriptor { @InternalKotlinNativeApi
fun DeclarationDescriptor.findPackageView(): PackageViewDescriptor {
val packageFragment = this.findPackage() val packageFragment = this.findPackage()
return packageFragment.module.getPackage(packageFragment.fqName) return packageFragment.module.getPackage(packageFragment.fqName)
} }
internal fun DeclarationDescriptor.allContainingDeclarations(): List<DeclarationDescriptor> { @InternalKotlinNativeApi
fun DeclarationDescriptor.allContainingDeclarations(): List<DeclarationDescriptor> {
var list = mutableListOf<DeclarationDescriptor>() var list = mutableListOf<DeclarationDescriptor>()
var current = this.containingDeclaration var current = this.containingDeclaration
while (current != null) { while (current != null) {
@@ -120,5 +132,33 @@ val ClassDescriptor.enumEntries: List<ClassDescriptor>
.filter { it.kind == ClassKind.ENUM_ENTRY } .filter { it.kind == ClassKind.ENUM_ENTRY }
} }
internal val DeclarationDescriptor.isExpectMember: Boolean @InternalKotlinNativeApi
val DeclarationDescriptor.isExpectMember: Boolean
get() = this is MemberDescriptor && this.isExpect get() = this is MemberDescriptor && this.isExpect
@InternalKotlinNativeApi
val arrayTypes = setOf(
"kotlin.Array",
"kotlin.ByteArray",
"kotlin.CharArray",
"kotlin.ShortArray",
"kotlin.IntArray",
"kotlin.LongArray",
"kotlin.FloatArray",
"kotlin.DoubleArray",
"kotlin.BooleanArray",
"kotlin.native.ImmutableBlob",
"kotlin.native.internal.NativePtrArray"
)
@InternalKotlinNativeApi
val arraysWithFixedSizeItems = setOf(
"kotlin.ByteArray",
"kotlin.CharArray",
"kotlin.ShortArray",
"kotlin.IntArray",
"kotlin.LongArray",
"kotlin.FloatArray",
"kotlin.DoubleArray",
"kotlin.BooleanArray"
)
@@ -0,0 +1,2 @@
[*]
ij_continuation_indent_size = 4
@@ -0,0 +1,33 @@
plugins {
kotlin("jvm")
}
dependencies {
implementation(intellijCore())
implementation(project(":compiler:cli-base"))
implementation(project(":compiler:cli-common"))
implementation(project(":compiler:ir.objcinterop"))
implementation(project(":compiler:ir.serialization.native"))
implementation(project(":core:compiler.common.native"))
implementation(project(":core:descriptors"))
implementation(project(":native:base"))
implementation(project(":native:kotlin-native-utils"))
testImplementation(libs.junit.jupiter.api)
testImplementation(libs.junit.jupiter.params)
testImplementation(project(":compiler:tests-common", "tests-jar"))
testRuntimeOnly(libs.junit.jupiter.engine)
}
kotlin {
compilerOptions {
optIn.add("org.jetbrains.kotlin.backend.konan.InternalKotlinNativeApi")
}
}
nativeTest("test", tag = null) {
useJUnitPlatform()
systemProperty("projectDir", projectDir.absolutePath)
workingDir(rootProject.projectDir)
}
@@ -1,10 +1,11 @@
/* /*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* that can be found in the LICENSE file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package org.jetbrains.kotlin.backend.konan.objcexport package org.jetbrains.kotlin.backend.konan.objcexport
import org.jetbrains.kotlin.backend.konan.InternalKotlinNativeApi
import org.jetbrains.kotlin.builtins.StandardNames import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.builtins.functions.FunctionTypeKind import org.jetbrains.kotlin.builtins.functions.FunctionTypeKind
import org.jetbrains.kotlin.builtins.getFunctionTypeKind import org.jetbrains.kotlin.builtins.getFunctionTypeKind
@@ -15,12 +16,14 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.classId
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.TypeUtils
internal fun ClassDescriptor.isMappedFunctionClass() = @InternalKotlinNativeApi
fun ClassDescriptor.isMappedFunctionClass() =
this.getFunctionTypeKind() == FunctionTypeKind.Function && this.getFunctionTypeKind() == FunctionTypeKind.Function &&
// Type parameters include return type. // Type parameters include return type.
declaredTypeParameters.size - 1 < CustomTypeMappers.functionTypeMappersArityLimit declaredTypeParameters.size - 1 < CustomTypeMappers.functionTypeMappersArityLimit
internal interface CustomTypeMapper { @InternalKotlinNativeApi
interface CustomTypeMapper {
val mappedClassId: ClassId val mappedClassId: ClassId
fun mapType(mappedSuperType: KotlinType, translator: ObjCExportTranslatorImpl, objCExportScope: ObjCExportScope): ObjCNonNullReferenceType fun mapType(mappedSuperType: KotlinType, translator: ObjCExportTranslatorImpl, objCExportScope: ObjCExportScope): ObjCNonNullReferenceType
} }
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.backend.konan.objcexport package org.jetbrains.kotlin.backend.konan.objcexport
import org.jetbrains.kotlin.backend.konan.InternalKotlinNativeApi
import org.jetbrains.kotlin.backend.konan.descriptors.getPackageFragments import org.jetbrains.kotlin.backend.konan.descriptors.getPackageFragments
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
@@ -14,7 +15,8 @@ import org.jetbrains.kotlin.name.isSubpackageOf
* Tries to infer a main package name that can be used * Tries to infer a main package name that can be used
* for bundle ID of a framework. * for bundle ID of a framework.
*/ */
internal class MainPackageGuesser { @InternalKotlinNativeApi
class MainPackageGuesser {
fun guess( fun guess(
moduleDescriptor: ModuleDescriptor, moduleDescriptor: ModuleDescriptor,
includedLibraryDescriptors: List<ModuleDescriptor>, includedLibraryDescriptors: List<ModuleDescriptor>,
@@ -1,44 +1,55 @@
/* /*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* that can be found in the LICENSE file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package org.jetbrains.kotlin.backend.konan.objcexport package org.jetbrains.kotlin.backend.konan.objcexport
import org.jetbrains.kotlin.backend.common.descriptors.allParameters import org.jetbrains.kotlin.backend.common.descriptors.allParameters
import org.jetbrains.kotlin.backend.konan.InternalKotlinNativeApi
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.ParameterDescriptor import org.jetbrains.kotlin.descriptors.ParameterDescriptor
import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrValueParameter import org.jetbrains.kotlin.ir.declarations.IrValueParameter
import org.jetbrains.kotlin.ir.util.allParameters import org.jetbrains.kotlin.ir.util.allParameters
internal sealed class TypeBridge @InternalKotlinNativeApi
internal object ReferenceBridge : TypeBridge() sealed class TypeBridge
internal data class BlockPointerBridge( @InternalKotlinNativeApi
object ReferenceBridge : TypeBridge()
@InternalKotlinNativeApi
data class BlockPointerBridge(
val numberOfParameters: Int, val numberOfParameters: Int,
val returnsVoid: Boolean val returnsVoid: Boolean
) : TypeBridge() ) : TypeBridge()
internal data class ValueTypeBridge(val objCValueType: ObjCValueType) : TypeBridge() @InternalKotlinNativeApi
data class ValueTypeBridge(val objCValueType: ObjCValueType) : TypeBridge()
internal sealed class MethodBridgeParameter @InternalKotlinNativeApi
sealed class MethodBridgeParameter
internal sealed class MethodBridgeReceiver : MethodBridgeParameter() { @InternalKotlinNativeApi
sealed class MethodBridgeReceiver : MethodBridgeParameter() {
object Static : MethodBridgeReceiver() object Static : MethodBridgeReceiver()
object Factory : MethodBridgeReceiver() object Factory : MethodBridgeReceiver()
object Instance : MethodBridgeReceiver() object Instance : MethodBridgeReceiver()
} }
internal object MethodBridgeSelector : MethodBridgeParameter() @InternalKotlinNativeApi
object MethodBridgeSelector : MethodBridgeParameter()
internal sealed class MethodBridgeValueParameter : MethodBridgeParameter() { @InternalKotlinNativeApi
sealed class MethodBridgeValueParameter : MethodBridgeParameter() {
data class Mapped(val bridge: TypeBridge) : MethodBridgeValueParameter() data class Mapped(val bridge: TypeBridge) : MethodBridgeValueParameter()
object ErrorOutParameter : MethodBridgeValueParameter() object ErrorOutParameter : MethodBridgeValueParameter()
data class SuspendCompletion(val useUnitCompletion: Boolean) : MethodBridgeValueParameter() data class SuspendCompletion(val useUnitCompletion: Boolean) : MethodBridgeValueParameter()
} }
internal data class MethodBridge( @InternalKotlinNativeApi
data class MethodBridge(
val returnBridge: ReturnValue, val returnBridge: ReturnValue,
val receiver: MethodBridgeReceiver, val receiver: MethodBridgeReceiver,
val valueParameters: List<MethodBridgeValueParameter> val valueParameters: List<MethodBridgeValueParameter>
@@ -76,7 +87,8 @@ internal data class MethodBridge(
get() = returnBridge is ReturnValue.WithError get() = returnBridge is ReturnValue.WithError
} }
internal fun MethodBridge.valueParametersAssociated( @InternalKotlinNativeApi
fun MethodBridge.valueParametersAssociated(
descriptor: FunctionDescriptor descriptor: FunctionDescriptor
): List<Pair<MethodBridgeValueParameter, ParameterDescriptor?>> { ): List<Pair<MethodBridgeValueParameter, ParameterDescriptor?>> {
val kotlinParameters = descriptor.allParameters.iterator() val kotlinParameters = descriptor.allParameters.iterator()
@@ -97,26 +109,3 @@ internal fun MethodBridge.valueParametersAssociated(
} }
}.also { assert(!kotlinParameters.hasNext()) } }.also { assert(!kotlinParameters.hasNext()) }
} }
internal fun MethodBridge.parametersAssociated(
irFunction: IrFunction
): List<Pair<MethodBridgeParameter, IrValueParameter?>> {
val kotlinParameters = irFunction.allParameters.iterator()
return this.paramBridges.map {
when (it) {
is MethodBridgeValueParameter.Mapped,
MethodBridgeReceiver.Instance,
is MethodBridgeValueParameter.SuspendCompletion ->
it to kotlinParameters.next()
MethodBridgeReceiver.Static, MethodBridgeSelector, MethodBridgeValueParameter.ErrorOutParameter ->
it to null
MethodBridgeReceiver.Factory -> {
kotlinParameters.next()
it to null
}
}
}.also { assert(!kotlinParameters.hasNext()) }
}
@@ -1,6 +1,6 @@
/* /*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* that can be found in the LICENSE file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package org.jetbrains.kotlin.backend.konan.objcexport package org.jetbrains.kotlin.backend.konan.objcexport
@@ -52,12 +52,13 @@ interface ObjCExportProblemCollector {
} }
} }
internal class ObjCExportTranslatorImpl( @InternalKotlinNativeApi
private val generator: ObjCExportHeaderGenerator?, class ObjCExportTranslatorImpl(
val mapper: ObjCExportMapper, private val generator: ObjCExportHeaderGenerator?,
val namer: ObjCExportNamer, val mapper: ObjCExportMapper,
val problemCollector: ObjCExportProblemCollector, val namer: ObjCExportNamer,
val objcGenerics: Boolean val problemCollector: ObjCExportProblemCollector,
val objcGenerics: Boolean
) : ObjCExportTranslator { ) : ObjCExportTranslator {
private val kotlinAnyName = namer.kotlinAnyName private val kotlinAnyName = namer.kotlinAnyName
@@ -1096,12 +1097,12 @@ internal class ObjCExportTranslatorImpl(
StubBuilder<S>(problemCollector).apply(block).build() StubBuilder<S>(problemCollector).apply(block).build()
} }
abstract class ObjCExportHeaderGenerator internal constructor( abstract class ObjCExportHeaderGenerator @InternalKotlinNativeApi constructor(
val moduleDescriptors: List<ModuleDescriptor>, val moduleDescriptors: List<ModuleDescriptor>,
internal val mapper: ObjCExportMapper, internal val mapper: ObjCExportMapper,
val namer: ObjCExportNamer, val namer: ObjCExportNamer,
val objcGenerics: Boolean, val objcGenerics: Boolean,
problemCollector: ObjCExportProblemCollector problemCollector: ObjCExportProblemCollector
) { ) {
private val stubs = mutableListOf<Stub<*>>() private val stubs = mutableListOf<Stub<*>>()
@@ -1173,7 +1174,8 @@ abstract class ObjCExportHeaderGenerator internal constructor(
add("NS_ASSUME_NONNULL_END") add("NS_ASSUME_NONNULL_END")
} }
internal fun buildInterface(): ObjCExportedInterface { @InternalKotlinNativeApi
fun buildInterface(): ObjCExportedInterface {
val headerLines = build() val headerLines = build()
return ObjCExportedInterface(generatedClasses, extensions, topLevel, headerLines, namer, mapper) return ObjCExportedInterface(generatedClasses, extensions, topLevel, headerLines, namer, mapper)
} }
@@ -1356,6 +1358,18 @@ abstract class ObjCExportHeaderGenerator internal constructor(
add("#import <$it>") add("#import <$it>")
} }
} }
fun createInstance(
moduleDescriptors: List<ModuleDescriptor>,
mapper: ObjCExportMapper,
namer: ObjCExportNamer,
problemCollector: ObjCExportProblemCollector,
objcGenerics: Boolean,
shouldExportKDoc: Boolean,
additionalImports: List<String>,
): ObjCExportHeaderGenerator = ObjCExportHeaderGeneratorImpl(
moduleDescriptors, mapper, namer, problemCollector, objcGenerics, shouldExportKDoc, additionalImports
)
} }
} }
@@ -1423,7 +1437,8 @@ private fun computeSuperClassType(descriptor: ClassDescriptor): KotlinType? =
internal const val OBJC_SUBCLASSING_RESTRICTED = "objc_subclassing_restricted" internal const val OBJC_SUBCLASSING_RESTRICTED = "objc_subclassing_restricted"
internal fun ClassDescriptor.needCompanionObjectProperty(namer: ObjCExportNamer, mapper: ObjCExportMapper): Boolean { @InternalKotlinNativeApi
fun ClassDescriptor.needCompanionObjectProperty(namer: ObjCExportNamer, mapper: ObjCExportMapper): Boolean {
val companionObject = companionObjectDescriptor val companionObject = companionObjectDescriptor
if (companionObject == null || !mapper.shouldBeExposed(companionObject)) return false if (companionObject == null || !mapper.shouldBeExposed(companionObject)) return false
@@ -1,54 +1,21 @@
/* /*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* that can be found in the LICENSE file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package org.jetbrains.kotlin.backend.konan.objcexport package org.jetbrains.kotlin.backend.konan.objcexport
import org.jetbrains.kotlin.backend.konan.KonanConfigKeys
import org.jetbrains.kotlin.backend.konan.driver.PhaseContext
import org.jetbrains.kotlin.backend.konan.reportCompilationWarning
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
import org.jetbrains.kotlin.cli.common.messages.MessageUtil
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.renderer.DescriptorRenderer
import org.jetbrains.kotlin.resolve.source.getPsi
internal class ObjCExportHeaderGeneratorImpl( internal class ObjCExportHeaderGeneratorImpl(
val context: PhaseContext,
moduleDescriptors: List<ModuleDescriptor>, moduleDescriptors: List<ModuleDescriptor>,
mapper: ObjCExportMapper, mapper: ObjCExportMapper,
namer: ObjCExportNamer, namer: ObjCExportNamer,
problemCollector: ObjCExportProblemCollector, problemCollector: ObjCExportProblemCollector,
objcGenerics: Boolean objcGenerics: Boolean,
override val shouldExportKDoc: Boolean,
private val additionalImports: List<String>,
) : ObjCExportHeaderGenerator(moduleDescriptors, mapper, namer, objcGenerics, problemCollector) { ) : ObjCExportHeaderGenerator(moduleDescriptors, mapper, namer, objcGenerics, problemCollector) {
override val shouldExportKDoc = context.shouldExportKDoc()
internal class ProblemCollector(val context: PhaseContext) : ObjCExportProblemCollector {
override fun reportWarning(text: String) {
context.reportCompilationWarning(text)
}
override fun reportWarning(declaration: DeclarationDescriptor, text: String) {
val psi = (declaration as? DeclarationDescriptorWithSource)?.source?.getPsi()
?: return reportWarning(
"$text\n (at ${DescriptorRenderer.COMPACT_WITH_SHORT_TYPES.render(declaration)})"
)
val location = MessageUtil.psiElementToMessageLocation(psi)
context.messageCollector.report(CompilerMessageSeverity.WARNING, text, location)
}
override fun reportException(throwable: Throwable) {
throw throwable
}
}
override fun getAdditionalImports(): List<String> = override fun getAdditionalImports(): List<String> =
context.config.configuration.getNotNull(KonanConfigKeys.FRAMEWORK_IMPORT_HEADERS) additionalImports
} }
@@ -1,12 +1,13 @@
/* /*
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* that can be found in the LICENSE file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package org.jetbrains.kotlin.backend.konan.objcexport package org.jetbrains.kotlin.backend.konan.objcexport
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.analyzer.ModuleInfo import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.backend.konan.InternalKotlinNativeApi
import org.jetbrains.kotlin.backend.konan.UnitSuspendFunctionObjCExport import org.jetbrains.kotlin.backend.konan.UnitSuspendFunctionObjCExport
import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
@@ -79,7 +80,8 @@ fun createObjCExportLazy(
deprecationResolver deprecationResolver
) )
internal class ObjCExportLazyImpl( @InternalKotlinNativeApi
class ObjCExportLazyImpl(
private val configuration: ObjCExportLazy.Configuration, private val configuration: ObjCExportLazy.Configuration,
problemCollector: ObjCExportProblemCollector, problemCollector: ObjCExportProblemCollector,
private val codeAnalyzer: KotlinCodeAnalyzer, private val codeAnalyzer: KotlinCodeAnalyzer,
@@ -1,14 +1,16 @@
/* /*
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* that can be found in the LICENSE file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package org.jetbrains.kotlin.backend.konan.objcexport package org.jetbrains.kotlin.backend.konan.objcexport
import org.jetbrains.kotlin.backend.konan.InternalKotlinNativeApi
import org.jetbrains.kotlin.konan.file.File import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
internal fun ObjCExportLazy.dumpObjCHeader(files: Collection<KtFile>, outputFile: String, shouldExportKDoc: Boolean) { @InternalKotlinNativeApi
fun ObjCExportLazy.dumpObjCHeader(files: Collection<KtFile>, outputFile: String, shouldExportKDoc: Boolean) {
val lines = (this.generateBase() + files.flatMap { this.translate(it) }) val lines = (this.generateBase() + files.flatMap { this.translate(it) })
.flatMap { StubRenderer.render(it, shouldExportKDoc) + listOf("") } .flatMap { StubRenderer.render(it, shouldExportKDoc) + listOf("") }
@@ -1,6 +1,6 @@
/* /*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* that can be found in the LICENSE file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package org.jetbrains.kotlin.backend.konan.objcexport package org.jetbrains.kotlin.backend.konan.objcexport
@@ -25,10 +25,11 @@ import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.types.typeUtil.isNothing import org.jetbrains.kotlin.types.typeUtil.isNothing
import org.jetbrains.kotlin.types.typeUtil.isUnit import org.jetbrains.kotlin.types.typeUtil.isUnit
internal class ObjCExportMapper( @InternalKotlinNativeApi
internal val deprecationResolver: DeprecationResolver? = null, class ObjCExportMapper(
private val local: Boolean = false, internal val deprecationResolver: DeprecationResolver? = null,
internal val unitSuspendFunctionExport: UnitSuspendFunctionObjCExport private val local: Boolean = false,
internal val unitSuspendFunctionExport: UnitSuspendFunctionObjCExport
) { ) {
fun getCustomTypeMapper(descriptor: ClassDescriptor): CustomTypeMapper? = CustomTypeMappers.getMapper(descriptor) fun getCustomTypeMapper(descriptor: ClassDescriptor): CustomTypeMapper? = CustomTypeMappers.getMapper(descriptor)
@@ -89,7 +90,8 @@ private fun isComponentNMethod(method: CallableMemberDescriptor): Boolean {
} }
// Note: partially duplicated in ObjCExportLazyImpl.translateTopLevels. // Note: partially duplicated in ObjCExportLazyImpl.translateTopLevels.
internal fun ObjCExportMapper.shouldBeExposed(descriptor: CallableMemberDescriptor): Boolean = when { @InternalKotlinNativeApi
fun ObjCExportMapper.shouldBeExposed(descriptor: CallableMemberDescriptor): Boolean = when {
!descriptor.isEffectivelyPublicApi -> false !descriptor.isEffectivelyPublicApi -> false
descriptor.isExpect -> false descriptor.isExpect -> false
isHiddenByDeprecation(descriptor) -> false isHiddenByDeprecation(descriptor) -> false
@@ -208,29 +210,33 @@ private fun ObjCExportMapper.isBase(descriptor: CallableMemberDescriptor): Boole
* ``` * ```
* Interface `I` is not exposed to the generated header, so C#f is considered to be a base method even though it has an "override" keyword. * Interface `I` is not exposed to the generated header, so C#f is considered to be a base method even though it has an "override" keyword.
*/ */
internal fun ObjCExportMapper.isBaseMethod(descriptor: FunctionDescriptor) = @InternalKotlinNativeApi
this.isBase(descriptor) fun ObjCExportMapper.isBaseMethod(descriptor: FunctionDescriptor) =
this.isBase(descriptor)
internal fun ObjCExportMapper.getBaseMethods(descriptor: FunctionDescriptor): List<FunctionDescriptor> = @InternalKotlinNativeApi
if (isBaseMethod(descriptor)) { fun ObjCExportMapper.getBaseMethods(descriptor: FunctionDescriptor): List<FunctionDescriptor> =
listOf(descriptor) if (isBaseMethod(descriptor)) {
} else { listOf(descriptor)
descriptor.overriddenDescriptors.filter { shouldBeExposed(it) } } else {
.flatMap { getBaseMethods(it.original)} descriptor.overriddenDescriptors.filter { shouldBeExposed(it) }
.distinct() .flatMap { getBaseMethods(it.original) }
} .distinct()
}
internal fun ObjCExportMapper.isBaseProperty(descriptor: PropertyDescriptor) = @InternalKotlinNativeApi
isBase(descriptor) fun ObjCExportMapper.isBaseProperty(descriptor: PropertyDescriptor) =
isBase(descriptor)
internal fun ObjCExportMapper.getBaseProperties(descriptor: PropertyDescriptor): List<PropertyDescriptor> = @InternalKotlinNativeApi
if (isBaseProperty(descriptor)) { fun ObjCExportMapper.getBaseProperties(descriptor: PropertyDescriptor): List<PropertyDescriptor> =
listOf(descriptor) if (isBaseProperty(descriptor)) {
} else { listOf(descriptor)
descriptor.overriddenDescriptors } else {
.flatMap { getBaseProperties(it.original) } descriptor.overriddenDescriptors
.distinct() .flatMap { getBaseProperties(it.original) }
} .distinct()
}
@Suppress("NO_TAIL_CALLS_FOUND", "NON_TAIL_RECURSIVE_CALL") // K2 warning suppression, TODO: KT-62472 @Suppress("NO_TAIL_CALLS_FOUND", "NON_TAIL_RECURSIVE_CALL") // K2 warning suppression, TODO: KT-62472
internal tailrec fun KotlinType.getErasedTypeClass(): ClassDescriptor = internal tailrec fun KotlinType.getErasedTypeClass(): ClassDescriptor =
@@ -242,7 +248,8 @@ internal fun ObjCExportMapper.isTopLevel(descriptor: CallableMemberDescriptor):
internal fun ObjCExportMapper.isObjCProperty(property: PropertyDescriptor): Boolean = internal fun ObjCExportMapper.isObjCProperty(property: PropertyDescriptor): Boolean =
property.extensionReceiverParameter == null || getClassIfCategory(property) != null property.extensionReceiverParameter == null || getClassIfCategory(property) != null
internal fun ClassDescriptor.getEnumValuesFunctionDescriptor(): SimpleFunctionDescriptor? { @InternalKotlinNativeApi
fun ClassDescriptor.getEnumValuesFunctionDescriptor(): SimpleFunctionDescriptor? {
require(this.kind == ClassKind.ENUM_CLASS) require(this.kind == ClassKind.ENUM_CLASS)
return this.staticScope.getContributedFunctions( return this.staticScope.getContributedFunctions(
@@ -251,7 +258,8 @@ internal fun ClassDescriptor.getEnumValuesFunctionDescriptor(): SimpleFunctionDe
).singleOrNull { it.extensionReceiverParameter == null && it.valueParameters.size == 0 } ).singleOrNull { it.extensionReceiverParameter == null && it.valueParameters.size == 0 }
} }
internal fun ClassDescriptor.getEnumEntriesPropertyDescriptor(): PropertyDescriptor? { @InternalKotlinNativeApi
fun ClassDescriptor.getEnumEntriesPropertyDescriptor(): PropertyDescriptor? {
require(this.kind == ClassKind.ENUM_CLASS) require(this.kind == ClassKind.ENUM_CLASS)
return this.staticScope.getContributedVariables( return this.staticScope.getContributedVariables(
@@ -312,7 +320,7 @@ private fun ObjCExportMapper.bridgeFunctionType(kotlinType: KotlinType): TypeBri
} }
private fun ObjCExportMapper.bridgeParameter(parameter: ParameterDescriptor): MethodBridgeValueParameter = private fun ObjCExportMapper.bridgeParameter(parameter: ParameterDescriptor): MethodBridgeValueParameter =
MethodBridgeValueParameter.Mapped(bridgeType(parameter.type)) MethodBridgeValueParameter.Mapped(bridgeType(parameter.type))
private fun ObjCExportMapper.bridgeReturnType( private fun ObjCExportMapper.bridgeReturnType(
descriptor: FunctionDescriptor, descriptor: FunctionDescriptor,
@@ -427,7 +435,8 @@ internal fun ObjCExportMapper.bridgePropertyType(descriptor: PropertyDescriptor)
return bridgeType(descriptor.type) return bridgeType(descriptor.type)
} }
internal enum class NSNumberKind(val mappedKotlinClassId: ClassId?, val objCType: ObjCType) { @InternalKotlinNativeApi
enum class NSNumberKind(val mappedKotlinClassId: ClassId?, val objCType: ObjCType) {
CHAR(PrimitiveType.BYTE, ObjCPrimitiveType.char), CHAR(PrimitiveType.BYTE, ObjCPrimitiveType.char),
UNSIGNED_CHAR(UnsignedType.UBYTE, ObjCPrimitiveType.unsigned_char), UNSIGNED_CHAR(UnsignedType.UBYTE, ObjCPrimitiveType.unsigned_char),
SHORT(PrimitiveType.SHORT, ObjCPrimitiveType.short), SHORT(PrimitiveType.SHORT, ObjCPrimitiveType.short),
@@ -1,20 +1,20 @@
/* /*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* that can be found in the LICENSE file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package org.jetbrains.kotlin.backend.konan.objcexport package org.jetbrains.kotlin.backend.konan.objcexport
import org.jetbrains.kotlin.backend.common.serialization.findSourceFile import org.jetbrains.kotlin.backend.common.serialization.findSourceFile
import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.InternalKotlinNativeApi
import org.jetbrains.kotlin.backend.konan.KonanFqNames
import org.jetbrains.kotlin.backend.konan.UnitSuspendFunctionObjCExport
import org.jetbrains.kotlin.backend.konan.cKeywords import org.jetbrains.kotlin.backend.konan.cKeywords
import org.jetbrains.kotlin.backend.konan.descriptors.isArray import org.jetbrains.kotlin.backend.konan.descriptors.isArray
import org.jetbrains.kotlin.backend.konan.descriptors.isInterface import org.jetbrains.kotlin.backend.konan.descriptors.isInterface
import org.jetbrains.kotlin.backend.konan.driver.PhaseContext
import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.konan.* import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib
import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.library.metadata.CurrentKlibModuleOrigin import org.jetbrains.kotlin.library.metadata.CurrentKlibModuleOrigin
import org.jetbrains.kotlin.library.metadata.DeserializedKlibModuleOrigin import org.jetbrains.kotlin.library.metadata.DeserializedKlibModuleOrigin
@@ -88,9 +88,12 @@ interface ObjCExportNamer {
fun getCompanionObjectPropertySelector(descriptor: ClassDescriptor): String fun getCompanionObjectPropertySelector(descriptor: ClassDescriptor): String
companion object { companion object {
internal const val kotlinThrowableAsErrorMethodName: String = "asError" @InternalKotlinNativeApi
internal const val objectPropertyName: String = "shared" const val kotlinThrowableAsErrorMethodName: String = "asError"
internal const val companionObjectPropertyName: String = "companion" @InternalKotlinNativeApi
const val objectPropertyName: String = "shared"
@InternalKotlinNativeApi
const val companionObjectPropertyName: String = "companion"
} }
} }
@@ -273,14 +276,14 @@ private class ObjCExportNamingHelper(
"char", "long", "float", "double", "int32_t", "int64_t", "int16_t", "int8_t", "unichar") "char", "long", "float", "double", "int32_t", "int64_t", "int16_t", "int8_t", "unichar")
} }
internal class ObjCExportNamerImpl( @InternalKotlinNativeApi
class ObjCExportNamerImpl(
private val configuration: ObjCExportNamer.Configuration, private val configuration: ObjCExportNamer.Configuration,
builtIns: KotlinBuiltIns, builtIns: KotlinBuiltIns,
private val mapper: ObjCExportMapper, private val mapper: ObjCExportMapper,
private val problemCollector: ObjCExportProblemCollector, private val problemCollector: ObjCExportProblemCollector,
private val local: Boolean private val local: Boolean
) : ObjCExportNamer { ) : ObjCExportNamer {
constructor( constructor(
moduleDescriptors: Set<ModuleDescriptor>, moduleDescriptors: Set<ModuleDescriptor>,
builtIns: KotlinBuiltIns, builtIns: KotlinBuiltIns,
@@ -703,7 +706,7 @@ internal class ObjCExportNamerImpl(
builtIns.mutableMap to mutableMapName builtIns.mutableMap to mutableMapName
) )
predefinedClassNames.forEach { descriptor, name -> predefinedClassNames.forEach { (descriptor, name) ->
objCClassNames.forceAssign(descriptor, name.objCName) objCClassNames.forceAssign(descriptor, name.objCName)
swiftClassAndProtocolNames.forceAssign(descriptor, name.swiftName) swiftClassAndProtocolNames.forceAssign(descriptor, name.swiftName)
} }
@@ -714,11 +717,11 @@ internal class ObjCExportNamerImpl(
NoLookupLocation.FROM_BACKEND NoLookupLocation.FROM_BACKEND
).single() ).single()
Predefined.anyMethodSelectors.forEach { name, selector -> Predefined.anyMethodSelectors.forEach { (name, selector) ->
methodSelectors.forceAssign(any.method(name), selector) methodSelectors.forceAssign(any.method(name), selector)
} }
Predefined.anyMethodSwiftNames.forEach { name, swiftName -> Predefined.anyMethodSwiftNames.forEach { (name, swiftName) ->
methodSwiftNames.forceAssign(any.method(name), swiftName) methodSwiftNames.forceAssign(any.method(name), swiftName)
} }
} }
@@ -1082,8 +1085,6 @@ internal val ModuleDescriptor.objCExportAdditionalNamePrefix: String get() {
return abbreviate(fullPrefix) return abbreviate(fullPrefix)
} }
internal val PhaseContext.objCExportTopLevelNamePrefix: String
get() = abbreviate(config.fullExportedNamePrefix)
fun abbreviate(name: String): String { fun abbreviate(name: String): String {
val normalizedName = name val normalizedName = name
@@ -1,10 +1,11 @@
/* /*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package org.jetbrains.kotlin.backend.konan.objcexport package org.jetbrains.kotlin.backend.konan.objcexport
import org.jetbrains.kotlin.backend.konan.InternalKotlinNativeApi
import org.jetbrains.kotlin.backend.konan.descriptors.isInterface import org.jetbrains.kotlin.backend.konan.descriptors.isInterface
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
@@ -35,7 +36,8 @@ internal inline fun <reified T : ObjCExportScope> ObjCExportScope.nearestScopeOf
return null return null
} }
internal object ObjCRootExportScope : ObjCExportScope @InternalKotlinNativeApi
object ObjCRootExportScope : ObjCExportScope
interface ObjCClassExportScope : ObjCExportScope { interface ObjCClassExportScope : ObjCExportScope {
fun getGenericTypeUsage(typeParameterDescriptor: TypeParameterDescriptor?): ObjCGenericTypeUsage? fun getGenericTypeUsage(typeParameterDescriptor: TypeParameterDescriptor?): ObjCGenericTypeUsage?
@@ -0,0 +1,21 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.backend.konan.objcexport
import org.jetbrains.kotlin.backend.konan.InternalKotlinNativeApi
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.SourceFile
@InternalKotlinNativeApi
class ObjCExportedInterface internal constructor(
val generatedClasses: Set<ClassDescriptor>,
val categoryMembers: Map<ClassDescriptor, List<CallableMemberDescriptor>>,
val topLevel: Map<SourceFile, List<CallableMemberDescriptor>>,
val headerLines: List<String>,
val namer: ObjCExportNamer,
val mapper: ObjCExportMapper
)
@@ -5,7 +5,7 @@
package org.jetbrains.kotlin.backend.konan.objcexport package org.jetbrains.kotlin.backend.konan.objcexport
import org.jetbrains.kotlin.backend.konan.llvm.LlvmParameterAttribute import org.jetbrains.kotlin.backend.konan.InternalKotlinNativeApi
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.Variance
@@ -154,16 +154,17 @@ object ObjCVoidType : ObjCType() {
override fun render(attrsAndName: String) = "void".withAttrsAndName(attrsAndName) override fun render(attrsAndName: String) = "void".withAttrsAndName(attrsAndName)
} }
internal enum class ObjCValueType(val encoding: String, val defaultParameterAttributes: List<LlvmParameterAttribute> = emptyList()) { @InternalKotlinNativeApi
BOOL("c", listOf(LlvmParameterAttribute.SignExt)), enum class ObjCValueType(val encoding: String) {
UNICHAR("S", listOf(LlvmParameterAttribute.ZeroExt)), BOOL("c"),
UNICHAR("S"),
// TODO: Switch to explicit SIGNED_CHAR // TODO: Switch to explicit SIGNED_CHAR
CHAR("c", listOf(LlvmParameterAttribute.SignExt)), CHAR("c"),
SHORT("s", listOf(LlvmParameterAttribute.SignExt)), SHORT("s"),
INT("i"), INT("i"),
LONG_LONG("q"), LONG_LONG("q"),
UNSIGNED_CHAR("C", listOf(LlvmParameterAttribute.ZeroExt)), UNSIGNED_CHAR("C"),
UNSIGNED_SHORT("S", listOf(LlvmParameterAttribute.ZeroExt)), UNSIGNED_SHORT("S"),
UNSIGNED_INT("I"), UNSIGNED_INT("I"),
UNSIGNED_LONG_LONG("Q"), UNSIGNED_LONG_LONG("Q"),
FLOAT("f"), FLOAT("f"),
@@ -206,7 +207,8 @@ data class ObjCGenericTypeParameterDeclaration(
get() = ObjCVariance.fromKotlinVariance(typeParameterDescriptor.variance) get() = ObjCVariance.fromKotlinVariance(typeParameterDescriptor.variance)
} }
internal fun ObjCType.makeNullableIfReferenceOrPointer(): ObjCType = when (this) { @InternalKotlinNativeApi
fun ObjCType.makeNullableIfReferenceOrPointer(): ObjCType = when (this) {
is ObjCPointerType -> ObjCPointerType(this.pointee, nullable = true) is ObjCPointerType -> ObjCPointerType(this.pointee, nullable = true)
is ObjCNonNullReferenceType -> ObjCNullableReferenceType(this) is ObjCNonNullReferenceType -> ObjCNullableReferenceType(this)
@@ -6,43 +6,11 @@
package org.jetbrains.kotlin.backend.konan.testUtils package org.jetbrains.kotlin.backend.konan.testUtils
import com.intellij.openapi.Disposable import com.intellij.openapi.Disposable
import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.analyzer.common.CommonDependenciesContainer
import org.jetbrains.kotlin.analyzer.common.CommonResolverForModuleFactory
import org.jetbrains.kotlin.backend.konan.KlibFactories
import org.jetbrains.kotlin.backend.konan.KonanConfig
import org.jetbrains.kotlin.backend.konan.KonanConfigKeys
import org.jetbrains.kotlin.backend.konan.KonanConfigKeys.Companion.KONAN_HOME
import org.jetbrains.kotlin.backend.konan.UnitSuspendFunctionObjCExport import org.jetbrains.kotlin.backend.konan.UnitSuspendFunctionObjCExport
import org.jetbrains.kotlin.backend.konan.driver.BasicPhaseContext
import org.jetbrains.kotlin.backend.konan.objcexport.* import org.jetbrains.kotlin.backend.konan.objcexport.*
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportHeaderGeneratorImpl
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportMapper
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportNamerImpl
import org.jetbrains.kotlin.builtins.DefaultBuiltIns import org.jetbrains.kotlin.builtins.DefaultBuiltIns
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
import org.jetbrains.kotlin.cli.common.arguments.K2NativeCompilerArguments
import org.jetbrains.kotlin.cli.common.createFlexiblePhaseConfig
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
import org.jetbrains.kotlin.library.resolveSingleFileKlib
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.platform.CommonPlatforms
import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlin.platform.konan.NativePlatforms
import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.resolve.CompilerEnvironment
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
import org.jetbrains.kotlin.resolve.konan.platform.NativePlatformAnalyzerServices
import org.jetbrains.kotlin.storage.LockBasedStorageManager
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.testFramework.MockProjectEx
import org.jetbrains.kotlin.test.util.KtTestUtil
import java.io.File import java.io.File
object Fe10ObjCExportHeaderGenerator : AbstractObjCExportHeaderGeneratorTest.ObjCExportHeaderGenerator { object Fe10ObjCExportHeaderGenerator : AbstractObjCExportHeaderGeneratorTest.ObjCExportHeaderGenerator {
@@ -70,19 +38,17 @@ object Fe10ObjCExportHeaderGenerator : AbstractObjCExportHeaderGeneratorTest.Obj
) )
val environment: KotlinCoreEnvironment = createKotlinCoreEnvironment(disposable) val environment: KotlinCoreEnvironment = createKotlinCoreEnvironment(disposable)
val phaseContext = BasicPhaseContext(
KonanConfig(environment.project, environment.configuration)
)
val kotlinFiles = root.walkTopDown().filter { it.isFile }.filter { it.extension == "kt" }.toList() val kotlinFiles = root.walkTopDown().filter { it.isFile }.filter { it.extension == "kt" }.toList()
return ObjCExportHeaderGeneratorImpl( return ObjCExportHeaderGeneratorImpl(
context = phaseContext,
moduleDescriptors = listOf(createModuleDescriptor(environment, kotlinFiles)), moduleDescriptors = listOf(createModuleDescriptor(environment, kotlinFiles)),
mapper = mapper, mapper = mapper,
namer = namer, namer = namer,
problemCollector = ObjCExportProblemCollector.SILENT, problemCollector = ObjCExportProblemCollector.SILENT,
objcGenerics = true objcGenerics = true,
shouldExportKDoc = true,
additionalImports = emptyList()
) )
} }
} }
@@ -9,9 +9,9 @@ import com.intellij.openapi.Disposable
import org.jetbrains.kotlin.analyzer.ModuleInfo import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.analyzer.common.CommonDependenciesContainer import org.jetbrains.kotlin.analyzer.common.CommonDependenciesContainer
import org.jetbrains.kotlin.analyzer.common.CommonResolverForModuleFactory import org.jetbrains.kotlin.analyzer.common.CommonResolverForModuleFactory
import org.jetbrains.kotlin.backend.konan.KlibFactories import org.jetbrains.kotlin.backend.common.serialization.metadata.DynamicTypeDeserializer
import org.jetbrains.kotlin.backend.konan.KonanConfigKeys
import org.jetbrains.kotlin.builtins.DefaultBuiltIns import org.jetbrains.kotlin.builtins.DefaultBuiltIns
import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
import org.jetbrains.kotlin.cli.common.arguments.K2NativeCompilerArguments import org.jetbrains.kotlin.cli.common.arguments.K2NativeCompilerArguments
import org.jetbrains.kotlin.cli.common.createFlexiblePhaseConfig import org.jetbrains.kotlin.cli.common.createFlexiblePhaseConfig
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.konan.target.CompilerOutputKind import org.jetbrains.kotlin.library.metadata.KlibMetadataFactories
import org.jetbrains.kotlin.library.resolveSingleFileKlib import org.jetbrains.kotlin.library.resolveSingleFileKlib
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.platform.CommonPlatforms import org.jetbrains.kotlin.platform.CommonPlatforms
@@ -87,13 +87,6 @@ private fun createCompilerConfiguration(): CompilerConfiguration {
val configuration = KotlinTestUtils.newConfiguration() val configuration = KotlinTestUtils.newConfiguration()
configuration.put(CommonConfigurationKeys.LANGUAGE_VERSION_SETTINGS, createLanguageVersionSettings()) configuration.put(CommonConfigurationKeys.LANGUAGE_VERSION_SETTINGS, createLanguageVersionSettings())
configuration.put(CLIConfigurationKeys.FLEXIBLE_PHASE_CONFIG, createFlexiblePhaseConfig(K2NativeCompilerArguments())) configuration.put(CLIConfigurationKeys.FLEXIBLE_PHASE_CONFIG, createFlexiblePhaseConfig(K2NativeCompilerArguments()))
configuration.put(KonanConfigKeys.KONAN_HOME, konanHomePath)
configuration.put(KonanConfigKeys.PRODUCE, CompilerOutputKind.FRAMEWORK)
configuration.put(KonanConfigKeys.AUTO_CACHEABLE_FROM, emptyList())
configuration.put(KonanConfigKeys.CACHE_DIRECTORIES, emptyList())
configuration.put(KonanConfigKeys.CACHED_LIBRARIES, emptyMap())
configuration.put(KonanConfigKeys.FRAMEWORK_IMPORT_HEADERS, emptyList())
configuration.put(KonanConfigKeys.EXPORT_KDOC, true)
return configuration return configuration
} }
@@ -109,7 +102,9 @@ private object DependenciesContainerImpl : CommonDependenciesContainer {
override fun registerDependencyForAllModules(moduleInfo: ModuleInfo, descriptorForModule: ModuleDescriptorImpl) = Unit override fun registerDependencyForAllModules(moduleInfo: ModuleInfo, descriptorForModule: ModuleDescriptorImpl) = Unit
override fun packageFragmentProviderForModuleInfo(moduleInfo: ModuleInfo): PackageFragmentProvider? = null override fun packageFragmentProviderForModuleInfo(moduleInfo: ModuleInfo): PackageFragmentProvider? = null
private val stdlibModuleDescriptor = KlibFactories.DefaultDeserializedDescriptorFactory.createDescriptor( private val klibFactory = KlibMetadataFactories(::KonanBuiltIns, DynamicTypeDeserializer)
private val stdlibModuleDescriptor = klibFactory.DefaultDeserializedDescriptorFactory.createDescriptor(
library = resolveSingleFileKlib(org.jetbrains.kotlin.konan.file.File("$konanHomePath/klib/common/stdlib")), library = resolveSingleFileKlib(org.jetbrains.kotlin.konan.file.File("$konanHomePath/klib/common/stdlib")),
languageVersionSettings = createLanguageVersionSettings(), languageVersionSettings = createLanguageVersionSettings(),
builtIns = DefaultBuiltIns.Instance, builtIns = DefaultBuiltIns.Instance,
@@ -5,7 +5,7 @@
package org.jetbrains.kotlin.backend.konan.testUtils package org.jetbrains.kotlin.backend.konan.testUtils
private const val konanHomePropertyKey = "org.jetbrains.kotlin.native.home" private const val konanHomePropertyKey = "kotlin.internal.native.test.nativeHome"
val konanHomePath: String val konanHomePath: String
get() = System.getProperty(konanHomePropertyKey) ?: error("Missing System property: '$konanHomePropertyKey'") get() = System.getProperty(konanHomePropertyKey) ?: error("Missing System property: '$konanHomePropertyKey'")
@@ -7,5 +7,5 @@ package org.jetbrains.kotlin.backend.konan.testUtils
import java.io.File import java.io.File
val projectDir = File("kotlin-native/backend.native") val projectDir = File(System.getProperty("projectDir"))
val testDataDir = projectDir.resolve("functionalTest/testData") val testDataDir = projectDir.resolve("src/test/testData")
@@ -6,8 +6,6 @@
package org.jetbrains.kotlin.backend.konan.tests package org.jetbrains.kotlin.backend.konan.tests
import com.intellij.openapi.util.Disposer import com.intellij.openapi.util.Disposer
import org.jetbrains.kotlin.backend.konan.KonanConfig
import org.jetbrains.kotlin.backend.konan.driver.BasicPhaseContext
import org.jetbrains.kotlin.backend.konan.objcexport.* import org.jetbrains.kotlin.backend.konan.objcexport.*
import org.jetbrains.kotlin.backend.konan.testUtils.* import org.jetbrains.kotlin.backend.konan.testUtils.*
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
@@ -68,14 +66,13 @@ class ObjCExportMapperTest : InlineSourceTestEnvironment {
val objcExportTranslator = ObjCExportTranslatorImpl( val objcExportTranslator = ObjCExportTranslatorImpl(
generator = ObjCExportHeaderGeneratorImpl( generator = ObjCExportHeaderGeneratorImpl(
context = BasicPhaseContext(
KonanConfig(kotlinCoreEnvironment.project, kotlinCoreEnvironment.configuration)
),
moduleDescriptors = listOf(module), moduleDescriptors = listOf(module),
mapper = objcExportMapper, mapper = objcExportMapper,
namer = objcExportNamer, namer = objcExportNamer,
problemCollector = ObjCExportProblemCollector.SILENT, problemCollector = ObjCExportProblemCollector.SILENT,
objcGenerics = true objcGenerics = true,
shouldExportKDoc = false,
additionalImports = emptyList()
), ),
mapper = objcExportMapper, mapper = objcExportMapper,
namer = objcExportNamer, namer = objcExportNamer,
@@ -0,0 +1,11 @@
plugins {
kotlin("jvm")
}
publishJarsForIde(
listOf(
":native:base",
":native:objcexport-header-generator",
":compiler:ir.serialization.native"
)
)
@@ -103,16 +103,6 @@ enum class JUnitMode {
JUnit4, JUnit5 JUnit4, JUnit5
} }
/**
* Convenience function to expose Project.projectTest for groovy
*/
fun projectTest(project: Project) = project.projectTest()
/**
* Convenience function to expose Project.projectTest for groovy
*/
fun projectTest(project: Project, jUnitMode: JUnitMode) = project.projectTest(jUnitMode = jUnitMode)
/** /**
* @param parallel is redundant if @param jUnit5Enabled is true, because * @param parallel is redundant if @param jUnit5Enabled is true, because
* JUnit5 supports parallel test execution by itself, without gradle help * JUnit5 supports parallel test execution by itself, without gradle help
+3 -1
View File
@@ -110,6 +110,8 @@ include ":benchmarks",
":native:kotlin-klib-commonizer-api", ":native:kotlin-klib-commonizer-api",
":native:kotlin-klib-commonizer-embeddable", ":native:kotlin-klib-commonizer-embeddable",
":native:executors", ":native:executors",
":native:base",
":native:objcexport-header-generator",
":core:compiler.common", ":core:compiler.common",
":core:compiler.common.jvm", ":core:compiler.common.jvm",
":core:compiler.common.js", ":core:compiler.common.js",
@@ -365,7 +367,7 @@ if (!buildProperties.inJpsBuildIdeaSync) {
":prepare:ide-plugin-dependencies:assignment-compiler-plugin-for-ide", ":prepare:ide-plugin-dependencies:assignment-compiler-plugin-for-ide",
":prepare:ide-plugin-dependencies:parcelize-compiler-plugin-for-ide", ":prepare:ide-plugin-dependencies:parcelize-compiler-plugin-for-ide",
":prepare:ide-plugin-dependencies:lombok-compiler-plugin-for-ide", ":prepare:ide-plugin-dependencies:lombok-compiler-plugin-for-ide",
":prepare:ide-plugin-dependencies:kotlin-backend-native-for-ide", ":prepare:ide-plugin-dependencies:kotlin-objcexport-header-generator-for-ide",
":prepare:ide-plugin-dependencies:tests-common-tests-for-ide", ":prepare:ide-plugin-dependencies:tests-common-tests-for-ide",
":prepare:ide-plugin-dependencies:kotlin-compiler-testdata-for-ide", ":prepare:ide-plugin-dependencies:kotlin-compiler-testdata-for-ide",
":prepare:ide-plugin-dependencies:kotlin-compiler-tests-for-ide", ":prepare:ide-plugin-dependencies:kotlin-compiler-tests-for-ide",