[klib] Add an option to write out header klibs
The header klib is supposed to only contain the public abi of the module similar to jvm-abi-gen. It is intended to be used as a dependency for other klib compilations instead of the full klib for compilation avoidance. ^KT-60807
This commit is contained in:
+2
-1
@@ -45,6 +45,7 @@ fun copyK2NativeCompilerArguments(from: K2NativeCompilerArguments, to: K2NativeC
|
|||||||
to.generateNoExitTestRunner = from.generateNoExitTestRunner
|
to.generateNoExitTestRunner = from.generateNoExitTestRunner
|
||||||
to.generateTestRunner = from.generateTestRunner
|
to.generateTestRunner = from.generateTestRunner
|
||||||
to.generateWorkerTestRunner = from.generateWorkerTestRunner
|
to.generateWorkerTestRunner = from.generateWorkerTestRunner
|
||||||
|
to.headerKlibPath = from.headerKlibPath
|
||||||
to.includeBinaries = from.includeBinaries?.copyOf()
|
to.includeBinaries = from.includeBinaries?.copyOf()
|
||||||
to.includes = from.includes?.copyOf()
|
to.includes = from.includes?.copyOf()
|
||||||
to.incrementalCacheDir = from.incrementalCacheDir
|
to.incrementalCacheDir = from.incrementalCacheDir
|
||||||
@@ -104,4 +105,4 @@ fun copyK2NativeCompilerArguments(from: K2NativeCompilerArguments, to: K2NativeC
|
|||||||
to.workerExceptionHandling = from.workerExceptionHandling
|
to.workerExceptionHandling = from.workerExceptionHandling
|
||||||
|
|
||||||
return to
|
return to
|
||||||
}
|
}
|
||||||
+6
@@ -372,6 +372,12 @@ class K2NativeCompilerArguments : CommonCompilerArguments() {
|
|||||||
@Argument(value = "-Xmetadata-klib", description = "Produce a klib that only contains the declarations metadata")
|
@Argument(value = "-Xmetadata-klib", description = "Produce a klib that only contains the declarations metadata")
|
||||||
var metadataKlib: Boolean = false
|
var metadataKlib: Boolean = false
|
||||||
|
|
||||||
|
@Argument(
|
||||||
|
value = "-Xheader-klib-path",
|
||||||
|
description = "Save a klib that only contains the public abi to the given path"
|
||||||
|
)
|
||||||
|
var headerKlibPath: String? = null
|
||||||
|
|
||||||
@Argument(value = "-Xdebug-prefix-map", valueDescription = "<old1=new1,old2=new2,...>", description = "Remap file source directory paths in debug info")
|
@Argument(value = "-Xdebug-prefix-map", valueDescription = "<old1=new1,old2=new2,...>", description = "Remap file source directory paths in debug info")
|
||||||
var debugPrefixMap: Array<String>? = null
|
var debugPrefixMap: Array<String>? = null
|
||||||
|
|
||||||
|
|||||||
@@ -58,7 +58,8 @@ internal class K2MetadataKlibSerializer(
|
|||||||
project,
|
project,
|
||||||
exportKDoc = false,
|
exportKDoc = false,
|
||||||
skipExpects = false,
|
skipExpects = false,
|
||||||
includeOnlyModuleContent = true
|
includeOnlyModuleContent = true,
|
||||||
|
produceHeaderKlib = false,
|
||||||
).serializeModule(module)
|
).serializeModule(module)
|
||||||
|
|
||||||
buildKotlinMetadataLibrary(configuration, serializedMetadata, destDir)
|
buildKotlinMetadataLibrary(configuration, serializedMetadata, destDir)
|
||||||
|
|||||||
+13
-4
@@ -74,6 +74,7 @@ class FirElementSerializer private constructor(
|
|||||||
private val serializeTypeTableToFunction: Boolean,
|
private val serializeTypeTableToFunction: Boolean,
|
||||||
private val typeApproximator: AbstractTypeApproximator,
|
private val typeApproximator: AbstractTypeApproximator,
|
||||||
private val languageVersionSettings: LanguageVersionSettings,
|
private val languageVersionSettings: LanguageVersionSettings,
|
||||||
|
private val produceHeaderKlib: Boolean,
|
||||||
) {
|
) {
|
||||||
private val contractSerializer = FirContractSerializer()
|
private val contractSerializer = FirContractSerializer()
|
||||||
private val providedDeclarationsService = session.providedDeclarationsForMetadataService
|
private val providedDeclarationsService = session.providedDeclarationsForMetadataService
|
||||||
@@ -89,7 +90,8 @@ class FirElementSerializer private constructor(
|
|||||||
|
|
||||||
fun addDeclaration(declaration: FirDeclaration, onUnsupportedDeclaration: (FirDeclaration) -> Unit) {
|
fun addDeclaration(declaration: FirDeclaration, onUnsupportedDeclaration: (FirDeclaration) -> Unit) {
|
||||||
if (declaration is FirMemberDeclaration) {
|
if (declaration is FirMemberDeclaration) {
|
||||||
if (!declaration.shouldBeSerialized(actualizedExpectDeclarations)) return
|
if (!declaration.isNotExpectOrShouldBeSerialized(actualizedExpectDeclarations)) return
|
||||||
|
if (!declaration.isNotPrivateOrShouldBeSerialized(produceHeaderKlib)) return
|
||||||
when (declaration) {
|
when (declaration) {
|
||||||
is FirProperty -> propertyProto(declaration)?.let { builder.addProperty(it) }
|
is FirProperty -> propertyProto(declaration)?.let { builder.addProperty(it) }
|
||||||
is FirSimpleFunction -> functionProto(declaration)?.let { builder.addFunction(it) }
|
is FirSimpleFunction -> functionProto(declaration)?.let { builder.addFunction(it) }
|
||||||
@@ -178,6 +180,7 @@ class FirElementSerializer private constructor(
|
|||||||
*/
|
*/
|
||||||
if (regularClass != null && regularClass.classKind != ClassKind.ENUM_ENTRY) {
|
if (regularClass != null && regularClass.classKind != ClassKind.ENUM_ENTRY) {
|
||||||
for (constructor in regularClass.constructors()) {
|
for (constructor in regularClass.constructors()) {
|
||||||
|
if (!constructor.isNotPrivateOrShouldBeSerialized(produceHeaderKlib)) continue
|
||||||
builder.addConstructor(constructorProto(constructor))
|
builder.addConstructor(constructorProto(constructor))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,6 +206,7 @@ class FirElementSerializer private constructor(
|
|||||||
|
|
||||||
for (declaration in callableMembers) {
|
for (declaration in callableMembers) {
|
||||||
if (declaration !is FirEnumEntry && declaration.isStatic) continue // ??? Miss values() & valueOf()
|
if (declaration !is FirEnumEntry && declaration.isStatic) continue // ??? Miss values() & valueOf()
|
||||||
|
if (!declaration.isNotPrivateOrShouldBeSerialized(produceHeaderKlib)) continue
|
||||||
when (declaration) {
|
when (declaration) {
|
||||||
is FirProperty -> propertyProto(declaration)?.let { builder.addProperty(it) }
|
is FirProperty -> propertyProto(declaration)?.let { builder.addProperty(it) }
|
||||||
is FirSimpleFunction -> functionProto(declaration)?.let { builder.addFunction(it) }
|
is FirSimpleFunction -> functionProto(declaration)?.let { builder.addFunction(it) }
|
||||||
@@ -1042,7 +1046,7 @@ class FirElementSerializer private constructor(
|
|||||||
FirElementSerializer(
|
FirElementSerializer(
|
||||||
session, scopeSession, declaration, Interner(typeParameters), extension,
|
session, scopeSession, declaration, Interner(typeParameters), extension,
|
||||||
typeTable, versionRequirementTable, serializeTypeTableToFunction = false,
|
typeTable, versionRequirementTable, serializeTypeTableToFunction = false,
|
||||||
typeApproximator, languageVersionSettings
|
typeApproximator, languageVersionSettings, produceHeaderKlib
|
||||||
)
|
)
|
||||||
|
|
||||||
val stringTable: FirElementAwareStringTable
|
val stringTable: FirElementAwareStringTable
|
||||||
@@ -1148,6 +1152,7 @@ class FirElementSerializer private constructor(
|
|||||||
extension: FirSerializerExtension,
|
extension: FirSerializerExtension,
|
||||||
typeApproximator: AbstractTypeApproximator,
|
typeApproximator: AbstractTypeApproximator,
|
||||||
languageVersionSettings: LanguageVersionSettings,
|
languageVersionSettings: LanguageVersionSettings,
|
||||||
|
produceHeaderKlib: Boolean = false,
|
||||||
): FirElementSerializer =
|
): FirElementSerializer =
|
||||||
FirElementSerializer(
|
FirElementSerializer(
|
||||||
session, scopeSession, null,
|
session, scopeSession, null,
|
||||||
@@ -1155,6 +1160,7 @@ class FirElementSerializer private constructor(
|
|||||||
serializeTypeTableToFunction = false,
|
serializeTypeTableToFunction = false,
|
||||||
typeApproximator,
|
typeApproximator,
|
||||||
languageVersionSettings,
|
languageVersionSettings,
|
||||||
|
produceHeaderKlib,
|
||||||
)
|
)
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@@ -1171,6 +1177,7 @@ class FirElementSerializer private constructor(
|
|||||||
versionRequirementTable = null, serializeTypeTableToFunction = true,
|
versionRequirementTable = null, serializeTypeTableToFunction = true,
|
||||||
typeApproximator,
|
typeApproximator,
|
||||||
languageVersionSettings,
|
languageVersionSettings,
|
||||||
|
produceHeaderKlib = false,
|
||||||
)
|
)
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@@ -1182,16 +1189,17 @@ class FirElementSerializer private constructor(
|
|||||||
parentSerializer: FirElementSerializer?,
|
parentSerializer: FirElementSerializer?,
|
||||||
typeApproximator: AbstractTypeApproximator,
|
typeApproximator: AbstractTypeApproximator,
|
||||||
languageVersionSettings: LanguageVersionSettings,
|
languageVersionSettings: LanguageVersionSettings,
|
||||||
|
produceHeaderKlib: Boolean = false,
|
||||||
): FirElementSerializer {
|
): FirElementSerializer {
|
||||||
val parentClassId = klass.symbol.classId.outerClassId
|
val parentClassId = klass.symbol.classId.outerClassId
|
||||||
val parent = if (parentClassId != null && !parentClassId.isLocal) {
|
val parent = if (parentClassId != null && !parentClassId.isLocal) {
|
||||||
val parentClass = session.symbolProvider.getClassLikeSymbolByClassId(parentClassId)!!.fir as FirRegularClass
|
val parentClass = session.symbolProvider.getClassLikeSymbolByClassId(parentClassId)!!.fir as FirRegularClass
|
||||||
parentSerializer ?: create(
|
parentSerializer ?: create(
|
||||||
session, scopeSession, parentClass, extension, null, typeApproximator,
|
session, scopeSession, parentClass, extension, null, typeApproximator,
|
||||||
languageVersionSettings,
|
languageVersionSettings, produceHeaderKlib
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
createTopLevel(session, scopeSession, extension, typeApproximator, languageVersionSettings)
|
createTopLevel(session, scopeSession, extension, typeApproximator, languageVersionSettings, produceHeaderKlib)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate type parameter ids for the outer class beforehand, as it would've had happened if we were always
|
// Calculate type parameter ids for the outer class beforehand, as it would've had happened if we were always
|
||||||
@@ -1212,6 +1220,7 @@ class FirElementSerializer private constructor(
|
|||||||
serializeTypeTableToFunction = false,
|
serializeTypeTableToFunction = false,
|
||||||
typeApproximator,
|
typeApproximator,
|
||||||
languageVersionSettings,
|
languageVersionSettings,
|
||||||
|
produceHeaderKlib,
|
||||||
)
|
)
|
||||||
for (typeParameter in klass.typeParameters) {
|
for (typeParameter in klass.typeParameters) {
|
||||||
if (typeParameter !is FirTypeParameter) continue
|
if (typeParameter !is FirTypeParameter) continue
|
||||||
|
|||||||
+10
-4
@@ -22,12 +22,14 @@ fun serializeSingleFirFile(
|
|||||||
actualizedExpectDeclarations: Set<FirDeclaration>?,
|
actualizedExpectDeclarations: Set<FirDeclaration>?,
|
||||||
serializerExtension: FirKLibSerializerExtension,
|
serializerExtension: FirKLibSerializerExtension,
|
||||||
languageVersionSettings: LanguageVersionSettings,
|
languageVersionSettings: LanguageVersionSettings,
|
||||||
|
produceHeaderKlib: Boolean = false,
|
||||||
): ProtoBuf.PackageFragment {
|
): ProtoBuf.PackageFragment {
|
||||||
val approximator = TypeApproximatorForMetadataSerializer(session)
|
val approximator = TypeApproximatorForMetadataSerializer(session)
|
||||||
val packageSerializer = FirElementSerializer.createTopLevel(
|
val packageSerializer = FirElementSerializer.createTopLevel(
|
||||||
session, scopeSession, serializerExtension,
|
session, scopeSession, serializerExtension,
|
||||||
approximator,
|
approximator,
|
||||||
languageVersionSettings
|
languageVersionSettings,
|
||||||
|
produceHeaderKlib
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: typealiases (see klib serializer)
|
// TODO: typealiases (see klib serializer)
|
||||||
@@ -40,13 +42,16 @@ fun serializeSingleFirFile(
|
|||||||
|
|
||||||
fun List<FirClassSymbol<*>>.makeClassesProtoWithNested() {
|
fun List<FirClassSymbol<*>>.makeClassesProtoWithNested() {
|
||||||
val classSymbols = this
|
val classSymbols = this
|
||||||
.filter { it.fir.shouldBeSerialized(actualizedExpectDeclarations) }
|
.filter {
|
||||||
|
it.fir.isNotExpectOrShouldBeSerialized(actualizedExpectDeclarations) &&
|
||||||
|
it.fir.isNotPrivateOrShouldBeSerialized(produceHeaderKlib)
|
||||||
|
}
|
||||||
.sortedBy { it.classId.asFqNameString() }
|
.sortedBy { it.classId.asFqNameString() }
|
||||||
for (symbol in classSymbols) {
|
for (symbol in classSymbols) {
|
||||||
val klass = symbol.fir
|
val klass = symbol.fir
|
||||||
val classSerializer = FirElementSerializer.create(
|
val classSerializer = FirElementSerializer.create(
|
||||||
session, scopeSession, klass, serializerExtension, null,
|
session, scopeSession, klass, serializerExtension, null,
|
||||||
approximator, languageVersionSettings
|
approximator, languageVersionSettings, produceHeaderKlib
|
||||||
)
|
)
|
||||||
val index = classSerializer.stringTable.getFqNameIndex(klass)
|
val index = classSerializer.stringTable.getFqNameIndex(klass)
|
||||||
|
|
||||||
@@ -60,7 +65,8 @@ fun serializeSingleFirFile(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val hasTopLevelDeclarations = file.declarations.any {
|
val hasTopLevelDeclarations = file.declarations.any {
|
||||||
it is FirMemberDeclaration && it.shouldBeSerialized(actualizedExpectDeclarations) &&
|
it is FirMemberDeclaration && it.isNotExpectOrShouldBeSerialized(actualizedExpectDeclarations) &&
|
||||||
|
it.isNotPrivateOrShouldBeSerialized(produceHeaderKlib) &&
|
||||||
(it is FirProperty || it is FirSimpleFunction || it is FirTypeAlias)
|
(it is FirProperty || it is FirSimpleFunction || it is FirTypeAlias)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-1
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.fir.FirSession
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
|
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isExpect
|
import org.jetbrains.kotlin.fir.declarations.utils.isExpect
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.utils.visibility
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.ConeIntermediateDiagnostic
|
import org.jetbrains.kotlin.fir.diagnostics.ConeIntermediateDiagnostic
|
||||||
import org.jetbrains.kotlin.fir.languageVersionSettings
|
import org.jetbrains.kotlin.fir.languageVersionSettings
|
||||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||||
@@ -47,6 +48,10 @@ fun ConeKotlinType.suspendFunctionTypeToFunctionTypeWithContinuation(session: Fi
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun FirMemberDeclaration.shouldBeSerialized(actualizedExpectDeclaration: Set<FirDeclaration>?): Boolean {
|
fun FirMemberDeclaration.isNotExpectOrShouldBeSerialized(actualizedExpectDeclaration: Set<FirDeclaration>?): Boolean {
|
||||||
return !isExpect || actualizedExpectDeclaration == null || this !in actualizedExpectDeclaration
|
return !isExpect || actualizedExpectDeclaration == null || this !in actualizedExpectDeclaration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun FirMemberDeclaration.isNotPrivateOrShouldBeSerialized(produceHeaderKlib: Boolean): Boolean {
|
||||||
|
return !produceHeaderKlib || visibility.isPublicAPI
|
||||||
|
}
|
||||||
|
|||||||
+21
-5
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.library.impl.IrMemoryStringWriter
|
|||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
import org.jetbrains.kotlin.utils.filterIsInstanceAnd
|
import org.jetbrains.kotlin.utils.filterIsInstanceAnd
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.applyIf
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import org.jetbrains.kotlin.backend.common.serialization.proto.AccessorIdSignature as ProtoAccessorIdSignature
|
import org.jetbrains.kotlin.backend.common.serialization.proto.AccessorIdSignature as ProtoAccessorIdSignature
|
||||||
import org.jetbrains.kotlin.backend.common.serialization.proto.CommonIdSignature as ProtoCommonIdSignature
|
import org.jetbrains.kotlin.backend.common.serialization.proto.CommonIdSignature as ProtoCommonIdSignature
|
||||||
@@ -118,6 +119,7 @@ open class IrFileSerializer(
|
|||||||
private val languageVersionSettings: LanguageVersionSettings,
|
private val languageVersionSettings: LanguageVersionSettings,
|
||||||
private val bodiesOnlyForInlines: Boolean = false,
|
private val bodiesOnlyForInlines: Boolean = false,
|
||||||
private val normalizeAbsolutePaths: Boolean = false,
|
private val normalizeAbsolutePaths: Boolean = false,
|
||||||
|
private val skipPrivateApi: Boolean = false,
|
||||||
private val sourceBaseDirs: Collection<String>
|
private val sourceBaseDirs: Collection<String>
|
||||||
) {
|
) {
|
||||||
private val loopIndex = hashMapOf<IrLoop, Int>()
|
private val loopIndex = hashMapOf<IrLoop, Int>()
|
||||||
@@ -183,7 +185,11 @@ open class IrFileSerializer(
|
|||||||
private fun serializeIrStatementOrigin(origin: IrStatementOrigin): Int =
|
private fun serializeIrStatementOrigin(origin: IrStatementOrigin): Int =
|
||||||
serializeString((origin as? IrStatementOriginImpl)?.debugName ?: error("Unable to serialize origin ${origin.javaClass.name}"))
|
serializeString((origin as? IrStatementOriginImpl)?.debugName ?: error("Unable to serialize origin ${origin.javaClass.name}"))
|
||||||
|
|
||||||
private fun serializeCoordinates(start: Int, end: Int): Long = BinaryCoordinates.encode(start, end)
|
private fun serializeCoordinates(start: Int, end: Int): Long = if (skipPrivateApi) {
|
||||||
|
0L
|
||||||
|
} else {
|
||||||
|
BinaryCoordinates.encode(start, end)
|
||||||
|
}
|
||||||
|
|
||||||
/* ------- Strings ---------------------------------------------------------- */
|
/* ------- Strings ---------------------------------------------------------- */
|
||||||
|
|
||||||
@@ -1340,9 +1346,9 @@ open class IrFileSerializer(
|
|||||||
|
|
||||||
// ---------- Top level ------------------------------------------------------
|
// ---------- Top level ------------------------------------------------------
|
||||||
|
|
||||||
private fun serializeFileEntry(entry: IrFileEntry): ProtoFileEntry = ProtoFileEntry.newBuilder()
|
private fun serializeFileEntry(entry: IrFileEntry, includeLineStartOffsets: Boolean = true): ProtoFileEntry = ProtoFileEntry.newBuilder()
|
||||||
.setName(entry.matchAndNormalizeFilePath())
|
.setName(entry.matchAndNormalizeFilePath())
|
||||||
.addAllLineStartOffset(entry.lineStartOffsets.asIterable())
|
.applyIf(includeLineStartOffsets) { addAllLineStartOffset(entry.lineStartOffsets.asIterable()) }
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
open fun backendSpecificExplicitRoot(node: IrAnnotationContainer): Boolean = false
|
open fun backendSpecificExplicitRoot(node: IrAnnotationContainer): Boolean = false
|
||||||
@@ -1351,12 +1357,18 @@ open class IrFileSerializer(
|
|||||||
open fun backendSpecificSerializeAllMembers(irClass: IrClass) = false
|
open fun backendSpecificSerializeAllMembers(irClass: IrClass) = false
|
||||||
open fun backendSpecificMetadata(irFile: IrFile): FileBackendSpecificMetadata? = null
|
open fun backendSpecificMetadata(irFile: IrFile): FileBackendSpecificMetadata? = null
|
||||||
|
|
||||||
|
private fun skipIfPrivate(declaration: IrDeclaration) =
|
||||||
|
skipPrivateApi && (declaration as? IrDeclarationWithVisibility)?.visibility?.isPublicAPI != true
|
||||||
|
|
||||||
open fun memberNeedsSerialization(member: IrDeclaration): Boolean {
|
open fun memberNeedsSerialization(member: IrDeclaration): Boolean {
|
||||||
val parent = member.parent
|
val parent = member.parent
|
||||||
require(parent is IrClass)
|
require(parent is IrClass)
|
||||||
if (backendSpecificSerializeAllMembers(parent)) return true
|
if (backendSpecificSerializeAllMembers(parent)) return true
|
||||||
if (bodiesOnlyForInlines && member is IrAnonymousInitializer && parent.visibility != DescriptorVisibilities.LOCAL)
|
if (bodiesOnlyForInlines && member is IrAnonymousInitializer && parent.visibility != DescriptorVisibilities.LOCAL)
|
||||||
return false
|
return false
|
||||||
|
if (skipIfPrivate(member)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
return (!member.isFakeOverride)
|
return (!member.isFakeOverride)
|
||||||
}
|
}
|
||||||
@@ -1414,11 +1426,15 @@ open class IrFileSerializer(
|
|||||||
val topLevelDeclarations = mutableListOf<SerializedDeclaration>()
|
val topLevelDeclarations = mutableListOf<SerializedDeclaration>()
|
||||||
|
|
||||||
val proto = ProtoFile.newBuilder()
|
val proto = ProtoFile.newBuilder()
|
||||||
.setFileEntry(serializeFileEntry(file.fileEntry))
|
.setFileEntry(serializeFileEntry(file.fileEntry, includeLineStartOffsets = !skipPrivateApi))
|
||||||
.addAllFqName(serializeFqName(file.packageFqName.asString()))
|
.addAllFqName(serializeFqName(file.packageFqName.asString()))
|
||||||
.addAllAnnotation(serializeAnnotations(file.annotations))
|
.addAllAnnotation(serializeAnnotations(file.annotations))
|
||||||
|
|
||||||
file.declarations.forEach {
|
file.declarations.forEach {
|
||||||
|
if (skipIfPrivate(it)) {
|
||||||
|
// Skip the declaration if producing header klib and the declaration is not public.
|
||||||
|
return@forEach
|
||||||
|
}
|
||||||
if (it.descriptor.isExpectMember && !it.descriptor.isSerializableExpectClass) {
|
if (it.descriptor.isExpectMember && !it.descriptor.isSerializableExpectClass) {
|
||||||
// Skip the declaration unless it is `expect annotation class` marked with `OptionalExpectation`
|
// Skip the declaration unless it is `expect annotation class` marked with `OptionalExpectation`
|
||||||
// without the corresponding `actual` counterpart for the current leaf target.
|
// without the corresponding `actual` counterpart for the current leaf target.
|
||||||
@@ -1441,7 +1457,7 @@ open class IrFileSerializer(
|
|||||||
|
|
||||||
// Make sure that all top level properties are initialized on library's load.
|
// Make sure that all top level properties are initialized on library's load.
|
||||||
file.declarations
|
file.declarations
|
||||||
.filterIsInstanceAnd<IrProperty> { it.backingField?.initializer != null && keepOrderOfProperties(it) }
|
.filterIsInstanceAnd<IrProperty> { it.backingField?.initializer != null && keepOrderOfProperties(it) && !skipIfPrivate(it) }
|
||||||
.forEach {
|
.forEach {
|
||||||
val fieldSymbol = it.backingField?.symbol ?: error("Not found ID ${it.render()}")
|
val fieldSymbol = it.backingField?.symbol ?: error("Not found ID ${it.render()}")
|
||||||
proto.addExplicitlyExportedToCompiler(serializeIrSymbol(fieldSymbol))
|
proto.addExplicitlyExportedToCompiler(serializeIrSymbol(fieldSymbol))
|
||||||
|
|||||||
+3
-2
@@ -27,8 +27,9 @@ class KlibMetadataMonolithicSerializer(
|
|||||||
exportKDoc: Boolean,
|
exportKDoc: Boolean,
|
||||||
skipExpects: Boolean,
|
skipExpects: Boolean,
|
||||||
includeOnlyModuleContent: Boolean = false,
|
includeOnlyModuleContent: Boolean = false,
|
||||||
allowErrorTypes: Boolean = false
|
allowErrorTypes: Boolean = false,
|
||||||
) : KlibMetadataSerializer(languageVersionSettings, metadataVersion, project, exportKDoc, skipExpects, includeOnlyModuleContent, allowErrorTypes) {
|
produceHeaderKlib: Boolean = false,
|
||||||
|
) : KlibMetadataSerializer(languageVersionSettings, metadataVersion, project, exportKDoc, skipExpects, includeOnlyModuleContent, allowErrorTypes, produceHeaderKlib) {
|
||||||
|
|
||||||
private fun serializePackageFragment(fqName: FqName, module: ModuleDescriptor): List<ProtoBuf.PackageFragment> {
|
private fun serializePackageFragment(fqName: FqName, module: ModuleDescriptor): List<ProtoBuf.PackageFragment> {
|
||||||
|
|
||||||
|
|||||||
+18
-8
@@ -18,7 +18,7 @@ import org.jetbrains.kotlin.metadata.ProtoBuf
|
|||||||
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
|
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
|
||||||
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.resolve.descriptorUtil.fqNameSafe
|
import org.jetbrains.kotlin.resolve.descriptorUtil.*
|
||||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||||
import org.jetbrains.kotlin.serialization.ApproximatingStringTable
|
import org.jetbrains.kotlin.serialization.ApproximatingStringTable
|
||||||
import org.jetbrains.kotlin.serialization.DescriptorSerializer
|
import org.jetbrains.kotlin.serialization.DescriptorSerializer
|
||||||
@@ -36,7 +36,8 @@ abstract class KlibMetadataSerializer(
|
|||||||
val exportKDoc: Boolean = false,
|
val exportKDoc: Boolean = false,
|
||||||
val skipExpects: Boolean = false,
|
val skipExpects: Boolean = false,
|
||||||
val includeOnlyModuleContent: Boolean = false,
|
val includeOnlyModuleContent: Boolean = false,
|
||||||
private val allowErrorTypes: Boolean
|
private val allowErrorTypes: Boolean,
|
||||||
|
val produceHeaderKlib: Boolean = false,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
lateinit var serializerContext: SerializerContext
|
lateinit var serializerContext: SerializerContext
|
||||||
@@ -54,7 +55,8 @@ abstract class KlibMetadataSerializer(
|
|||||||
metadataVersion,
|
metadataVersion,
|
||||||
ApproximatingStringTable(),
|
ApproximatingStringTable(),
|
||||||
allowErrorTypes,
|
allowErrorTypes,
|
||||||
exportKDoc
|
exportKDoc,
|
||||||
|
produceHeaderKlib
|
||||||
)
|
)
|
||||||
return SerializerContext(
|
return SerializerContext(
|
||||||
extension,
|
extension,
|
||||||
@@ -94,8 +96,8 @@ abstract class KlibMetadataSerializer(
|
|||||||
// TODO: we filter out expects with present actuals.
|
// TODO: we filter out expects with present actuals.
|
||||||
// This is done because deserialized member scope doesn't give us actuals
|
// This is done because deserialized member scope doesn't give us actuals
|
||||||
// when it has a choice
|
// when it has a choice
|
||||||
private fun List<DeclarationDescriptor>.filterOutExpectsWithActuals(): List<DeclarationDescriptor> {
|
private fun Sequence<DeclarationDescriptor>.filterOutExpectsWithActuals(): Sequence<DeclarationDescriptor> {
|
||||||
val actualClassIds = this.filter{ !it.isExpectMember }.map { ClassId.topLevel(it.fqNameSafe) }
|
val actualClassIds = this.filter { !it.isExpectMember }.map { ClassId.topLevel(it.fqNameSafe) }
|
||||||
return this.filterNot {
|
return this.filterNot {
|
||||||
// TODO: this only filters classes for now.
|
// TODO: this only filters classes for now.
|
||||||
// Need to do the same for functions etc
|
// Need to do the same for functions etc
|
||||||
@@ -103,12 +105,20 @@ abstract class KlibMetadataSerializer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun List<DeclarationDescriptor>.filterOutExpects(): List<DeclarationDescriptor> =
|
private fun Sequence<DeclarationDescriptor>.filterOutExpects(): Sequence<DeclarationDescriptor> =
|
||||||
if (skipExpects)
|
if (skipExpects)
|
||||||
this.filterNot { it.isExpectMember && !it.isSerializableExpectClass }
|
this.filterNot { it.isExpectMember && !it.isSerializableExpectClass }
|
||||||
else
|
else
|
||||||
this.filterOutExpectsWithActuals()
|
this.filterOutExpectsWithActuals()
|
||||||
|
|
||||||
|
private fun Sequence<DeclarationDescriptor>.filterPrivate(): Sequence<DeclarationDescriptor> =
|
||||||
|
if (produceHeaderKlib) {
|
||||||
|
// We keep all interfaces since publicly accessible classes can inherit from private interfaces.
|
||||||
|
this.filter {
|
||||||
|
it is ClassDescriptor && it.kind.isInterface || it is DeclarationDescriptorWithVisibility && it.effectiveVisibility().publicApi
|
||||||
|
}
|
||||||
|
} else this
|
||||||
|
|
||||||
private fun serializeClasses(packageName: FqName,
|
private fun serializeClasses(packageName: FqName,
|
||||||
//builder: ProtoBuf.PackageFragment.Builder,
|
//builder: ProtoBuf.PackageFragment.Builder,
|
||||||
descriptors: Collection<DeclarationDescriptor>): List<Pair<ProtoBuf.Class, Int>> {
|
descriptors: Collection<DeclarationDescriptor>): List<Pair<ProtoBuf.Class, Int>> {
|
||||||
@@ -131,8 +141,8 @@ abstract class KlibMetadataSerializer(
|
|||||||
allTopLevelDescriptors: List<DeclarationDescriptor>
|
allTopLevelDescriptors: List<DeclarationDescriptor>
|
||||||
): List<ProtoBuf.PackageFragment> {
|
): List<ProtoBuf.PackageFragment> {
|
||||||
|
|
||||||
val classifierDescriptors = allClassifierDescriptors.filterOutExpects()
|
val classifierDescriptors = allClassifierDescriptors.asSequence().filterOutExpects().filterPrivate().toList()
|
||||||
val topLevelDescriptors = allTopLevelDescriptors.filterOutExpects()
|
val topLevelDescriptors = allTopLevelDescriptors.asSequence().filterOutExpects().filterPrivate().toList()
|
||||||
|
|
||||||
if (TOP_LEVEL_CLASS_DECLARATION_COUNT_PER_FILE == null &&
|
if (TOP_LEVEL_CLASS_DECLARATION_COUNT_PER_FILE == null &&
|
||||||
TOP_LEVEL_DECLARATION_COUNT_PER_FILE == null) {
|
TOP_LEVEL_DECLARATION_COUNT_PER_FILE == null) {
|
||||||
|
|||||||
+16
-2
@@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.backend.common.serialization.metadata
|
package org.jetbrains.kotlin.backend.common.serialization.metadata
|
||||||
|
|
||||||
import org.jetbrains.kotlin.config.LanguageFeature
|
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf
|
import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf
|
||||||
@@ -15,8 +14,10 @@ import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
|
|||||||
import org.jetbrains.kotlin.metadata.serialization.MutableVersionRequirementTable
|
import org.jetbrains.kotlin.metadata.serialization.MutableVersionRequirementTable
|
||||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||||
import org.jetbrains.kotlin.psi.KtPrimaryConstructor
|
import org.jetbrains.kotlin.psi.KtPrimaryConstructor
|
||||||
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.source.getPsi
|
import org.jetbrains.kotlin.resolve.source.getPsi
|
||||||
import org.jetbrains.kotlin.serialization.DescriptorSerializer
|
import org.jetbrains.kotlin.serialization.DescriptorSerializer
|
||||||
|
import org.jetbrains.kotlin.serialization.DescriptorSerializer.Companion.sort
|
||||||
import org.jetbrains.kotlin.serialization.KotlinSerializerExtensionBase
|
import org.jetbrains.kotlin.serialization.KotlinSerializerExtensionBase
|
||||||
import org.jetbrains.kotlin.serialization.StringTableImpl
|
import org.jetbrains.kotlin.serialization.StringTableImpl
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.DYNAMIC_TYPE_DESERIALIZER_ID
|
import org.jetbrains.kotlin.serialization.deserialization.DYNAMIC_TYPE_DESERIALIZER_ID
|
||||||
@@ -28,9 +29,22 @@ class KlibMetadataSerializerExtension(
|
|||||||
override val metadataVersion: BinaryVersion,
|
override val metadataVersion: BinaryVersion,
|
||||||
override val stringTable: StringTableImpl,
|
override val stringTable: StringTableImpl,
|
||||||
private val allowErrorTypes: Boolean,
|
private val allowErrorTypes: Boolean,
|
||||||
private val exportKDoc: Boolean
|
private val exportKDoc: Boolean,
|
||||||
|
private val produceHeaderKlib: Boolean
|
||||||
) : KotlinSerializerExtensionBase(KlibMetadataSerializerProtocol) {
|
) : KotlinSerializerExtensionBase(KlibMetadataSerializerProtocol) {
|
||||||
override fun shouldUseTypeTable(): Boolean = true
|
override fun shouldUseTypeTable(): Boolean = true
|
||||||
|
override val customClassMembersProducer: ClassMembersProducer?
|
||||||
|
get() = if (produceHeaderKlib)
|
||||||
|
object : ClassMembersProducer {
|
||||||
|
override fun getCallableMembers(classDescriptor: ClassDescriptor) =
|
||||||
|
sort(
|
||||||
|
DescriptorUtils.getAllDescriptors(classDescriptor.defaultType.memberScope)
|
||||||
|
.filterIsInstance<CallableMemberDescriptor>()
|
||||||
|
.filter { it.kind != CallableMemberDescriptor.Kind.FAKE_OVERRIDE }
|
||||||
|
.filter { it.visibility.isPublicAPI }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
else super.customClassMembersProducer
|
||||||
|
|
||||||
private fun descriptorFileId(descriptor: DeclarationDescriptorWithSource): Int? {
|
private fun descriptorFileId(descriptor: DeclarationDescriptorWithSource): Int? {
|
||||||
val fileName = descriptor.source.containingFile.name ?: return null
|
val fileName = descriptor.source.containingFile.name ?: return null
|
||||||
|
|||||||
+9
-4
@@ -163,10 +163,15 @@ class DescriptorSerializer private constructor(
|
|||||||
classDescriptor.inlineClassRepresentation?.let { inlineClassRepresentation ->
|
classDescriptor.inlineClassRepresentation?.let { inlineClassRepresentation ->
|
||||||
builder.inlineClassUnderlyingPropertyName = getSimpleNameIndex(inlineClassRepresentation.underlyingPropertyName)
|
builder.inlineClassUnderlyingPropertyName = getSimpleNameIndex(inlineClassRepresentation.underlyingPropertyName)
|
||||||
|
|
||||||
val property = callableMembers.single {
|
// The underlying property might be missing from `callableMembers` if we are producing a header klib and
|
||||||
it is PropertyDescriptor && it.extensionReceiverParameter == null && it.name == inlineClassRepresentation.underlyingPropertyName
|
// the inline class is a part of the public API but the underlying property is not.
|
||||||
}
|
val property = callableMembers.singleOrNull { candidate ->
|
||||||
if (!property.visibility.isPublicAPI) {
|
candidate is PropertyDescriptor
|
||||||
|
&& candidate.extensionReceiverParameter == null
|
||||||
|
&& candidate.name == inlineClassRepresentation.underlyingPropertyName
|
||||||
|
} ?: return@let
|
||||||
|
|
||||||
|
if (property.visibility.isPublicAPI) {
|
||||||
if (useTypeTable()) {
|
if (useTypeTable()) {
|
||||||
builder.inlineClassUnderlyingTypeId = typeId(inlineClassRepresentation.underlyingType)
|
builder.inlineClassUnderlyingTypeId = typeId(inlineClassRepresentation.underlyingType)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+19
-9
@@ -7,6 +7,7 @@ import org.jetbrains.kotlin.backend.common.serialization.metadata.serializeKlibH
|
|||||||
import org.jetbrains.kotlin.backend.konan.driver.PhaseContext
|
import org.jetbrains.kotlin.backend.konan.driver.PhaseContext
|
||||||
import org.jetbrains.kotlin.backend.konan.driver.phases.Fir2IrOutput
|
import org.jetbrains.kotlin.backend.konan.driver.phases.Fir2IrOutput
|
||||||
import org.jetbrains.kotlin.backend.konan.driver.phases.FirOutput
|
import org.jetbrains.kotlin.backend.konan.driver.phases.FirOutput
|
||||||
|
import org.jetbrains.kotlin.backend.konan.driver.phases.FirSerializerInput
|
||||||
import org.jetbrains.kotlin.backend.konan.driver.phases.SerializerOutput
|
import org.jetbrains.kotlin.backend.konan.driver.phases.SerializerOutput
|
||||||
import org.jetbrains.kotlin.backend.konan.serialization.KonanIrModuleSerializer
|
import org.jetbrains.kotlin.backend.konan.serialization.KonanIrModuleSerializer
|
||||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||||
@@ -34,11 +35,13 @@ internal fun PhaseContext.firSerializer(input: FirOutput): SerializerOutput? = w
|
|||||||
else -> firSerializerBase(input.firResult, null)
|
else -> firSerializerBase(input.firResult, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun PhaseContext.fir2IrSerializer(input: Fir2IrOutput) = firSerializerBase(input.firResult, input)
|
internal fun PhaseContext.fir2IrSerializer(input: FirSerializerInput) =
|
||||||
|
firSerializerBase(input.firToIrOutput.firResult, input.firToIrOutput, produceHeaderKlib = input.produceHeaderKlib)
|
||||||
|
|
||||||
internal fun PhaseContext.firSerializerBase(
|
internal fun PhaseContext.firSerializerBase(
|
||||||
firResult: FirResult,
|
firResult: FirResult,
|
||||||
fir2IrInput: Fir2IrOutput?,
|
fir2IrInput: Fir2IrOutput?,
|
||||||
|
produceHeaderKlib: Boolean = false,
|
||||||
): SerializerOutput {
|
): SerializerOutput {
|
||||||
val configuration = config.configuration
|
val configuration = config.configuration
|
||||||
val sourceFiles = mutableListOf<KtSourceFile>()
|
val sourceFiles = mutableListOf<KtSourceFile>()
|
||||||
@@ -71,6 +74,8 @@ internal fun PhaseContext.firSerializerBase(
|
|||||||
moduleName = fir2IrInput?.irModuleFragment?.descriptor?.name?.asString()
|
moduleName = fir2IrInput?.irModuleFragment?.descriptor?.name?.asString()
|
||||||
?: firResult.outputs.last().session.moduleData.name.asString(),
|
?: firResult.outputs.last().session.moduleData.name.asString(),
|
||||||
firFilesAndSessionsBySourceFile,
|
firFilesAndSessionsBySourceFile,
|
||||||
|
bodiesOnlyForInlines = produceHeaderKlib,
|
||||||
|
skipPrivateApi = produceHeaderKlib,
|
||||||
) { firFile, session, scopeSession ->
|
) { firFile, session, scopeSession ->
|
||||||
serializeSingleFirFile(
|
serializeSingleFirFile(
|
||||||
firFile,
|
firFile,
|
||||||
@@ -87,6 +92,7 @@ internal fun PhaseContext.firSerializerBase(
|
|||||||
additionalAnnotationsProvider = fir2IrInput?.components?.annotationsFromPluginRegistrar?.createMetadataAnnotationsProvider()
|
additionalAnnotationsProvider = fir2IrInput?.components?.annotationsFromPluginRegistrar?.createMetadataAnnotationsProvider()
|
||||||
),
|
),
|
||||||
configuration.languageVersionSettings,
|
configuration.languageVersionSettings,
|
||||||
|
produceHeaderKlib,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -102,14 +108,16 @@ class KotlinFileSerializedData(
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal fun PhaseContext.serializeNativeModule(
|
internal fun PhaseContext.serializeNativeModule(
|
||||||
configuration: CompilerConfiguration,
|
configuration: CompilerConfiguration,
|
||||||
messageLogger: IrMessageLogger,
|
messageLogger: IrMessageLogger,
|
||||||
files: List<KtSourceFile>,
|
files: List<KtSourceFile>,
|
||||||
dependencies: List<KonanLibrary>?,
|
dependencies: List<KonanLibrary>?,
|
||||||
moduleFragment: IrModuleFragment?,
|
moduleFragment: IrModuleFragment?,
|
||||||
moduleName: String,
|
moduleName: String,
|
||||||
firFilesAndSessionsBySourceFile: Map<KtSourceFile, Triple<FirFile, FirSession, ScopeSession>>,
|
firFilesAndSessionsBySourceFile: Map<KtSourceFile, Triple<FirFile, FirSession, ScopeSession>>,
|
||||||
serializeSingleFile: (FirFile, FirSession, ScopeSession) -> ProtoBuf.PackageFragment
|
bodiesOnlyForInlines: Boolean = false,
|
||||||
|
skipPrivateApi: Boolean = false,
|
||||||
|
serializeSingleFile: (FirFile, FirSession, ScopeSession) -> ProtoBuf.PackageFragment
|
||||||
): SerializerOutput {
|
): SerializerOutput {
|
||||||
if (moduleFragment != null) {
|
if (moduleFragment != null) {
|
||||||
assert(files.size == moduleFragment.files.size)
|
assert(files.size == moduleFragment.files.size)
|
||||||
@@ -126,6 +134,8 @@ internal fun PhaseContext.serializeNativeModule(
|
|||||||
normalizeAbsolutePaths = absolutePathNormalization,
|
normalizeAbsolutePaths = absolutePathNormalization,
|
||||||
sourceBaseDirs = sourceBaseDirs,
|
sourceBaseDirs = sourceBaseDirs,
|
||||||
languageVersionSettings = configuration.languageVersionSettings,
|
languageVersionSettings = configuration.languageVersionSettings,
|
||||||
|
bodiesOnlyForInlines = bodiesOnlyForInlines,
|
||||||
|
skipPrivateApi = skipPrivateApi
|
||||||
).serializedIrModule(moduleFragment)
|
).serializedIrModule(moduleFragment)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
@@ -225,6 +225,8 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
|
|||||||
|
|
||||||
internal val metadataKlib get() = configuration.get(KonanConfigKeys.METADATA_KLIB)!!
|
internal val metadataKlib get() = configuration.get(KonanConfigKeys.METADATA_KLIB)!!
|
||||||
|
|
||||||
|
internal val headerKlibPath get() = configuration.get(KonanConfigKeys.HEADER_KLIB)
|
||||||
|
|
||||||
internal val produceStaticFramework get() = configuration.getBoolean(KonanConfigKeys.STATIC_FRAMEWORK)
|
internal val produceStaticFramework get() = configuration.getBoolean(KonanConfigKeys.STATIC_FRAMEWORK)
|
||||||
|
|
||||||
internal val purgeUserLibs: Boolean
|
internal val purgeUserLibs: Boolean
|
||||||
|
|||||||
+2
@@ -75,6 +75,8 @@ class KonanConfigKeys {
|
|||||||
= CompilerConfigurationKey.create("provide manifest addend file")
|
= CompilerConfigurationKey.create("provide manifest addend file")
|
||||||
val METADATA_KLIB: CompilerConfigurationKey<Boolean>
|
val METADATA_KLIB: CompilerConfigurationKey<Boolean>
|
||||||
= CompilerConfigurationKey.create("metadata klib")
|
= CompilerConfigurationKey.create("metadata klib")
|
||||||
|
val HEADER_KLIB: CompilerConfigurationKey<String?>
|
||||||
|
= CompilerConfigurationKey.create("path to file where header klib should be produced")
|
||||||
val MODULE_NAME: CompilerConfigurationKey<String?>
|
val MODULE_NAME: CompilerConfigurationKey<String?>
|
||||||
= CompilerConfigurationKey.create("module name")
|
= CompilerConfigurationKey.create("module name")
|
||||||
val NATIVE_LIBRARY_FILES: CompilerConfigurationKey<List<String>>
|
val NATIVE_LIBRARY_FILES: CompilerConfigurationKey<List<String>>
|
||||||
|
|||||||
+1
@@ -56,6 +56,7 @@ fun CompilerConfiguration.setupFromArguments(arguments: K2NativeCompilerArgument
|
|||||||
(arguments.produce ?: "program").uppercase())
|
(arguments.produce ?: "program").uppercase())
|
||||||
put(PRODUCE, outputKind)
|
put(PRODUCE, outputKind)
|
||||||
put(METADATA_KLIB, arguments.metadataKlib)
|
put(METADATA_KLIB, arguments.metadataKlib)
|
||||||
|
putIfNotNull(HEADER_KLIB, arguments.headerKlibPath)
|
||||||
|
|
||||||
arguments.libraryVersion?.let { put(LIBRARY_VERSION, it) }
|
arguments.libraryVersion?.let { put(LIBRARY_VERSION, it) }
|
||||||
|
|
||||||
|
|||||||
+12
-1
@@ -108,8 +108,15 @@ internal class DynamicCompilerDriver : CompilerDriver() {
|
|||||||
engine.runFirSerializer(frontendOutput)
|
engine.runFirSerializer(frontendOutput)
|
||||||
} else {
|
} else {
|
||||||
val fir2IrOutput = engine.runFir2Ir(frontendOutput)
|
val fir2IrOutput = engine.runFir2Ir(frontendOutput)
|
||||||
|
|
||||||
|
val headerKlibPath = environment.configuration.get(KonanConfigKeys.HEADER_KLIB)
|
||||||
|
if (!headerKlibPath.isNullOrEmpty()) {
|
||||||
|
val headerKlib = engine.runFir2IrSerializer(FirSerializerInput(fir2IrOutput, produceHeaderKlib = true))
|
||||||
|
engine.writeKlib(headerKlib, headerKlibPath)
|
||||||
|
}
|
||||||
|
|
||||||
engine.runK2SpecialBackendChecks(fir2IrOutput)
|
engine.runK2SpecialBackendChecks(fir2IrOutput)
|
||||||
engine.runFir2IrSerializer(fir2IrOutput)
|
engine.runFir2IrSerializer(FirSerializerInput(fir2IrOutput))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,6 +131,10 @@ internal class DynamicCompilerDriver : CompilerDriver() {
|
|||||||
} else {
|
} else {
|
||||||
engine.runPsiToIr(frontendOutput, isProducingLibrary = true) as PsiToIrOutput.ForKlib
|
engine.runPsiToIr(frontendOutput, isProducingLibrary = true) as PsiToIrOutput.ForKlib
|
||||||
}
|
}
|
||||||
|
if (!config.headerKlibPath.isNullOrEmpty()) {
|
||||||
|
val headerKlib = engine.runSerializer(frontendOutput.moduleDescriptor, psiToIrOutput, produceHeaderKlib = true)
|
||||||
|
engine.writeKlib(headerKlib, config.headerKlibPath)
|
||||||
|
}
|
||||||
return engine.runSerializer(frontendOutput.moduleDescriptor, psiToIrOutput)
|
return engine.runSerializer(frontendOutput.moduleDescriptor, psiToIrOutput)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+10
-4
@@ -10,6 +10,12 @@ import org.jetbrains.kotlin.backend.konan.driver.PhaseEngine
|
|||||||
import org.jetbrains.kotlin.backend.konan.firSerializer
|
import org.jetbrains.kotlin.backend.konan.firSerializer
|
||||||
import org.jetbrains.kotlin.backend.konan.fir2IrSerializer
|
import org.jetbrains.kotlin.backend.konan.fir2IrSerializer
|
||||||
|
|
||||||
|
|
||||||
|
internal data class FirSerializerInput(
|
||||||
|
val firToIrOutput: Fir2IrOutput,
|
||||||
|
val produceHeaderKlib: Boolean = false,
|
||||||
|
)
|
||||||
|
|
||||||
internal val FirSerializerPhase = createSimpleNamedCompilerPhase<PhaseContext, FirOutput, SerializerOutput?>(
|
internal val FirSerializerPhase = createSimpleNamedCompilerPhase<PhaseContext, FirOutput, SerializerOutput?>(
|
||||||
"FirSerializer", "Fir serializer",
|
"FirSerializer", "Fir serializer",
|
||||||
outputIfNotEnabled = { _, _, _, _ -> SerializerOutput(null, null, null, listOf()) }
|
outputIfNotEnabled = { _, _, _, _ -> SerializerOutput(null, null, null, listOf()) }
|
||||||
@@ -17,10 +23,10 @@ internal val FirSerializerPhase = createSimpleNamedCompilerPhase<PhaseContext, F
|
|||||||
context.firSerializer(input)
|
context.firSerializer(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal val Fir2IrSerializerPhase = createSimpleNamedCompilerPhase<PhaseContext, Fir2IrOutput, SerializerOutput>(
|
internal val Fir2IrSerializerPhase = createSimpleNamedCompilerPhase<PhaseContext, FirSerializerInput, SerializerOutput>(
|
||||||
"Fir2IrSerializer", "Fir2Ir serializer",
|
"Fir2IrSerializer", "Fir2Ir serializer",
|
||||||
outputIfNotEnabled = { _, _, _, _ -> SerializerOutput(null, null, null, listOf()) }
|
outputIfNotEnabled = { _, _, _, _ -> SerializerOutput(null, null, null, listOf()) }
|
||||||
) { context: PhaseContext, input: Fir2IrOutput ->
|
) { context: PhaseContext, input: FirSerializerInput ->
|
||||||
context.fir2IrSerializer(input)
|
context.fir2IrSerializer(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,7 +37,7 @@ internal fun <T : PhaseContext> PhaseEngine<T>.runFirSerializer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal fun <T : PhaseContext> PhaseEngine<T>.runFir2IrSerializer(
|
internal fun <T : PhaseContext> PhaseEngine<T>.runFir2IrSerializer(
|
||||||
fir2irOutput: Fir2IrOutput
|
firSerializerInput: FirSerializerInput
|
||||||
): SerializerOutput {
|
): SerializerOutput {
|
||||||
return this.runPhase(Fir2IrSerializerPhase, fir2irOutput)
|
return this.runPhase(Fir2IrSerializerPhase, firSerializerInput)
|
||||||
}
|
}
|
||||||
+12
-8
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.library.SerializedMetadata
|
|||||||
internal data class SerializerInput(
|
internal data class SerializerInput(
|
||||||
val moduleDescriptor: ModuleDescriptor,
|
val moduleDescriptor: ModuleDescriptor,
|
||||||
val psiToIrOutput: PsiToIrOutput.ForKlib?,
|
val psiToIrOutput: PsiToIrOutput.ForKlib?,
|
||||||
|
val produceHeaderKlib: Boolean,
|
||||||
)
|
)
|
||||||
|
|
||||||
data class SerializerOutput(
|
data class SerializerOutput(
|
||||||
@@ -48,24 +49,27 @@ internal val SerializerPhase = createSimpleNamedCompilerPhase<PhaseContext, Seri
|
|||||||
normalizeAbsolutePaths = normalizeAbsolutePaths,
|
normalizeAbsolutePaths = normalizeAbsolutePaths,
|
||||||
sourceBaseDirs = relativePathBase,
|
sourceBaseDirs = relativePathBase,
|
||||||
languageVersionSettings = config.languageVersionSettings,
|
languageVersionSettings = config.languageVersionSettings,
|
||||||
|
bodiesOnlyForInlines = input.produceHeaderKlib,
|
||||||
|
skipPrivateApi = input.produceHeaderKlib,
|
||||||
).serializedIrModule(ir)
|
).serializedIrModule(ir)
|
||||||
}
|
}
|
||||||
|
|
||||||
val serializer = KlibMetadataMonolithicSerializer(
|
val serializer = KlibMetadataMonolithicSerializer(
|
||||||
config.configuration.languageVersionSettings,
|
config.configuration.languageVersionSettings,
|
||||||
config.configuration.get(CommonConfigurationKeys.METADATA_VERSION)!!,
|
config.configuration.get(CommonConfigurationKeys.METADATA_VERSION)!!,
|
||||||
config.project,
|
config.project,
|
||||||
exportKDoc = context.shouldExportKDoc(),
|
exportKDoc = context.shouldExportKDoc(),
|
||||||
!expectActualLinker, includeOnlyModuleContent = true)
|
!expectActualLinker, includeOnlyModuleContent = true, produceHeaderKlib = input.produceHeaderKlib)
|
||||||
val serializedMetadata = serializer.serializeModule(input.moduleDescriptor)
|
val serializedMetadata = serializer.serializeModule(input.moduleDescriptor)
|
||||||
val neededLibraries = config.librariesWithDependencies()
|
val neededLibraries = config.librariesWithDependencies()
|
||||||
SerializerOutput(serializedMetadata, serializedIr, null, neededLibraries)
|
SerializerOutput(serializedMetadata, serializedIr, null, neededLibraries)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun <T : PhaseContext> PhaseEngine<T>.runSerializer(
|
internal fun <T : PhaseContext> PhaseEngine<T>.runSerializer(
|
||||||
moduleDescriptor: ModuleDescriptor,
|
moduleDescriptor: ModuleDescriptor,
|
||||||
psiToIrResult: PsiToIrOutput.ForKlib?,
|
psiToIrResult: PsiToIrOutput.ForKlib?,
|
||||||
|
produceHeaderKlib: Boolean = false,
|
||||||
): SerializerOutput {
|
): SerializerOutput {
|
||||||
val input = SerializerInput(moduleDescriptor, psiToIrResult)
|
val input = SerializerInput(moduleDescriptor, psiToIrResult, produceHeaderKlib)
|
||||||
return this.runPhase(SerializerPhase, input)
|
return this.runPhase(SerializerPhase, input)
|
||||||
}
|
}
|
||||||
+14
-7
@@ -14,13 +14,19 @@ import org.jetbrains.kotlin.konan.library.impl.buildLibrary
|
|||||||
import org.jetbrains.kotlin.library.KotlinAbiVersion
|
import org.jetbrains.kotlin.library.KotlinAbiVersion
|
||||||
import org.jetbrains.kotlin.library.KotlinLibraryVersioning
|
import org.jetbrains.kotlin.library.KotlinLibraryVersioning
|
||||||
import org.jetbrains.kotlin.library.metadata.KlibMetadataVersion
|
import org.jetbrains.kotlin.library.metadata.KlibMetadataVersion
|
||||||
|
import org.jetbrains.kotlin.util.removeSuffixIfPresent
|
||||||
|
|
||||||
internal val WriteKlibPhase = createSimpleNamedCompilerPhase<PhaseContext, SerializerOutput>(
|
internal data class KlibWriterInput(
|
||||||
|
val serializerOutput: SerializerOutput,
|
||||||
|
val customOutputPath: String?
|
||||||
|
)
|
||||||
|
internal val WriteKlibPhase = createSimpleNamedCompilerPhase<PhaseContext, KlibWriterInput>(
|
||||||
"WriteKlib", "Write klib output",
|
"WriteKlib", "Write klib output",
|
||||||
) { context, input ->
|
) { context, input ->
|
||||||
val config = context.config
|
val config = context.config
|
||||||
val configuration = config.configuration
|
val configuration = config.configuration
|
||||||
val outputFiles = OutputFiles(config.outputPath, config.target, config.produce)
|
val outputFiles = OutputFiles(input.customOutputPath?.removeSuffixIfPresent(".klib")
|
||||||
|
?: config.outputPath, config.target, config.produce)
|
||||||
val nopack = configuration.getBoolean(KonanConfigKeys.NOPACK)
|
val nopack = configuration.getBoolean(KonanConfigKeys.NOPACK)
|
||||||
val output = outputFiles.klibOutputFileName(!nopack)
|
val output = outputFiles.klibOutputFileName(!nopack)
|
||||||
val libraryName = config.moduleId
|
val libraryName = config.moduleId
|
||||||
@@ -51,14 +57,14 @@ internal val WriteKlibPhase = createSimpleNamedCompilerPhase<PhaseContext, Seria
|
|||||||
(e.g. commonized cinterops, host vs client environment differences).
|
(e.g. commonized cinterops, host vs client environment differences).
|
||||||
*/
|
*/
|
||||||
val linkDependencies = if (context.config.metadataKlib) emptyList()
|
val linkDependencies = if (context.config.metadataKlib) emptyList()
|
||||||
else input.neededLibraries
|
else input.serializerOutput.neededLibraries
|
||||||
|
|
||||||
buildLibrary(
|
buildLibrary(
|
||||||
natives = config.nativeLibraries,
|
natives = config.nativeLibraries,
|
||||||
included = config.includeBinaries,
|
included = config.includeBinaries,
|
||||||
linkDependencies = linkDependencies,
|
linkDependencies = linkDependencies,
|
||||||
metadata = input.serializedMetadata!!,
|
metadata = input.serializerOutput.serializedMetadata!!,
|
||||||
ir = input.serializedIr,
|
ir = input.serializerOutput.serializedIr,
|
||||||
versions = versions,
|
versions = versions,
|
||||||
target = target,
|
target = target,
|
||||||
output = output,
|
output = output,
|
||||||
@@ -66,12 +72,13 @@ internal val WriteKlibPhase = createSimpleNamedCompilerPhase<PhaseContext, Seria
|
|||||||
nopack = nopack,
|
nopack = nopack,
|
||||||
shortName = shortLibraryName,
|
shortName = shortLibraryName,
|
||||||
manifestProperties = manifestProperties,
|
manifestProperties = manifestProperties,
|
||||||
dataFlowGraph = input.dataFlowGraph
|
dataFlowGraph = input.serializerOutput.dataFlowGraph
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun <T : PhaseContext> PhaseEngine<T>.writeKlib(
|
internal fun <T : PhaseContext> PhaseEngine<T>.writeKlib(
|
||||||
serializationOutput: SerializerOutput,
|
serializationOutput: SerializerOutput,
|
||||||
|
customOutputPath: String? = null,
|
||||||
) {
|
) {
|
||||||
this.runPhase(WriteKlibPhase, serializationOutput)
|
this.runPhase(WriteKlibPhase, KlibWriterInput(serializationOutput, customOutputPath))
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-14
@@ -12,21 +12,23 @@ import org.jetbrains.kotlin.ir.util.IrMessageLogger
|
|||||||
import org.jetbrains.kotlin.ir.util.hasAnnotation
|
import org.jetbrains.kotlin.ir.util.hasAnnotation
|
||||||
|
|
||||||
class KonanIrFileSerializer(
|
class KonanIrFileSerializer(
|
||||||
messageLogger: IrMessageLogger,
|
messageLogger: IrMessageLogger,
|
||||||
declarationTable: DeclarationTable,
|
declarationTable: DeclarationTable,
|
||||||
languageVersionSettings: LanguageVersionSettings,
|
languageVersionSettings: LanguageVersionSettings,
|
||||||
bodiesOnlyForInlines: Boolean = false,
|
bodiesOnlyForInlines: Boolean = false,
|
||||||
compatibilityMode: CompatibilityMode,
|
compatibilityMode: CompatibilityMode,
|
||||||
normalizeAbsolutePaths: Boolean,
|
normalizeAbsolutePaths: Boolean,
|
||||||
sourceBaseDirs: Collection<String>
|
sourceBaseDirs: Collection<String>,
|
||||||
|
skipPrivateApi: Boolean = false,
|
||||||
) : IrFileSerializer(
|
) : IrFileSerializer(
|
||||||
messageLogger = messageLogger,
|
messageLogger,
|
||||||
declarationTable = declarationTable,
|
declarationTable,
|
||||||
compatibilityMode = compatibilityMode,
|
compatibilityMode,
|
||||||
languageVersionSettings = languageVersionSettings,
|
languageVersionSettings,
|
||||||
bodiesOnlyForInlines = bodiesOnlyForInlines,
|
skipPrivateApi = skipPrivateApi,
|
||||||
normalizeAbsolutePaths = normalizeAbsolutePaths,
|
bodiesOnlyForInlines = bodiesOnlyForInlines,
|
||||||
sourceBaseDirs = sourceBaseDirs
|
normalizeAbsolutePaths = normalizeAbsolutePaths,
|
||||||
|
sourceBaseDirs = sourceBaseDirs
|
||||||
) {
|
) {
|
||||||
|
|
||||||
override fun backendSpecificExplicitRoot(node: IrAnnotationContainer): Boolean {
|
override fun backendSpecificExplicitRoot(node: IrAnnotationContainer): Boolean {
|
||||||
|
|||||||
+5
-1
@@ -15,6 +15,8 @@ class KonanIrModuleSerializer(
|
|||||||
normalizeAbsolutePaths: Boolean,
|
normalizeAbsolutePaths: Boolean,
|
||||||
sourceBaseDirs: Collection<String>,
|
sourceBaseDirs: Collection<String>,
|
||||||
private val languageVersionSettings: LanguageVersionSettings,
|
private val languageVersionSettings: LanguageVersionSettings,
|
||||||
|
private val bodiesOnlyForInlines: Boolean = false,
|
||||||
|
private val skipPrivateApi: Boolean = false,
|
||||||
) : IrModuleSerializer<KonanIrFileSerializer>(messageLogger, compatibilityMode, normalizeAbsolutePaths, sourceBaseDirs) {
|
) : IrModuleSerializer<KonanIrFileSerializer>(messageLogger, compatibilityMode, normalizeAbsolutePaths, sourceBaseDirs) {
|
||||||
|
|
||||||
private val globalDeclarationTable = KonanGlobalDeclarationTable(irBuiltIns)
|
private val globalDeclarationTable = KonanGlobalDeclarationTable(irBuiltIns)
|
||||||
@@ -33,5 +35,7 @@ class KonanIrModuleSerializer(
|
|||||||
compatibilityMode = compatibilityMode,
|
compatibilityMode = compatibilityMode,
|
||||||
normalizeAbsolutePaths = normalizeAbsolutePaths,
|
normalizeAbsolutePaths = normalizeAbsolutePaths,
|
||||||
sourceBaseDirs = sourceBaseDirs,
|
sourceBaseDirs = sourceBaseDirs,
|
||||||
languageVersionSettings = languageVersionSettings)
|
languageVersionSettings = languageVersionSettings,
|
||||||
|
bodiesOnlyForInlines = bodiesOnlyForInlines,
|
||||||
|
skipPrivateApi = skipPrivateApi)
|
||||||
}
|
}
|
||||||
|
|||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
private val x = object { fun f() = 1 }
|
||||||
|
|
||||||
|
fun g() =
|
||||||
|
x.f() +
|
||||||
|
object { fun f() = 0 }.f()
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
fun g() = 1
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
class Class
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
open class Class
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
class A {
|
||||||
|
val publicVal = 0
|
||||||
|
fun publicMethod() = 0
|
||||||
|
|
||||||
|
internal val internalVal = 0
|
||||||
|
internal fun internalMethod() = 0
|
||||||
|
|
||||||
|
protected val protectedVal = 0
|
||||||
|
protected fun protectedMethod() = 0
|
||||||
|
|
||||||
|
private val privateVal = 0
|
||||||
|
private fun privateMethod() = 0
|
||||||
|
|
||||||
|
val publicValBody = internalMethod() + privateMethod() + 2
|
||||||
|
val publicMethodBody = publicValBody + 2
|
||||||
|
}
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
class A {
|
||||||
|
val publicVal = 0
|
||||||
|
fun publicMethod() = 0
|
||||||
|
|
||||||
|
internal val internalVal = 42
|
||||||
|
internal fun internalMethod() = 42
|
||||||
|
|
||||||
|
protected val protectedVal = 0
|
||||||
|
protected fun protectedMethod() = 0
|
||||||
|
|
||||||
|
val publicValBody = internalMethod() + 1
|
||||||
|
val publicMethodBody = publicValBody + 1
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
const val x = 0
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
const val x = 1
|
||||||
Vendored
+4
@@ -0,0 +1,4 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
inline fun f() = 1
|
||||||
|
inline fun g() = 2
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
inline fun g() = 2
|
||||||
|
|
||||||
|
inline fun f() = 1
|
||||||
|
|
||||||
|
// This changes the line numbers in f, g
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
fun sum(x: Int, y: Int): Int =
|
||||||
|
try {
|
||||||
|
var result = x
|
||||||
|
result += y
|
||||||
|
result
|
||||||
|
} finally {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
fun sum(x: Int, y: Int): Int = y + x
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
private class A {
|
||||||
|
inline fun test(crossinline s: () -> Unit) {
|
||||||
|
object {
|
||||||
|
fun run() {
|
||||||
|
s()
|
||||||
|
}
|
||||||
|
}.run()
|
||||||
|
}
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
private class A {
|
||||||
|
inline fun test(crossinline s: () -> Unit) {
|
||||||
|
object {
|
||||||
|
fun run() {
|
||||||
|
//s()
|
||||||
|
}
|
||||||
|
}.run()
|
||||||
|
}
|
||||||
|
}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
class A {
|
||||||
|
private class B {
|
||||||
|
inline fun test(crossinline s: () -> Unit) {
|
||||||
|
object {
|
||||||
|
fun run() {
|
||||||
|
s()
|
||||||
|
}
|
||||||
|
}.run()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
class A {
|
||||||
|
private class B {
|
||||||
|
inline fun test(crossinline s: () -> Unit) {
|
||||||
|
object {
|
||||||
|
fun run() {
|
||||||
|
//s()
|
||||||
|
}
|
||||||
|
}.run()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+3
@@ -0,0 +1,3 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
inline fun sum(x: Int, y: Int): Int = x + y
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
inline fun sum(x: Int, y: Int): Int = y + x
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
private inline fun f() = { 1 }()
|
||||||
|
fun g() = f()
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
fun g() = 1
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
fun id(x: Int): Int = x
|
||||||
Vendored
+3
@@ -0,0 +1,3 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
fun id(y: Int): Int = y
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
private interface A {
|
||||||
|
fun foo() = 0
|
||||||
|
fun bar(): String
|
||||||
|
}
|
||||||
|
|
||||||
|
class B: A {
|
||||||
|
override fun bar() = "test${foo()}"
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
private interface A {
|
||||||
|
fun foo() = 42
|
||||||
|
fun bar(): String
|
||||||
|
}
|
||||||
|
|
||||||
|
class B: A {
|
||||||
|
override fun bar() = "test${foo()}"
|
||||||
|
}
|
||||||
Vendored
+13
@@ -0,0 +1,13 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
class PublicClass1
|
||||||
|
class PublicClass2
|
||||||
|
|
||||||
|
typealias PublicTypeAlias1 = PublicClass1
|
||||||
|
typealias PublicTypeAlias2 = PublicClass1
|
||||||
|
|
||||||
|
internal typealias InternalTypeAlias1 = PublicClass1
|
||||||
|
internal typealias InternalTypeAlias2 = PublicClass1
|
||||||
|
|
||||||
|
private typealias PrivateTypeAlias1 = PublicClass1
|
||||||
|
private typealias PrivateTypeAlias2 = PublicClass1
|
||||||
Vendored
+12
@@ -0,0 +1,12 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
class PublicClass1
|
||||||
|
class PublicClass2
|
||||||
|
|
||||||
|
typealias PublicTypeAlias1 = PublicClass1
|
||||||
|
typealias PublicTypeAlias2 = PublicClass1
|
||||||
|
|
||||||
|
internal typealias InternalTypeAlias1 = PublicClass1
|
||||||
|
internal typealias InternalTypeAlias2 = PublicClass1
|
||||||
|
|
||||||
|
private typealias PrivateTypeAlias1 = PublicClass2
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
fun foo() = 0
|
||||||
Vendored
+3
@@ -0,0 +1,3 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
fun foo() = "0"
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
open class A
|
||||||
|
class B : A()
|
||||||
Vendored
+4
@@ -0,0 +1,4 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
open class A
|
||||||
|
class B
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
private val x = 1
|
||||||
|
|
||||||
|
object A { fun f() = x }
|
||||||
|
|
||||||
|
val y = 2
|
||||||
Vendored
+5
@@ -0,0 +1,5 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
object A { fun f() = 1 }
|
||||||
|
|
||||||
|
val y = 2
|
||||||
Vendored
+13
@@ -0,0 +1,13 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
val publicVal = 0
|
||||||
|
const val publicConst = 0
|
||||||
|
fun publicFun() = 0
|
||||||
|
|
||||||
|
internal val internalVal = 0
|
||||||
|
internal const val internalConst = 0
|
||||||
|
internal fun internalFun() = 0
|
||||||
|
|
||||||
|
private val privateVal = 0
|
||||||
|
private const val privateConst = 0
|
||||||
|
private fun privateFun() = 0
|
||||||
Vendored
+9
@@ -0,0 +1,9 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
val publicVal = 0
|
||||||
|
const val publicConst = 0
|
||||||
|
fun publicFun() = 0
|
||||||
|
|
||||||
|
internal val internalVal = 0
|
||||||
|
internal const val internalConst = 0
|
||||||
|
internal fun internalFun() = 0
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
package lib
|
||||||
|
|
||||||
|
interface Interface {
|
||||||
|
fun getInt(): Int
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getInterface(): Interface =
|
||||||
|
object : Interface {
|
||||||
|
override fun getInt(): Int = 10
|
||||||
|
}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
package app
|
||||||
|
|
||||||
|
import lib.*
|
||||||
|
|
||||||
|
fun runAppAndReturnOk(): String {
|
||||||
|
val i = getInterface()
|
||||||
|
val value = i.getInt()
|
||||||
|
if (value != 10) error("getInterface().getInt() is '$value', but is expected to be '10'")
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+31
@@ -0,0 +1,31 @@
|
|||||||
|
package lib
|
||||||
|
|
||||||
|
interface I {
|
||||||
|
val iProperty: Int
|
||||||
|
fun iMethod(): Int
|
||||||
|
}
|
||||||
|
|
||||||
|
open class A : I {
|
||||||
|
override val iProperty: Int = 0
|
||||||
|
override fun iMethod(): Int = 10
|
||||||
|
|
||||||
|
val aProperty: Int = 20
|
||||||
|
fun aMethod(): Int = 30
|
||||||
|
inline fun aInlineMethod(): Int = 40
|
||||||
|
|
||||||
|
private class AB {}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val aConst: Int = 50
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class B : A() {
|
||||||
|
val bProperty: Int = 60
|
||||||
|
fun bMethod(): Int = 70
|
||||||
|
inline fun bInlineMethod(): Int = 80
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val bConst: Int = 90
|
||||||
|
}
|
||||||
|
}
|
||||||
+40
@@ -0,0 +1,40 @@
|
|||||||
|
package app
|
||||||
|
|
||||||
|
import lib.*
|
||||||
|
|
||||||
|
fun useI(i: I) {
|
||||||
|
i.iProperty
|
||||||
|
i.iMethod()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun useA(a: A) {
|
||||||
|
a.iProperty
|
||||||
|
a.iMethod()
|
||||||
|
|
||||||
|
a.aProperty
|
||||||
|
a.aMethod()
|
||||||
|
a.aInlineMethod()
|
||||||
|
A.aConst
|
||||||
|
}
|
||||||
|
|
||||||
|
fun useB(b: B) {
|
||||||
|
b.iProperty
|
||||||
|
b.iMethod()
|
||||||
|
|
||||||
|
b.aProperty
|
||||||
|
b.aMethod()
|
||||||
|
b.aInlineMethod()
|
||||||
|
|
||||||
|
b.bProperty
|
||||||
|
b.bMethod()
|
||||||
|
b.bInlineMethod()
|
||||||
|
B.bConst
|
||||||
|
}
|
||||||
|
|
||||||
|
fun runAppAndReturnOk(): String {
|
||||||
|
useI(A())
|
||||||
|
useA(A())
|
||||||
|
useB(B())
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
package lib
|
||||||
|
|
||||||
|
object Object {
|
||||||
|
val x = 1
|
||||||
|
val y = 2
|
||||||
|
val z = x + y
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
package lib
|
||||||
|
|
||||||
|
val x = 1
|
||||||
|
val y = 2
|
||||||
|
val z = x + y
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
package app
|
||||||
|
|
||||||
|
import lib.*
|
||||||
|
|
||||||
|
fun runAppAndReturnOk(): String {
|
||||||
|
if (Object.z != 3) error("lib.Object.z is ${Object.z}, but '3' was expected")
|
||||||
|
if (z != 3) error("lib.z is $z, but '3' was expected")
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
Vendored
+5
@@ -0,0 +1,5 @@
|
|||||||
|
package lib
|
||||||
|
|
||||||
|
annotation class A(val value: String)
|
||||||
|
|
||||||
|
inline fun a() = A("OK")
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
package app
|
||||||
|
|
||||||
|
import lib.*
|
||||||
|
|
||||||
|
fun runAppAndReturnOk(): String {
|
||||||
|
return a().value
|
||||||
|
}
|
||||||
Vendored
+11
@@ -0,0 +1,11 @@
|
|||||||
|
package lib
|
||||||
|
|
||||||
|
interface Interface {
|
||||||
|
fun getInt(): Int
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun getCounter(crossinline init: () -> Int): Interface =
|
||||||
|
object : Interface {
|
||||||
|
var value = init()
|
||||||
|
override fun getInt(): Int = value++
|
||||||
|
}
|
||||||
Vendored
+13
@@ -0,0 +1,13 @@
|
|||||||
|
package app
|
||||||
|
|
||||||
|
import lib.*
|
||||||
|
|
||||||
|
fun runAppAndReturnOk(): String {
|
||||||
|
val a = lib.getCounter { 100 }
|
||||||
|
val x = a.getInt()
|
||||||
|
if (x != 100) error("a returned $x but expected '100'")
|
||||||
|
val y = a.getInt()
|
||||||
|
if (y != 101) error("a returned $y but expected '101'")
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
package lib
|
||||||
|
|
||||||
|
fun inlineCapture(s: String): String {
|
||||||
|
return with(StringBuilder()) {
|
||||||
|
val o = object {
|
||||||
|
override fun toString() = s
|
||||||
|
}
|
||||||
|
append(o)
|
||||||
|
}.toString()
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
package app
|
||||||
|
|
||||||
|
import lib.*
|
||||||
|
|
||||||
|
fun runAppAndReturnOk(): String {
|
||||||
|
return inlineCapture("OK")
|
||||||
|
}
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
package lib
|
||||||
|
|
||||||
|
var result = "fail"
|
||||||
|
|
||||||
|
inline fun foo(crossinline s: () -> String) {
|
||||||
|
object {
|
||||||
|
private inline fun test(crossinline z: () -> String) {
|
||||||
|
result = object { //should be marked as public abi as there is no regenerated abject on inline
|
||||||
|
fun run(): String {
|
||||||
|
return "O"
|
||||||
|
}
|
||||||
|
}.run() + z()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo() {
|
||||||
|
test { s() }
|
||||||
|
}
|
||||||
|
}.foo()
|
||||||
|
}
|
||||||
Vendored
+10
@@ -0,0 +1,10 @@
|
|||||||
|
package app
|
||||||
|
|
||||||
|
import lib.*
|
||||||
|
|
||||||
|
fun runAppAndReturnOk(): String {
|
||||||
|
foo {
|
||||||
|
"K"
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
Vendored
+4
@@ -0,0 +1,4 @@
|
|||||||
|
package lib
|
||||||
|
|
||||||
|
inline fun <reified T> safeCall(x: Any?, fn: (T) -> T): T? =
|
||||||
|
if (x is T) fn(x) else null
|
||||||
Vendored
+13
@@ -0,0 +1,13 @@
|
|||||||
|
package app
|
||||||
|
|
||||||
|
import lib.*
|
||||||
|
|
||||||
|
fun runAppAndReturnOk(): String {
|
||||||
|
val a = safeCall<Int>(10) { it * it }
|
||||||
|
if (a != 100) error("a is '$a', but is expected to be '100'")
|
||||||
|
|
||||||
|
val b = safeCall<Int>(null) { it * it }
|
||||||
|
if (b != null) error("b is '$b', but is expected to be 'null'")
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
package lib
|
||||||
|
|
||||||
|
enum class E {
|
||||||
|
A, B
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun value(x: E) = when (x) {
|
||||||
|
E.A -> "OK"
|
||||||
|
E.B -> "Fail"
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
package app
|
||||||
|
|
||||||
|
import lib.*
|
||||||
|
|
||||||
|
fun runAppAndReturnOk(): String = value(E.A)
|
||||||
Vendored
+19
@@ -0,0 +1,19 @@
|
|||||||
|
package lib
|
||||||
|
|
||||||
|
var result = "fail"
|
||||||
|
|
||||||
|
inline fun foo(crossinline s: () -> String) {
|
||||||
|
object {
|
||||||
|
private inline fun test(crossinline z: () -> String) {
|
||||||
|
object {
|
||||||
|
fun run() {
|
||||||
|
result = z()
|
||||||
|
}
|
||||||
|
}.run()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo() {
|
||||||
|
test { s() } // regenerated object should be marked as public abi
|
||||||
|
}
|
||||||
|
}.foo()
|
||||||
|
}
|
||||||
Vendored
+10
@@ -0,0 +1,10 @@
|
|||||||
|
package app
|
||||||
|
|
||||||
|
import lib.*
|
||||||
|
|
||||||
|
fun runAppAndReturnOk(): String {
|
||||||
|
foo {
|
||||||
|
"OK"
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
package lib
|
||||||
|
|
||||||
|
inline fun anInlineFunction(crossinline crossInlineLamba: () -> Unit) {
|
||||||
|
Foo().apply {
|
||||||
|
barMethod { crossInlineLamba() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Foo {
|
||||||
|
fun barMethod(aLambda: () -> Unit) { aLambda() }
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
package app
|
||||||
|
|
||||||
|
import lib.*
|
||||||
|
|
||||||
|
fun runAppAndReturnOk(): String {
|
||||||
|
var result = "Fail"
|
||||||
|
anInlineFunction { result = "OK" }
|
||||||
|
return result
|
||||||
|
}
|
||||||
Vendored
+7
@@ -0,0 +1,7 @@
|
|||||||
|
package lib
|
||||||
|
|
||||||
|
class A private constructor(val x: Int) {
|
||||||
|
companion object {
|
||||||
|
fun create(x: Int): A = A(x * 2)
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+10
@@ -0,0 +1,10 @@
|
|||||||
|
package app
|
||||||
|
|
||||||
|
import lib.*
|
||||||
|
|
||||||
|
fun runAppAndReturnOk(): String {
|
||||||
|
val a = A.create(10)
|
||||||
|
if (a.x != 20) error("a.x is '${a.x}', but is expected to be '20'")
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
Vendored
+6
@@ -0,0 +1,6 @@
|
|||||||
|
package lib
|
||||||
|
|
||||||
|
value class A private constructor(val value: String) {
|
||||||
|
companion object { fun a() = A("OK") }
|
||||||
|
inline fun b() = value
|
||||||
|
}
|
||||||
native/native.tests/testData/klib/header-klibs/compilation/privateValueClassConstructor/main/main.kt
Vendored
+7
@@ -0,0 +1,7 @@
|
|||||||
|
package app
|
||||||
|
|
||||||
|
import lib.*
|
||||||
|
|
||||||
|
fun runAppAndReturnOk(): String {
|
||||||
|
return A.a().b()
|
||||||
|
}
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
package lib
|
||||||
|
|
||||||
|
val prop: Int = 1
|
||||||
|
fun func(): Int = 2
|
||||||
|
inline fun inlineFunc(): Int = 3
|
||||||
|
const val constant: Int = 4
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
package app
|
||||||
|
|
||||||
|
import lib.*
|
||||||
|
|
||||||
|
fun runAppAndReturnOk(): String {
|
||||||
|
if (prop != 1) error("prop is '$prop', but is expected to be '1'")
|
||||||
|
val funcValue = func()
|
||||||
|
if (funcValue != 2) error("func() is '$funcValue', but is expected to be '2'")
|
||||||
|
val inlineFuncValue = inlineFunc()
|
||||||
|
if (inlineFuncValue != 3) error("inlineFunc() is '$inlineFuncValue', but is expected to be '3'")
|
||||||
|
if (constant != 4) error("constant is '$constant', but is expected to be '4'")
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+132
@@ -0,0 +1,132 @@
|
|||||||
|
/*
|
||||||
|
* 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.konan.blackboxtest;
|
||||||
|
|
||||||
|
import com.intellij.testFramework.TestDataPath;
|
||||||
|
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||||
|
import org.junit.jupiter.api.Tag;
|
||||||
|
import org.jetbrains.kotlin.konan.blackboxtest.support.group.FirPipeline;
|
||||||
|
import org.jetbrains.kotlin.test.TestMetadata;
|
||||||
|
import org.junit.jupiter.api.Nested;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.GenerateNativeTestsKt}. DO NOT MODIFY MANUALLY */
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
@TestMetadata("native/native.tests/testData/klib/header-klibs/comparison")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@Tag("frontend-fir")
|
||||||
|
@FirPipeline()
|
||||||
|
public class FirNativeHeaderKlibComparisonTestGenerated extends AbstractNativeHeaderKlibComparisonTest {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInComparison() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("native/native.tests/testData/klib/header-klibs/comparison"), Pattern.compile("^([^\\.]+)$"), null, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("anonymousObjects")
|
||||||
|
public void testAnonymousObjects() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/comparison/anonymousObjects/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("classFlags")
|
||||||
|
public void testClassFlags() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/comparison/classFlags/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("classPrivateMembers")
|
||||||
|
public void testClassPrivateMembers() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/comparison/classPrivateMembers/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("constant")
|
||||||
|
public void testConstant() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/comparison/constant/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("declarationOrderInline")
|
||||||
|
public void testDeclarationOrderInline() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/comparison/declarationOrderInline/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("functionBody")
|
||||||
|
public void testFunctionBody() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/comparison/functionBody/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("inlineFunInPrivateClass")
|
||||||
|
public void testInlineFunInPrivateClass() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/comparison/inlineFunInPrivateClass/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("inlineFunInPrivateNestedClass")
|
||||||
|
public void testInlineFunInPrivateNestedClass() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/comparison/inlineFunInPrivateNestedClass/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("inlineFunctionBody")
|
||||||
|
public void testInlineFunctionBody() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/comparison/inlineFunctionBody/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("lambdas")
|
||||||
|
public void testLambdas() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/comparison/lambdas/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("parameterName")
|
||||||
|
public void testParameterName() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/comparison/parameterName/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateInterface")
|
||||||
|
public void testPrivateInterface() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/comparison/privateInterface/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateTypealias")
|
||||||
|
public void testPrivateTypealias() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/comparison/privateTypealias/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("returnType")
|
||||||
|
public void testReturnType() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/comparison/returnType/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("superClass")
|
||||||
|
public void testSuperClass() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/comparison/superClass/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("syntheticAccessors")
|
||||||
|
public void testSyntheticAccessors() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/comparison/syntheticAccessors/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("topLevelPrivateMembers")
|
||||||
|
public void testTopLevelPrivateMembers() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/comparison/topLevelPrivateMembers/");
|
||||||
|
}
|
||||||
|
}
|
||||||
+114
@@ -0,0 +1,114 @@
|
|||||||
|
/*
|
||||||
|
* 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.konan.blackboxtest;
|
||||||
|
|
||||||
|
import com.intellij.testFramework.TestDataPath;
|
||||||
|
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||||
|
import org.junit.jupiter.api.Tag;
|
||||||
|
import org.jetbrains.kotlin.konan.blackboxtest.support.group.FirPipeline;
|
||||||
|
import org.jetbrains.kotlin.test.TestMetadata;
|
||||||
|
import org.junit.jupiter.api.Nested;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.GenerateNativeTestsKt}. DO NOT MODIFY MANUALLY */
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
@TestMetadata("native/native.tests/testData/klib/header-klibs/compilation")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@Tag("frontend-fir")
|
||||||
|
@FirPipeline()
|
||||||
|
public class FirNativeHeaderKlibCompilationTestGenerated extends AbstractNativeHeaderKlibCompilationTest {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInCompilation() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("native/native.tests/testData/klib/header-klibs/compilation"), Pattern.compile("^([^\\.]+)$"), null, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("anonymousObject")
|
||||||
|
public void testAnonymousObject() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/compilation/anonymousObject/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("classes")
|
||||||
|
public void testClasses() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/compilation/classes/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("clinit")
|
||||||
|
public void testClinit() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/compilation/clinit/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("inlineAnnotationInstantiation")
|
||||||
|
public void testInlineAnnotationInstantiation() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/compilation/inlineAnnotationInstantiation/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("inlineAnonymousObject")
|
||||||
|
public void testInlineAnonymousObject() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/compilation/inlineAnonymousObject/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("inlineCapture")
|
||||||
|
public void testInlineCapture() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/compilation/inlineCapture/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("inlineNoRegeneration")
|
||||||
|
public void testInlineNoRegeneration() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/compilation/inlineNoRegeneration/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("inlineReifiedFunction")
|
||||||
|
public void testInlineReifiedFunction() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/compilation/inlineReifiedFunction/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("inlineWhenMappings")
|
||||||
|
public void testInlineWhenMappings() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/compilation/inlineWhenMappings/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("innerObjectRegeneration")
|
||||||
|
public void testInnerObjectRegeneration() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/compilation/innerObjectRegeneration/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("kt-40133")
|
||||||
|
public void testKt_40133() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/compilation/kt-40133/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateOnlyConstructors")
|
||||||
|
public void testPrivateOnlyConstructors() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/compilation/privateOnlyConstructors/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateValueClassConstructor")
|
||||||
|
public void testPrivateValueClassConstructor() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/compilation/privateValueClassConstructor/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("topLevel")
|
||||||
|
public void testTopLevel() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/compilation/topLevel/");
|
||||||
|
}
|
||||||
|
}
|
||||||
+128
@@ -0,0 +1,128 @@
|
|||||||
|
/*
|
||||||
|
* 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.konan.blackboxtest;
|
||||||
|
|
||||||
|
import com.intellij.testFramework.TestDataPath;
|
||||||
|
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||||
|
import org.jetbrains.kotlin.test.TestMetadata;
|
||||||
|
import org.junit.jupiter.api.Nested;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.GenerateNativeTestsKt}. DO NOT MODIFY MANUALLY */
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
@TestMetadata("native/native.tests/testData/klib/header-klibs/comparison")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class NativeHeaderKlibComparisonTestGenerated extends AbstractNativeHeaderKlibComparisonTest {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInComparison() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("native/native.tests/testData/klib/header-klibs/comparison"), Pattern.compile("^([^\\.]+)$"), null, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("anonymousObjects")
|
||||||
|
public void testAnonymousObjects() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/comparison/anonymousObjects/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("classFlags")
|
||||||
|
public void testClassFlags() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/comparison/classFlags/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("classPrivateMembers")
|
||||||
|
public void testClassPrivateMembers() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/comparison/classPrivateMembers/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("constant")
|
||||||
|
public void testConstant() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/comparison/constant/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("declarationOrderInline")
|
||||||
|
public void testDeclarationOrderInline() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/comparison/declarationOrderInline/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("functionBody")
|
||||||
|
public void testFunctionBody() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/comparison/functionBody/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("inlineFunInPrivateClass")
|
||||||
|
public void testInlineFunInPrivateClass() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/comparison/inlineFunInPrivateClass/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("inlineFunInPrivateNestedClass")
|
||||||
|
public void testInlineFunInPrivateNestedClass() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/comparison/inlineFunInPrivateNestedClass/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("inlineFunctionBody")
|
||||||
|
public void testInlineFunctionBody() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/comparison/inlineFunctionBody/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("lambdas")
|
||||||
|
public void testLambdas() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/comparison/lambdas/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("parameterName")
|
||||||
|
public void testParameterName() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/comparison/parameterName/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateInterface")
|
||||||
|
public void testPrivateInterface() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/comparison/privateInterface/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateTypealias")
|
||||||
|
public void testPrivateTypealias() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/comparison/privateTypealias/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("returnType")
|
||||||
|
public void testReturnType() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/comparison/returnType/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("superClass")
|
||||||
|
public void testSuperClass() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/comparison/superClass/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("syntheticAccessors")
|
||||||
|
public void testSyntheticAccessors() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/comparison/syntheticAccessors/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("topLevelPrivateMembers")
|
||||||
|
public void testTopLevelPrivateMembers() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/comparison/topLevelPrivateMembers/");
|
||||||
|
}
|
||||||
|
}
|
||||||
+110
@@ -0,0 +1,110 @@
|
|||||||
|
/*
|
||||||
|
* 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.konan.blackboxtest;
|
||||||
|
|
||||||
|
import com.intellij.testFramework.TestDataPath;
|
||||||
|
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||||
|
import org.jetbrains.kotlin.test.TestMetadata;
|
||||||
|
import org.junit.jupiter.api.Nested;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.GenerateNativeTestsKt}. DO NOT MODIFY MANUALLY */
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
@TestMetadata("native/native.tests/testData/klib/header-klibs/compilation")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class NativeHeaderKlibCompilationTestGenerated extends AbstractNativeHeaderKlibCompilationTest {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInCompilation() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("native/native.tests/testData/klib/header-klibs/compilation"), Pattern.compile("^([^\\.]+)$"), null, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("anonymousObject")
|
||||||
|
public void testAnonymousObject() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/compilation/anonymousObject/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("classes")
|
||||||
|
public void testClasses() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/compilation/classes/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("clinit")
|
||||||
|
public void testClinit() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/compilation/clinit/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("inlineAnnotationInstantiation")
|
||||||
|
public void testInlineAnnotationInstantiation() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/compilation/inlineAnnotationInstantiation/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("inlineAnonymousObject")
|
||||||
|
public void testInlineAnonymousObject() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/compilation/inlineAnonymousObject/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("inlineCapture")
|
||||||
|
public void testInlineCapture() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/compilation/inlineCapture/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("inlineNoRegeneration")
|
||||||
|
public void testInlineNoRegeneration() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/compilation/inlineNoRegeneration/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("inlineReifiedFunction")
|
||||||
|
public void testInlineReifiedFunction() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/compilation/inlineReifiedFunction/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("inlineWhenMappings")
|
||||||
|
public void testInlineWhenMappings() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/compilation/inlineWhenMappings/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("innerObjectRegeneration")
|
||||||
|
public void testInnerObjectRegeneration() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/compilation/innerObjectRegeneration/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("kt-40133")
|
||||||
|
public void testKt_40133() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/compilation/kt-40133/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateOnlyConstructors")
|
||||||
|
public void testPrivateOnlyConstructors() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/compilation/privateOnlyConstructors/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateValueClassConstructor")
|
||||||
|
public void testPrivateValueClassConstructor() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/compilation/privateValueClassConstructor/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("topLevel")
|
||||||
|
public void testTopLevel() throws Exception {
|
||||||
|
runTest("native/native.tests/testData/klib/header-klibs/compilation/topLevel/");
|
||||||
|
}
|
||||||
|
}
|
||||||
+30
@@ -314,6 +314,36 @@ fun main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Header klib comparison tests
|
||||||
|
testGroup("native/native.tests/tests-gen", "native/native.tests/testData") {
|
||||||
|
testClass<AbstractNativeHeaderKlibComparisonTest>(
|
||||||
|
suiteTestClassName = "NativeHeaderKlibComparisonTestGenerated",
|
||||||
|
) {
|
||||||
|
model("klib/header-klibs/comparison", extension = null, recursive = false)
|
||||||
|
}
|
||||||
|
testClass<AbstractNativeHeaderKlibComparisonTest>(
|
||||||
|
suiteTestClassName = "FirNativeHeaderKlibComparisonTestGenerated",
|
||||||
|
annotations = listOf(*frontendFir()),
|
||||||
|
) {
|
||||||
|
model("klib/header-klibs/comparison", extension = null, recursive = false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Header klib compilation tests
|
||||||
|
testGroup("native/native.tests/tests-gen", "native/native.tests/testData") {
|
||||||
|
testClass<AbstractNativeHeaderKlibCompilationTest>(
|
||||||
|
suiteTestClassName = "NativeHeaderKlibCompilationTestGenerated",
|
||||||
|
) {
|
||||||
|
model("klib/header-klibs/compilation", extension = null, recursive = false)
|
||||||
|
}
|
||||||
|
testClass<AbstractNativeHeaderKlibCompilationTest>(
|
||||||
|
suiteTestClassName = "FirNativeHeaderKlibCompilationTestGenerated",
|
||||||
|
annotations = listOf(*frontendFir()),
|
||||||
|
) {
|
||||||
|
model("klib/header-klibs/compilation", extension = null, recursive = false)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+103
@@ -0,0 +1,103 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2022 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.konan.blackboxtest
|
||||||
|
|
||||||
|
import com.intellij.testFramework.TestDataFile
|
||||||
|
import org.jetbrains.kotlin.konan.blackboxtest.support.*
|
||||||
|
import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilationArtifact
|
||||||
|
import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilationResult.Companion.assertSuccess
|
||||||
|
import org.jetbrains.kotlin.konan.blackboxtest.support.group.UsePartialLinkage
|
||||||
|
import org.jetbrains.kotlin.konan.blackboxtest.support.runner.TestRunChecks
|
||||||
|
import org.jetbrains.kotlin.konan.blackboxtest.support.settings.Timeouts
|
||||||
|
import org.jetbrains.kotlin.konan.blackboxtest.support.util.getAbsoluteFile
|
||||||
|
import org.junit.jupiter.api.Tag
|
||||||
|
import java.io.File
|
||||||
|
import kotlin.test.assertContentEquals
|
||||||
|
import kotlin.test.assertFailsWith
|
||||||
|
|
||||||
|
@Tag("klib")
|
||||||
|
@UsePartialLinkage(UsePartialLinkage.Mode.ENABLED_WITH_ERROR)
|
||||||
|
abstract class AbstractNativeHeaderKlibComparisonTest : AbstractNativeSimpleTest() {
|
||||||
|
|
||||||
|
protected fun runTest(@TestDataFile testPath: String) {
|
||||||
|
val testPathFull = getAbsoluteFile(testPath)
|
||||||
|
|
||||||
|
val testCaseBase: TestCase = generateTestcaseFromDirectory(testPathFull, "base", listOf())
|
||||||
|
compileToLibrary(testCaseBase).assertSuccess()
|
||||||
|
val headerKlibBase = File(getHeaderPath("base"))
|
||||||
|
assert(headerKlibBase.exists())
|
||||||
|
|
||||||
|
val sameAbiDir = testPathFull.resolve("sameAbi")
|
||||||
|
val differentAbiDir = testPathFull.resolve("differentAbi")
|
||||||
|
|
||||||
|
assert(sameAbiDir.exists() || differentAbiDir.exists()) { "Nothing to compare" }
|
||||||
|
|
||||||
|
if (sameAbiDir.exists()) {
|
||||||
|
val testCaseSameAbi: TestCase = generateTestcaseFromDirectory(testPathFull, "sameAbi", listOf())
|
||||||
|
compileToLibrary(testCaseSameAbi).assertSuccess()
|
||||||
|
val headerKlibSameAbi = File(getHeaderPath("sameAbi"))
|
||||||
|
assert(headerKlibSameAbi.exists())
|
||||||
|
assertContentEquals(headerKlibBase.readBytes(), headerKlibSameAbi.readBytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
if (differentAbiDir.exists()) {
|
||||||
|
val testCaseDifferentAbi: TestCase = generateTestcaseFromDirectory(testPathFull, "differentAbi", listOf())
|
||||||
|
compileToLibrary(testCaseDifferentAbi).assertSuccess()
|
||||||
|
val headerKlibDifferentAbi = File(getHeaderPath("differentAbi"))
|
||||||
|
assert(headerKlibDifferentAbi.exists())
|
||||||
|
assertFailsWith<AssertionError>("base and differentAbi header klib are equal") {
|
||||||
|
assertContentEquals(headerKlibBase.readBytes(), headerKlibDifferentAbi.readBytes())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Tag("klib")
|
||||||
|
@UsePartialLinkage(UsePartialLinkage.Mode.ENABLED_WITH_ERROR)
|
||||||
|
abstract class AbstractNativeHeaderKlibCompilationTest : AbstractNativeSimpleTest() {
|
||||||
|
|
||||||
|
protected fun runTest(@TestDataFile testPath: String) {
|
||||||
|
val testPathFull = getAbsoluteFile(testPath)
|
||||||
|
assert(testPathFull.exists())
|
||||||
|
val testCaseLib: TestCase = generateTestcaseFromDirectory(testPathFull, "lib", listOf())
|
||||||
|
val klibLib = compileToLibrary(testCaseLib)
|
||||||
|
val headerKlibLib = File(getHeaderPath("lib"))
|
||||||
|
assert(headerKlibLib.exists())
|
||||||
|
val testPathApp = testPathFull.resolve("main")
|
||||||
|
val klibAppFromHeader = compileToLibrary(testPathApp, TestCompilationArtifact.KLIB(headerKlibLib))
|
||||||
|
val klibAppFromFull = compileToLibrary(testPathApp, klibLib.resultingArtifact)
|
||||||
|
assertContentEquals(
|
||||||
|
klibAppFromHeader.klibFile.readBytes(),
|
||||||
|
klibAppFromFull.klibFile.readBytes()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun AbstractNativeSimpleTest.getHeaderPath(rev: String) = buildDir.absolutePath + "/header.$rev.klib"
|
||||||
|
private fun AbstractNativeSimpleTest.generateTestcaseFromDirectory(source: File, rev: String, extraArgs: List<String>): TestCase {
|
||||||
|
val moduleName: String = source.name
|
||||||
|
val module = TestModule.Exclusive(moduleName, emptySet(), emptySet(), emptySet())
|
||||||
|
source.resolve(rev).listFiles()?.forEach {
|
||||||
|
muteTestIfNecessary(it)
|
||||||
|
module.files += TestFile.createCommitted(it, module)
|
||||||
|
}
|
||||||
|
|
||||||
|
val headerKlibPath = "-Xheader-klib-path=" + getHeaderPath(rev)
|
||||||
|
val relativeBasePath = "-Xklib-relative-path-base=$source/$rev"
|
||||||
|
|
||||||
|
return TestCase(
|
||||||
|
id = TestCaseId.Named(moduleName),
|
||||||
|
kind = TestKind.STANDALONE,
|
||||||
|
modules = setOf(module),
|
||||||
|
freeCompilerArgs = TestCompilerArgs(extraArgs + relativeBasePath + headerKlibPath),
|
||||||
|
nominalPackageName = PackageName.EMPTY,
|
||||||
|
checks = TestRunChecks.Default(testRunSettings.get<Timeouts>().executionTimeout),
|
||||||
|
extras = TestCase.WithTestRunnerExtras(TestRunnerType.DEFAULT)
|
||||||
|
).apply {
|
||||||
|
initialize(null, null)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user