From fafea27283f5f98aac98b07272171323bd29b420 Mon Sep 17 00:00:00 2001 From: Johan Bay Date: Fri, 26 May 2023 09:49:48 +0200 Subject: [PATCH] [klib tool] Add option to print ir Dumping the IR from a klib is useful for debugging klib compilations. ^KT-58877 --- .../jetbrains/kotlin/ir/util/DumpIrTree.kt | 2 + .../kotlin/ir/util/RenderIrElement.kt | 34 +++++-- .../org/jetbrains/kotlin/cli/klib/main.kt | 97 +++++++++++++++++-- .../native.tests/testData/klibIr/class.ir.txt | 8 ++ native/native.tests/testData/klibIr/class.kt | 5 + .../testData/klibIr/class.sig.ir.txt | 8 ++ .../testData/klibIr/constructor.ir.txt | 35 +++++++ .../testData/klibIr/constructor.kt | 8 ++ .../testData/klibIr/constructor.sig.ir.txt | 35 +++++++ .../native.tests/testData/klibIr/enum.ir.txt | 42 ++++++++ native/native.tests/testData/klibIr/enum.kt | 8 ++ .../testData/klibIr/enum.sig.ir.txt | 42 ++++++++ .../native.tests/testData/klibIr/field.ir.txt | 38 ++++++++ native/native.tests/testData/klibIr/field.kt | 7 ++ .../testData/klibIr/field.sig.ir.txt | 38 ++++++++ .../native.tests/testData/klibIr/fun.ir.txt | 22 +++++ native/native.tests/testData/klibIr/fun.kt | 7 ++ .../testData/klibIr/fun.sig.ir.txt | 22 +++++ .../testData/klibIr/typealias.ir.fir.txt | 11 +++ .../testData/klibIr/typealias.ir.txt | 11 +++ .../native.tests/testData/klibIr/typealias.kt | 7 ++ .../testData/klibIr/typealias.sig.ir.fir.txt | 11 +++ .../testData/klibIr/typealias.sig.ir.txt | 11 +++ ...> FirNativeKlibContentsTestGenerated.java} | 2 +- .../FirNativeKlibIrTestGenerated.java | 66 +++++++++++++ ...a => NativeKlibContentsTestGenerated.java} | 2 +- .../NativeKlibIrTestGenerated.java | 62 ++++++++++++ .../generators/tests/GenerateNativeTests.kt | 23 ++++- .../AbstractNativeKlibEvolutionTest.kt | 3 +- .../blackboxtest/AbstractNativeKlibIrTest.kt | 84 ++++++++++++++++ .../blackboxtest/NativeSimpleTestUtils.kt | 3 + .../blackboxtest/support/TestDirectives.kt | 4 + .../support/util/TestCompilationArtifacts.kt | 19 +++- 33 files changed, 753 insertions(+), 24 deletions(-) create mode 100644 native/native.tests/testData/klibIr/class.ir.txt create mode 100644 native/native.tests/testData/klibIr/class.kt create mode 100644 native/native.tests/testData/klibIr/class.sig.ir.txt create mode 100644 native/native.tests/testData/klibIr/constructor.ir.txt create mode 100644 native/native.tests/testData/klibIr/constructor.kt create mode 100644 native/native.tests/testData/klibIr/constructor.sig.ir.txt create mode 100644 native/native.tests/testData/klibIr/enum.ir.txt create mode 100644 native/native.tests/testData/klibIr/enum.kt create mode 100644 native/native.tests/testData/klibIr/enum.sig.ir.txt create mode 100644 native/native.tests/testData/klibIr/field.ir.txt create mode 100644 native/native.tests/testData/klibIr/field.kt create mode 100644 native/native.tests/testData/klibIr/field.sig.ir.txt create mode 100644 native/native.tests/testData/klibIr/fun.ir.txt create mode 100644 native/native.tests/testData/klibIr/fun.kt create mode 100644 native/native.tests/testData/klibIr/fun.sig.ir.txt create mode 100644 native/native.tests/testData/klibIr/typealias.ir.fir.txt create mode 100644 native/native.tests/testData/klibIr/typealias.ir.txt create mode 100644 native/native.tests/testData/klibIr/typealias.kt create mode 100644 native/native.tests/testData/klibIr/typealias.sig.ir.fir.txt create mode 100644 native/native.tests/testData/klibIr/typealias.sig.ir.txt rename native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/{FirNativeKLibContentsTestGenerated.java => FirNativeKlibContentsTestGenerated.java} (99%) create mode 100644 native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/FirNativeKlibIrTestGenerated.java rename native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/{NativeKLibContentsTestGenerated.java => NativeKlibContentsTestGenerated.java} (99%) create mode 100644 native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeKlibIrTestGenerated.java create mode 100644 native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/AbstractNativeKlibIrTest.kt diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DumpIrTree.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DumpIrTree.kt index e13f06691f8..40bdce5fca5 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DumpIrTree.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DumpIrTree.kt @@ -52,6 +52,7 @@ fun IrFile.dumpTreesFromLineNumber(lineNumber: Int, options: DumpIrTreeOptions = * the file facade class (see [IrDeclarationOrigin.FILE_CLASS]) * @property printFlagsInDeclarationReferences If `false`, flags like `fake_override`, `inline` etc. are not printed in rendered declaration * references. + * @property printSignatures Whether to print signatures for nodes that have public signatures */ data class DumpIrTreeOptions( val normalizeNames: Boolean = false, @@ -59,6 +60,7 @@ data class DumpIrTreeOptions( val verboseErrorTypes: Boolean = true, val printFacadeClassInFqNames: Boolean = true, val printFlagsInDeclarationReferences: Boolean = true, + val printSignatures: Boolean = false, ) private fun IrFile.shouldSkipDump(): Boolean { diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt index 493154a15e3..0117775909a 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt @@ -72,7 +72,7 @@ class RenderIrElementVisitor(private val options: DumpIrTreeOptions = DumpIrTree renderClassWithRenderer(declaration, null, options) override fun visitEnumEntry(declaration: IrEnumEntry, data: Nothing?) = - renderEnumEntry(declaration) + renderEnumEntry(declaration, options) override fun visitField(declaration: IrField, data: Nothing?) = renderField(declaration, null, options) @@ -260,7 +260,9 @@ class RenderIrElementVisitor(private val options: DumpIrTreeOptions = DumpIrTree override fun visitSimpleFunction(declaration: IrSimpleFunction, data: Nothing?): String = declaration.runTrimEnd { "FUN ${renderOriginIfNonTrivial()}" + - "name:$name visibility:$visibility modality:$modality " + + "name:$name " + + renderSignatureIfEnabled(options.printSignatures) + + "visibility:$visibility modality:$modality " + renderTypeParameters() + " " + renderValueParameterTypes() + " " + "returnType:${renderReturnType(this@RenderIrElementVisitor, options)} " + @@ -277,6 +279,7 @@ class RenderIrElementVisitor(private val options: DumpIrTreeOptions = DumpIrTree override fun visitConstructor(declaration: IrConstructor, data: Nothing?): String = declaration.runTrimEnd { "CONSTRUCTOR ${renderOriginIfNonTrivial()}" + + renderSignatureIfEnabled(options.printSignatures) + "visibility:$visibility " + renderTypeParameters() + " " + renderValueParameterTypes() + " " + @@ -287,7 +290,9 @@ class RenderIrElementVisitor(private val options: DumpIrTreeOptions = DumpIrTree override fun visitProperty(declaration: IrProperty, data: Nothing?): String = declaration.runTrimEnd { "PROPERTY ${renderOriginIfNonTrivial()}" + - "name:$name visibility:$visibility modality:$modality " + + "name:$name " + + renderSignatureIfEnabled(options.printSignatures) + + "visibility:$visibility modality:$modality " + renderPropertyFlags() } @@ -303,7 +308,7 @@ class RenderIrElementVisitor(private val options: DumpIrTreeOptions = DumpIrTree } override fun visitEnumEntry(declaration: IrEnumEntry, data: Nothing?): String = - renderEnumEntry(declaration) + renderEnumEntry(declaration, options) override fun visitAnonymousInitializer(declaration: IrAnonymousInitializer, data: Nothing?): String = "ANONYMOUS_INITIALIZER isStatic=${declaration.isStatic}" @@ -330,7 +335,9 @@ class RenderIrElementVisitor(private val options: DumpIrTreeOptions = DumpIrTree override fun visitTypeAlias(declaration: IrTypeAlias, data: Nothing?): String = declaration.run { "TYPEALIAS ${declaration.renderOriginIfNonTrivial()}" + - "name:$name visibility:$visibility expandedType:${expandedType.render()}" + + "name:$name " + + renderSignatureIfEnabled(options.printSignatures) + + "visibility:$visibility expandedType:${expandedType.render()}" + renderTypeAliasFlags() } @@ -540,6 +547,9 @@ internal fun DescriptorRenderer.renderDescriptor(descriptor: DeclarationDescript else render(descriptor) +private fun IrDeclarationWithName.renderSignatureIfEnabled(printSignatures: Boolean): String = + if (printSignatures) symbol.signature?.let { "signature:${it.render()} " }.orEmpty() else "" + internal fun IrDeclaration.renderOriginIfNonTrivial(): String = if (origin != IrDeclarationOrigin.DEFINED) "$origin " else "" @@ -872,17 +882,22 @@ private fun StringBuilder.renderAsAnnotationArgument(irElement: IrElement?, rend private fun renderClassWithRenderer(declaration: IrClass, renderer: RenderIrElementVisitor?, options: DumpIrTreeOptions) = declaration.runTrimEnd { "CLASS ${renderOriginIfNonTrivial()}" + - "$kind name:$name modality:$modality visibility:$visibility " + + "$kind name:$name " + + renderSignatureIfEnabled(options.printSignatures) + + "modality:$modality visibility:$visibility " + renderClassFlags() + "superTypes:[${superTypes.joinToString(separator = "; ") { it.renderTypeWithRenderer(renderer, options) }}]" } -private fun renderEnumEntry(declaration: IrEnumEntry) = declaration.runTrimEnd { - "ENUM_ENTRY ${renderOriginIfNonTrivial()}name:$name" +private fun renderEnumEntry(declaration: IrEnumEntry, options: DumpIrTreeOptions) = declaration.runTrimEnd { + "ENUM_ENTRY " + + renderOriginIfNonTrivial() + + "name:$name " + + renderSignatureIfEnabled(options.printSignatures) } private fun renderField(declaration: IrField, renderer: RenderIrElementVisitor?, options: DumpIrTreeOptions) = declaration.runTrimEnd { - "FIELD ${renderOriginIfNonTrivial()}name:$name type:${ + "FIELD ${renderOriginIfNonTrivial()}name:$name ${renderSignatureIfEnabled(options.printSignatures)}type:${ type.renderTypeWithRenderer( renderer, options @@ -894,6 +909,7 @@ private fun renderTypeParameter(declaration: IrTypeParameter, renderer: RenderIr declaration.runTrimEnd { "TYPE_PARAMETER ${renderOriginIfNonTrivial()}" + "name:$name index:$index variance:$variance " + + renderSignatureIfEnabled(options.printSignatures) + "superTypes:[${ superTypes.joinToString(separator = "; ") { it.renderTypeWithRenderer( diff --git a/kotlin-native/klib/src/main/kotlin/org/jetbrains/kotlin/cli/klib/main.kt b/kotlin-native/klib/src/main/kotlin/org/jetbrains/kotlin/cli/klib/main.kt index 30365dd212e..79c80fbc249 100644 --- a/kotlin-native/klib/src/main/kotlin/org/jetbrains/kotlin/cli/klib/main.kt +++ b/kotlin-native/klib/src/main/kotlin/org/jetbrains/kotlin/cli/klib/main.kt @@ -6,7 +6,16 @@ package org.jetbrains.kotlin.cli.klib // TODO: Extract `library` package as a shared jar? +import org.jetbrains.kotlin.backend.common.linkage.partial.PartialLinkageSupportForLinker +import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideBuilder +import org.jetbrains.kotlin.backend.common.serialization.BasicIrModuleDeserializer +import org.jetbrains.kotlin.backend.common.serialization.DeserializationStrategy +import org.jetbrains.kotlin.backend.common.serialization.IrModuleDeserializer +import org.jetbrains.kotlin.backend.common.serialization.KotlinIrLinker import org.jetbrains.kotlin.backend.common.serialization.metadata.DynamicTypeDeserializer +import org.jetbrains.kotlin.backend.konan.serialization.KonanIdSignaturer +import org.jetbrains.kotlin.backend.konan.serialization.KonanManglerDesc +import org.jetbrains.kotlin.backend.konan.serialization.KonanManglerIr import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns import org.jetbrains.kotlin.config.ApiVersion import org.jetbrains.kotlin.config.LanguageVersion @@ -14,19 +23,29 @@ import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib +import org.jetbrains.kotlin.ir.IrBuiltIns +import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI +import org.jetbrains.kotlin.ir.builders.TranslationPluginContext +import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl +import org.jetbrains.kotlin.ir.types.IrTypeSystemContextImpl +import org.jetbrains.kotlin.ir.util.DumpIrTreeOptions +import org.jetbrains.kotlin.ir.util.IrMessageLogger +import org.jetbrains.kotlin.ir.util.SymbolTable +import org.jetbrains.kotlin.ir.util.dump import org.jetbrains.kotlin.konan.file.File import org.jetbrains.kotlin.konan.library.KonanLibrary import org.jetbrains.kotlin.konan.library.resolverByName import org.jetbrains.kotlin.konan.target.Distribution import org.jetbrains.kotlin.konan.target.PlatformManager import org.jetbrains.kotlin.konan.util.DependencyDirectories -import org.jetbrains.kotlin.konan.util.DependencyProcessor import org.jetbrains.kotlin.konan.util.KonanHomeProvider -import org.jetbrains.kotlin.library.KLIB_FILE_EXTENSION_WITH_DOT +import org.jetbrains.kotlin.library.* import org.jetbrains.kotlin.library.metadata.KlibMetadataFactories import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf +import org.jetbrains.kotlin.library.metadata.kotlinLibrary import org.jetbrains.kotlin.library.metadata.parseModuleHeader -import org.jetbrains.kotlin.library.unpackZippedKonanLibraryTo +import org.jetbrains.kotlin.psi2ir.descriptors.IrBuiltInsOverDescriptors +import org.jetbrains.kotlin.psi2ir.generators.TypeTranslatorImpl import org.jetbrains.kotlin.storage.LockBasedStorageManager import org.jetbrains.kotlin.util.Logger import org.jetbrains.kotlin.util.removeSuffixIfPresent @@ -39,13 +58,14 @@ fun printUsage() { println("where the commands are:") println("\tinfo\tgeneral information about the library") println("\tinstall\tinstall the library to the local repository") + println("\tdump-ir\tprint out the intermediate representation (IR) for the library (to be used for debugging purposes only)") println("\tcontents\tlist contents of the library") println("\tsignatures\tlist of ID signatures in the library") println("\tremove\tremove the library from the local repository") println("and the options are:") println("\t-repository \twork with the specified repository") println("\t-target \tinspect specifics of the given target") - println("\t-print-signatures [true|false]\tprint ID signature for every declaration (only for \"contents\" command)") + println("\t-print-signatures [true|false]\tprint ID signature for every declaration (only for \"contents\" and \"dump-ir\" commands)") } private fun parseArgs(args: Array): Map> { @@ -86,11 +106,18 @@ fun error(text: String): Nothing { kotlin.error("error: $text") } -object KlibToolLogger : Logger { - override fun warning(message: String) = org.jetbrains.kotlin.cli.klib.warn(message) - override fun error(message: String) = org.jetbrains.kotlin.cli.klib.warn(message) +object KlibToolLogger : Logger, IrMessageLogger { + override fun warning(message: String) = warn(message) + override fun error(message: String) = warn(message) override fun fatal(message: String) = org.jetbrains.kotlin.cli.klib.error(message) override fun log(message: String) = println(message) + override fun report(severity: IrMessageLogger.Severity, message: String, location: IrMessageLogger.Location?) { + when (severity) { + IrMessageLogger.Severity.INFO -> log(message) + IrMessageLogger.Severity.WARNING -> warning(message) + IrMessageLogger.Severity.ERROR -> error(message) + } + } } // TODO(Dmitrii Krasnov): I'm not sure that we should put konan distribution dir here @@ -165,6 +192,61 @@ class Library(val libraryNameOrPath: String, val requestedRepository: String?, v library?.libraryFile?.deleteRecursively() } + class KlibToolLinker( + module: ModuleDescriptor, irBuiltIns: IrBuiltIns, symbolTable: SymbolTable + ) : KotlinIrLinker(module, KlibToolLogger, irBuiltIns, symbolTable, emptyList()) { + override val fakeOverrideBuilder = FakeOverrideBuilder( + linker = this, + symbolTable = symbolTable, + mangler = KonanManglerIr, + typeSystem = IrTypeSystemContextImpl(builtIns), + friendModules = emptyMap(), + partialLinkageSupport = PartialLinkageSupportForLinker.DISABLED, + ) + override val translationPluginContext: TranslationPluginContext + get() = TODO("Not needed for ir dumping") + + override fun createModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: KotlinLibrary?, strategyResolver: (String) -> DeserializationStrategy): IrModuleDeserializer { + return KlibToolModuleDeserializer(moduleDescriptor, klib ?: error("Expecting kotlin library for $moduleDescriptor"), strategyResolver) + } + + override fun isBuiltInModule(moduleDescriptor: ModuleDescriptor): Boolean { + return false + } + + inner class KlibToolModuleDeserializer( + module: ModuleDescriptor, + klib: KotlinLibrary, + strategyResolver: (String) -> DeserializationStrategy + ) : BasicIrModuleDeserializer( + this, + module, + klib, + strategyResolver, + klib.versions.abiVersion ?: KotlinAbiVersion.CURRENT + ) + } + + @OptIn(ObsoleteDescriptorBasedAPI::class) + fun ir(output: Appendable, printSignatures: Boolean) { + val module = loadModule() + if (module.kotlinLibrary.isInterop) error("Deserializing IR from IR-less libraries is not supported yet") + val versionSpec = LanguageVersionSettingsImpl(currentLanguageVersion, currentApiVersion) + val idSignaturer = KonanIdSignaturer(KonanManglerDesc) + val symbolTable = SymbolTable(idSignaturer, IrFactoryImpl) + val typeTranslator = TypeTranslatorImpl(symbolTable, versionSpec, module) + val irBuiltIns = IrBuiltInsOverDescriptors(module.builtIns, typeTranslator, symbolTable) + val linker = KlibToolLinker(module, irBuiltIns, symbolTable) + module.allDependencyModules.forEach { + linker.deserializeOnlyHeaderModule(it, it.kotlinLibrary) + linker.resolveModuleDeserializer(it, null).init() + } + val irFragment = linker.deserializeFullModule(module, module.kotlinLibrary) + linker.resolveModuleDeserializer(module, null).init() + linker.modulesWithReachableTopLevels.forEach(IrModuleDeserializer::deserializeReachableDeclarations) + output.append(irFragment.dump(DumpIrTreeOptions(printSignatures = printSignatures))) + } + fun contents(output: Appendable, printSignatures: Boolean) { val module = loadModule() val signatureRenderer = if (printSignatures) DefaultKlibSignatureRenderer("// ID signature: ") else KlibSignatureRenderer.NO_SIGNATURE @@ -231,6 +313,7 @@ fun main(args: Array) { val library = Library(command.library, repository, target) when (command.verb) { + "dump-ir" -> library.ir(System.out, printSignatures) "contents" -> library.contents(System.out, printSignatures) "signatures" -> library.signatures(System.out) "info" -> library.info() diff --git a/native/native.tests/testData/klibIr/class.ir.txt b/native/native.tests/testData/klibIr/class.ir.txt new file mode 100644 index 00000000000..4c432fadb80 --- /dev/null +++ b/native/native.tests/testData/klibIr/class.ir.txt @@ -0,0 +1,8 @@ +MODULE_FRAGMENT name: + FILE fqName:test fileName:class.kt + CLASS CLASS name:A modality:FINAL visibility:public superTypes:[] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:test.A + CONSTRUCTOR visibility:public <> () returnType:test.A [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'UNBOUND IrConstructorPublicSymbolImpl' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:A modality:FINAL visibility:public superTypes:[]' diff --git a/native/native.tests/testData/klibIr/class.kt b/native/native.tests/testData/klibIr/class.kt new file mode 100644 index 00000000000..faac2cac75f --- /dev/null +++ b/native/native.tests/testData/klibIr/class.kt @@ -0,0 +1,5 @@ +// FIR_IDENTICAL +package test + +class A { +} diff --git a/native/native.tests/testData/klibIr/class.sig.ir.txt b/native/native.tests/testData/klibIr/class.sig.ir.txt new file mode 100644 index 00000000000..1fb3be7cad2 --- /dev/null +++ b/native/native.tests/testData/klibIr/class.sig.ir.txt @@ -0,0 +1,8 @@ +MODULE_FRAGMENT name: + FILE fqName:test fileName:class.kt + CLASS CLASS name:A signature:test/A|null[0] modality:FINAL visibility:public superTypes:[] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:test.A + CONSTRUCTOR signature:test/A.|(){}[0] visibility:public <> () returnType:test.A [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'UNBOUND IrConstructorPublicSymbolImpl' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:A signature:test/A|null[0] modality:FINAL visibility:public superTypes:[]' diff --git a/native/native.tests/testData/klibIr/constructor.ir.txt b/native/native.tests/testData/klibIr/constructor.ir.txt new file mode 100644 index 00000000000..a3493ffbc8c --- /dev/null +++ b/native/native.tests/testData/klibIr/constructor.ir.txt @@ -0,0 +1,35 @@ +MODULE_FRAGMENT name: + FILE fqName:test fileName:constructor.kt + CLASS CLASS name:A modality:FINAL visibility:public superTypes:[] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:test.A + CONSTRUCTOR visibility:public <> (x:) returnType:test.A [primary] + VALUE_PARAMETER name:x index:0 type: + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'UNBOUND IrConstructorPublicSymbolImpl' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:A modality:FINAL visibility:public superTypes:[]' + PROPERTY name:x visibility:public modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:x type: visibility:private [final] + EXPRESSION_BODY + GET_VAR 'x: declared in test.A.' type= origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:test.A) returnType: + correspondingProperty: PROPERTY name:x visibility:public modality:FINAL [val] + $this: VALUE_PARAMETER name: type:test.A + BLOCK_BODY + RETURN type= from='public final fun (): declared in test.A' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:x type: visibility:private [final]' type= origin=null + receiver: GET_VAR ': test.A declared in test.A.' type=test.A origin=null + CLASS OBJECT name:Companion modality:FINAL visibility:public [companion] superTypes:[] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:test.A.Companion + CONSTRUCTOR visibility:private <> () returnType:test.A.Companion [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'UNBOUND IrConstructorPublicSymbolImpl' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS OBJECT name:Companion modality:FINAL visibility:public [companion] superTypes:[]' + FUN name:create visibility:public modality:FINAL <> ($this:test.A.Companion, x:) returnType:test.A + $this: VALUE_PARAMETER name: type:test.A.Companion + VALUE_PARAMETER name:x index:0 type: + BLOCK_BODY + RETURN type= from='public final fun create (x: ): test.A declared in test.A.Companion' + CONSTRUCTOR_CALL 'public constructor (x: ) [primary] declared in test.A' type=test.A origin=null + x: CALL 'UNBOUND IrSimpleFunctionPublicSymbolImpl' type= origin=MUL + $this: GET_VAR 'x: declared in test.A.Companion.create' type= origin=null + 1: CONST Int type= value=2 diff --git a/native/native.tests/testData/klibIr/constructor.kt b/native/native.tests/testData/klibIr/constructor.kt new file mode 100644 index 00000000000..42178a4e811 --- /dev/null +++ b/native/native.tests/testData/klibIr/constructor.kt @@ -0,0 +1,8 @@ +// FIR_IDENTICAL +package test + +class A constructor(val x: Int) { + companion object { + fun create(x: Int): A = A(x * 2) + } +} \ No newline at end of file diff --git a/native/native.tests/testData/klibIr/constructor.sig.ir.txt b/native/native.tests/testData/klibIr/constructor.sig.ir.txt new file mode 100644 index 00000000000..da3779a1a45 --- /dev/null +++ b/native/native.tests/testData/klibIr/constructor.sig.ir.txt @@ -0,0 +1,35 @@ +MODULE_FRAGMENT name: + FILE fqName:test fileName:constructor.kt + CLASS CLASS name:A signature:test/A|null[0] modality:FINAL visibility:public superTypes:[] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:test.A + CONSTRUCTOR signature:test/A.|(kotlin.Int){}[0] visibility:public <> (x:) returnType:test.A [primary] + VALUE_PARAMETER name:x index:0 type: + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'UNBOUND IrConstructorPublicSymbolImpl' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:A signature:test/A|null[0] modality:FINAL visibility:public superTypes:[]' + PROPERTY name:x signature:test/A.x|{}x[0] visibility:public modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:x signature:[ test/A.x|{}x[0] <- Local[|FIELD PROPERTY_BACKING_FIELD name:x type:kotlin.Int visibility:private [final]] ] type: visibility:private [final] + EXPRESSION_BODY + GET_VAR 'x: declared in test.A.' type= origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: signature:test/A.x.|(){}[0] visibility:public modality:FINAL <> ($this:test.A) returnType: + correspondingProperty: PROPERTY name:x signature:test/A.x|{}x[0] visibility:public modality:FINAL [val] + $this: VALUE_PARAMETER name: type:test.A + BLOCK_BODY + RETURN type= from='public final fun (): declared in test.A' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:x signature:[ test/A.x|{}x[0] <- Local[|FIELD PROPERTY_BACKING_FIELD name:x type:kotlin.Int visibility:private [final]] ] type: visibility:private [final]' type= origin=null + receiver: GET_VAR ': test.A declared in test.A.' type=test.A origin=null + CLASS OBJECT name:Companion signature:test/A.Companion|null[0] modality:FINAL visibility:public [companion] superTypes:[] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:test.A.Companion + CONSTRUCTOR signature:test/A.Companion.|(){}[0] visibility:private <> () returnType:test.A.Companion [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'UNBOUND IrConstructorPublicSymbolImpl' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS OBJECT name:Companion signature:test/A.Companion|null[0] modality:FINAL visibility:public [companion] superTypes:[]' + FUN name:create signature:test/A.Companion.create|create(kotlin.Int){}[0] visibility:public modality:FINAL <> ($this:test.A.Companion, x:) returnType:test.A + $this: VALUE_PARAMETER name: type:test.A.Companion + VALUE_PARAMETER name:x index:0 type: + BLOCK_BODY + RETURN type= from='public final fun create (x: ): test.A declared in test.A.Companion' + CONSTRUCTOR_CALL 'public constructor (x: ) [primary] declared in test.A' type=test.A origin=null + x: CALL 'UNBOUND IrSimpleFunctionPublicSymbolImpl' type= origin=MUL + $this: GET_VAR 'x: declared in test.A.Companion.create' type= origin=null + 1: CONST Int type= value=2 diff --git a/native/native.tests/testData/klibIr/enum.ir.txt b/native/native.tests/testData/klibIr/enum.ir.txt new file mode 100644 index 00000000000..8f9b58005a3 --- /dev/null +++ b/native/native.tests/testData/klibIr/enum.ir.txt @@ -0,0 +1,42 @@ +MODULE_FRAGMENT name: + FILE fqName:test fileName:enum.kt + CLASS ENUM_CLASS name:Color modality:FINAL visibility:public superTypes:[] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:test.Color + CONSTRUCTOR visibility:private <> (rgb:) returnType:test.Color [primary] + VALUE_PARAMETER name:rgb index:0 type: + BLOCK_BODY + ENUM_CONSTRUCTOR_CALL 'UNBOUND IrConstructorPublicSymbolImpl' + <1>: test.Color + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS ENUM_CLASS name:Color modality:FINAL visibility:public superTypes:[]' + PROPERTY name:rgb visibility:public modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:rgb type: visibility:private [final] + EXPRESSION_BODY + GET_VAR 'rgb: declared in test.Color.' type= origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:test.Color) returnType: + correspondingProperty: PROPERTY name:rgb visibility:public modality:FINAL [val] + $this: VALUE_PARAMETER name: type:test.Color + BLOCK_BODY + RETURN type= from='public final fun (): declared in test.Color' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:rgb type: visibility:private [final]' type= origin=null + receiver: GET_VAR ': test.Color declared in test.Color.' type=test.Color origin=null + ENUM_ENTRY name:RED + init: EXPRESSION_BODY + ENUM_CONSTRUCTOR_CALL 'private constructor (rgb: ) [primary] declared in test.Color' + rgb: CONST Int type= value=16711680 + ENUM_ENTRY name:GREEN + init: EXPRESSION_BODY + ENUM_CONSTRUCTOR_CALL 'private constructor (rgb: ) [primary] declared in test.Color' + rgb: CONST Int type= value=65280 + ENUM_ENTRY name:BLUE + init: EXPRESSION_BODY + ENUM_CONSTRUCTOR_CALL 'private constructor (rgb: ) [primary] declared in test.Color' + rgb: CONST Int type= value=255 + FUN ENUM_CLASS_SPECIAL_MEMBER name:values visibility:public modality:FINAL <> () returnType: + SYNTHETIC_BODY kind=ENUM_VALUES + FUN ENUM_CLASS_SPECIAL_MEMBER name:valueOf visibility:public modality:FINAL <> (value:) returnType:test.Color + VALUE_PARAMETER name:value index:0 type: + SYNTHETIC_BODY kind=ENUM_VALUEOF + PROPERTY ENUM_CLASS_SPECIAL_MEMBER name:entries visibility:public modality:FINAL [val] + FUN ENUM_CLASS_SPECIAL_MEMBER name: visibility:public modality:FINAL <> () returnType: + correspondingProperty: PROPERTY ENUM_CLASS_SPECIAL_MEMBER name:entries visibility:public modality:FINAL [val] + SYNTHETIC_BODY kind=ENUM_ENTRIES diff --git a/native/native.tests/testData/klibIr/enum.kt b/native/native.tests/testData/klibIr/enum.kt new file mode 100644 index 00000000000..6ac08df192e --- /dev/null +++ b/native/native.tests/testData/klibIr/enum.kt @@ -0,0 +1,8 @@ +// FIR_IDENTICAL +package test + +enum class Color(val rgb: Int) { + RED(0xFF0000), + GREEN(0x00FF00), + BLUE(0x0000FF) +} \ No newline at end of file diff --git a/native/native.tests/testData/klibIr/enum.sig.ir.txt b/native/native.tests/testData/klibIr/enum.sig.ir.txt new file mode 100644 index 00000000000..cab1f25cb59 --- /dev/null +++ b/native/native.tests/testData/klibIr/enum.sig.ir.txt @@ -0,0 +1,42 @@ +MODULE_FRAGMENT name: + FILE fqName:test fileName:enum.kt + CLASS ENUM_CLASS name:Color signature:test/Color|null[0] modality:FINAL visibility:public superTypes:[] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:test.Color + CONSTRUCTOR signature:test/Color.|(kotlin.Int){}[0] visibility:private <> (rgb:) returnType:test.Color [primary] + VALUE_PARAMETER name:rgb index:0 type: + BLOCK_BODY + ENUM_CONSTRUCTOR_CALL 'UNBOUND IrConstructorPublicSymbolImpl' + <1>: test.Color + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS ENUM_CLASS name:Color signature:test/Color|null[0] modality:FINAL visibility:public superTypes:[]' + PROPERTY name:rgb signature:test/Color.rgb|{}rgb[0] visibility:public modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:rgb signature:[ test/Color.rgb|{}rgb[0] <- Local[|FIELD PROPERTY_BACKING_FIELD name:rgb type:kotlin.Int visibility:private [final]] ] type: visibility:private [final] + EXPRESSION_BODY + GET_VAR 'rgb: declared in test.Color.' type= origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: signature:test/Color.rgb.|(){}[0] visibility:public modality:FINAL <> ($this:test.Color) returnType: + correspondingProperty: PROPERTY name:rgb signature:test/Color.rgb|{}rgb[0] visibility:public modality:FINAL [val] + $this: VALUE_PARAMETER name: type:test.Color + BLOCK_BODY + RETURN type= from='public final fun (): declared in test.Color' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:rgb signature:[ test/Color.rgb|{}rgb[0] <- Local[|FIELD PROPERTY_BACKING_FIELD name:rgb type:kotlin.Int visibility:private [final]] ] type: visibility:private [final]' type= origin=null + receiver: GET_VAR ': test.Color declared in test.Color.' type=test.Color origin=null + ENUM_ENTRY name:RED signature:test/Color.RED|null[0] + init: EXPRESSION_BODY + ENUM_CONSTRUCTOR_CALL 'private constructor (rgb: ) [primary] declared in test.Color' + rgb: CONST Int type= value=16711680 + ENUM_ENTRY name:GREEN signature:test/Color.GREEN|null[0] + init: EXPRESSION_BODY + ENUM_CONSTRUCTOR_CALL 'private constructor (rgb: ) [primary] declared in test.Color' + rgb: CONST Int type= value=65280 + ENUM_ENTRY name:BLUE signature:test/Color.BLUE|null[0] + init: EXPRESSION_BODY + ENUM_CONSTRUCTOR_CALL 'private constructor (rgb: ) [primary] declared in test.Color' + rgb: CONST Int type= value=255 + FUN ENUM_CLASS_SPECIAL_MEMBER name:values signature:test/Color.values|values#static(){}[0] visibility:public modality:FINAL <> () returnType: + SYNTHETIC_BODY kind=ENUM_VALUES + FUN ENUM_CLASS_SPECIAL_MEMBER name:valueOf signature:test/Color.valueOf|valueOf#static(kotlin.String){}[0] visibility:public modality:FINAL <> (value:) returnType:test.Color + VALUE_PARAMETER name:value index:0 type: + SYNTHETIC_BODY kind=ENUM_VALUEOF + PROPERTY ENUM_CLASS_SPECIAL_MEMBER name:entries signature:test/Color.entries|#static{}entries[0] visibility:public modality:FINAL [val] + FUN ENUM_CLASS_SPECIAL_MEMBER name: signature:test/Color.entries.|#static(){}[0] visibility:public modality:FINAL <> () returnType: + correspondingProperty: PROPERTY ENUM_CLASS_SPECIAL_MEMBER name:entries signature:test/Color.entries|#static{}entries[0] visibility:public modality:FINAL [val] + SYNTHETIC_BODY kind=ENUM_ENTRIES diff --git a/native/native.tests/testData/klibIr/field.ir.txt b/native/native.tests/testData/klibIr/field.ir.txt new file mode 100644 index 00000000000..dffcdf96f59 --- /dev/null +++ b/native/native.tests/testData/klibIr/field.ir.txt @@ -0,0 +1,38 @@ +MODULE_FRAGMENT name: + FILE fqName:test fileName:field.kt + CLASS CLASS name:A modality:FINAL visibility:public superTypes:[] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:test.A + CONSTRUCTOR visibility:public <> () returnType:test.A [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'UNBOUND IrConstructorPublicSymbolImpl' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:A modality:FINAL visibility:public superTypes:[]' + PROPERTY name:x visibility:public modality:FINAL [var] + FIELD PROPERTY_BACKING_FIELD name:x type: visibility:private + EXPRESSION_BODY + CONST Int type= value=5 + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:test.A) returnType: + correspondingProperty: PROPERTY name:x visibility:public modality:FINAL [var] + $this: VALUE_PARAMETER name: type:test.A + BLOCK_BODY + RETURN type= from='public final fun (): declared in test.A' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:x type: visibility:private' type= origin=null + receiver: GET_VAR ': test.A declared in test.A.' type=test.A origin=null + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:test.A, :) returnType: + correspondingProperty: PROPERTY name:x visibility:public modality:FINAL [var] + $this: VALUE_PARAMETER name: type:test.A + VALUE_PARAMETER name: index:0 type: + BLOCK_BODY + SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:x type: visibility:private' type= origin=null + receiver: GET_VAR ': test.A declared in test.A.' type=test.A origin=null + value: GET_VAR ': declared in test.A.' type= origin=null + PROPERTY name:y visibility:public modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:y type: visibility:private [final] + EXPRESSION_BODY + CONST Int type= value=10 + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:test.A) returnType: + correspondingProperty: PROPERTY name:y visibility:public modality:FINAL [val] + $this: VALUE_PARAMETER name: type:test.A + BLOCK_BODY + RETURN type= from='public final fun (): declared in test.A' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:y type: visibility:private [final]' type= origin=null + receiver: GET_VAR ': test.A declared in test.A.' type=test.A origin=null diff --git a/native/native.tests/testData/klibIr/field.kt b/native/native.tests/testData/klibIr/field.kt new file mode 100644 index 00000000000..cfc4239cd57 --- /dev/null +++ b/native/native.tests/testData/klibIr/field.kt @@ -0,0 +1,7 @@ +// FIR_IDENTICAL +package test + +class A { + var x: Int = 5 + final val y: Int = 10 +} diff --git a/native/native.tests/testData/klibIr/field.sig.ir.txt b/native/native.tests/testData/klibIr/field.sig.ir.txt new file mode 100644 index 00000000000..4f431388e7f --- /dev/null +++ b/native/native.tests/testData/klibIr/field.sig.ir.txt @@ -0,0 +1,38 @@ +MODULE_FRAGMENT name: + FILE fqName:test fileName:field.kt + CLASS CLASS name:A signature:test/A|null[0] modality:FINAL visibility:public superTypes:[] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:test.A + CONSTRUCTOR signature:test/A.|(){}[0] visibility:public <> () returnType:test.A [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'UNBOUND IrConstructorPublicSymbolImpl' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:A signature:test/A|null[0] modality:FINAL visibility:public superTypes:[]' + PROPERTY name:x signature:test/A.x|{}x[0] visibility:public modality:FINAL [var] + FIELD PROPERTY_BACKING_FIELD name:x signature:[ test/A.x|{}x[0] <- Local[|FIELD PROPERTY_BACKING_FIELD name:x type:kotlin.Int visibility:private] ] type: visibility:private + EXPRESSION_BODY + CONST Int type= value=5 + FUN DEFAULT_PROPERTY_ACCESSOR name: signature:test/A.x.|(){}[0] visibility:public modality:FINAL <> ($this:test.A) returnType: + correspondingProperty: PROPERTY name:x signature:test/A.x|{}x[0] visibility:public modality:FINAL [var] + $this: VALUE_PARAMETER name: type:test.A + BLOCK_BODY + RETURN type= from='public final fun (): declared in test.A' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:x signature:[ test/A.x|{}x[0] <- Local[|FIELD PROPERTY_BACKING_FIELD name:x type:kotlin.Int visibility:private] ] type: visibility:private' type= origin=null + receiver: GET_VAR ': test.A declared in test.A.' type=test.A origin=null + FUN DEFAULT_PROPERTY_ACCESSOR name: signature:test/A.x.|(kotlin.Int){}[0] visibility:public modality:FINAL <> ($this:test.A, :) returnType: + correspondingProperty: PROPERTY name:x signature:test/A.x|{}x[0] visibility:public modality:FINAL [var] + $this: VALUE_PARAMETER name: type:test.A + VALUE_PARAMETER name: index:0 type: + BLOCK_BODY + SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:x signature:[ test/A.x|{}x[0] <- Local[|FIELD PROPERTY_BACKING_FIELD name:x type:kotlin.Int visibility:private] ] type: visibility:private' type= origin=null + receiver: GET_VAR ': test.A declared in test.A.' type=test.A origin=null + value: GET_VAR ': declared in test.A.' type= origin=null + PROPERTY name:y signature:test/A.y|{}y[0] visibility:public modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:y signature:[ test/A.y|{}y[0] <- Local[|FIELD PROPERTY_BACKING_FIELD name:x type:kotlin.Int visibility:private] ] type: visibility:private [final] + EXPRESSION_BODY + CONST Int type= value=10 + FUN DEFAULT_PROPERTY_ACCESSOR name: signature:test/A.y.|(){}[0] visibility:public modality:FINAL <> ($this:test.A) returnType: + correspondingProperty: PROPERTY name:y signature:test/A.y|{}y[0] visibility:public modality:FINAL [val] + $this: VALUE_PARAMETER name: type:test.A + BLOCK_BODY + RETURN type= from='public final fun (): declared in test.A' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:y signature:[ test/A.y|{}y[0] <- Local[|FIELD PROPERTY_BACKING_FIELD name:x type:kotlin.Int visibility:private] ] type: visibility:private [final]' type= origin=null + receiver: GET_VAR ': test.A declared in test.A.' type=test.A origin=null diff --git a/native/native.tests/testData/klibIr/fun.ir.txt b/native/native.tests/testData/klibIr/fun.ir.txt new file mode 100644 index 00000000000..1bd94fa683f --- /dev/null +++ b/native/native.tests/testData/klibIr/fun.ir.txt @@ -0,0 +1,22 @@ +MODULE_FRAGMENT name: + FILE fqName:test fileName:fun.kt + CLASS CLASS name:A modality:FINAL visibility:public superTypes:[] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:test.A + CONSTRUCTOR visibility:public <> () returnType:test.A [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'UNBOUND IrConstructorPublicSymbolImpl' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:A modality:FINAL visibility:public superTypes:[]' + FUN name:foo visibility:private modality:FINAL <> ($this:test.A) returnType: + $this: VALUE_PARAMETER name: type:test.A + BLOCK_BODY + RETURN type= from='private final fun foo (): declared in test.A' + CONST Int type= value=42 + FUN name:bar visibility:public modality:FINAL <> ($this:test.A, z:) returnType: + $this: VALUE_PARAMETER name: type:test.A + VALUE_PARAMETER name:z index:0 type: + BLOCK_BODY + RETURN type= from='public final fun bar (z: ): declared in test.A' + CALL 'UNBOUND IrSimpleFunctionPublicSymbolImpl' type= origin=PLUS + $this: CALL 'private final fun foo (): declared in test.A' type= origin=null + $this: GET_VAR ': test.A declared in test.A.bar' type=test.A origin=null + 1: GET_VAR 'z: declared in test.A.bar' type= origin=null diff --git a/native/native.tests/testData/klibIr/fun.kt b/native/native.tests/testData/klibIr/fun.kt new file mode 100644 index 00000000000..4bed42ed712 --- /dev/null +++ b/native/native.tests/testData/klibIr/fun.kt @@ -0,0 +1,7 @@ +// FIR_IDENTICAL +package test + +class A { + private fun foo() = 42 + public fun bar(z: Int) = foo() + z +} diff --git a/native/native.tests/testData/klibIr/fun.sig.ir.txt b/native/native.tests/testData/klibIr/fun.sig.ir.txt new file mode 100644 index 00000000000..4434d88d839 --- /dev/null +++ b/native/native.tests/testData/klibIr/fun.sig.ir.txt @@ -0,0 +1,22 @@ +MODULE_FRAGMENT name: + FILE fqName:test fileName:fun.kt + CLASS CLASS name:A signature:test/A|null[0] modality:FINAL visibility:public superTypes:[] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:test.A + CONSTRUCTOR signature:test/A.|(){}[0] visibility:public <> () returnType:test.A [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'UNBOUND IrConstructorPublicSymbolImpl' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:A signature:test/A|null[0] modality:FINAL visibility:public superTypes:[]' + FUN name:foo signature:test/A.foo|foo(){}[0] visibility:private modality:FINAL <> ($this:test.A) returnType: + $this: VALUE_PARAMETER name: type:test.A + BLOCK_BODY + RETURN type= from='private final fun foo (): declared in test.A' + CONST Int type= value=42 + FUN name:bar signature:test/A.bar|bar(kotlin.Int){}[0] visibility:public modality:FINAL <> ($this:test.A, z:) returnType: + $this: VALUE_PARAMETER name: type:test.A + VALUE_PARAMETER name:z index:0 type: + BLOCK_BODY + RETURN type= from='public final fun bar (z: ): declared in test.A' + CALL 'UNBOUND IrSimpleFunctionPublicSymbolImpl' type= origin=PLUS + $this: CALL 'private final fun foo (): declared in test.A' type= origin=null + $this: GET_VAR ': test.A declared in test.A.bar' type=test.A origin=null + 1: GET_VAR 'z: declared in test.A.bar' type= origin=null diff --git a/native/native.tests/testData/klibIr/typealias.ir.fir.txt b/native/native.tests/testData/klibIr/typealias.ir.fir.txt new file mode 100644 index 00000000000..cadb5e60856 --- /dev/null +++ b/native/native.tests/testData/klibIr/typealias.ir.fir.txt @@ -0,0 +1,11 @@ +MODULE_FRAGMENT name: + FILE fqName:test fileName:typealias.kt + TYPEALIAS name:PublicTypeAlias visibility:public expandedType:test.ClassName + TYPEALIAS name:InternalTypeAlias visibility:internal expandedType:test.ClassName + TYPEALIAS name:PrivateTypeAlias visibility:private expandedType:test.ClassName + CLASS CLASS name:ClassName modality:FINAL visibility:public superTypes:[] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:test.ClassName + CONSTRUCTOR visibility:public <> () returnType:test.ClassName [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'UNBOUND IrConstructorPublicSymbolImpl' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:ClassName modality:FINAL visibility:public superTypes:[]' diff --git a/native/native.tests/testData/klibIr/typealias.ir.txt b/native/native.tests/testData/klibIr/typealias.ir.txt new file mode 100644 index 00000000000..a3577fe3e60 --- /dev/null +++ b/native/native.tests/testData/klibIr/typealias.ir.txt @@ -0,0 +1,11 @@ +MODULE_FRAGMENT name: + FILE fqName:test fileName:typealias.kt + CLASS CLASS name:ClassName modality:FINAL visibility:public superTypes:[] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:test.ClassName + CONSTRUCTOR visibility:public <> () returnType:test.ClassName [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'UNBOUND IrConstructorPublicSymbolImpl' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:ClassName modality:FINAL visibility:public superTypes:[]' + TYPEALIAS name:PublicTypeAlias visibility:public expandedType:test.ClassName + TYPEALIAS name:InternalTypeAlias visibility:internal expandedType:test.ClassName + TYPEALIAS name:PrivateTypeAlias visibility:private expandedType:test.ClassName diff --git a/native/native.tests/testData/klibIr/typealias.kt b/native/native.tests/testData/klibIr/typealias.kt new file mode 100644 index 00000000000..f6622fbc861 --- /dev/null +++ b/native/native.tests/testData/klibIr/typealias.kt @@ -0,0 +1,7 @@ +package test + +class ClassName + +typealias PublicTypeAlias = ClassName +internal typealias InternalTypeAlias = ClassName +private typealias PrivateTypeAlias = ClassName \ No newline at end of file diff --git a/native/native.tests/testData/klibIr/typealias.sig.ir.fir.txt b/native/native.tests/testData/klibIr/typealias.sig.ir.fir.txt new file mode 100644 index 00000000000..e2e546dc510 --- /dev/null +++ b/native/native.tests/testData/klibIr/typealias.sig.ir.fir.txt @@ -0,0 +1,11 @@ +MODULE_FRAGMENT name: + FILE fqName:test fileName:typealias.kt + TYPEALIAS name:PublicTypeAlias signature:test/PublicTypeAlias|null[0] visibility:public expandedType:test.ClassName + TYPEALIAS name:InternalTypeAlias signature:test/InternalTypeAlias|null[0] visibility:internal expandedType:test.ClassName + TYPEALIAS name:PrivateTypeAlias signature:[ File 'typealias.kt' <- test/PrivateTypeAlias|null[0] ] visibility:private expandedType:test.ClassName + CLASS CLASS name:ClassName signature:test/ClassName|null[0] modality:FINAL visibility:public superTypes:[] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:test.ClassName + CONSTRUCTOR signature:test/ClassName.|(){}[0] visibility:public <> () returnType:test.ClassName [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'UNBOUND IrConstructorPublicSymbolImpl' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:ClassName signature:test/ClassName|null[0] modality:FINAL visibility:public superTypes:[]' diff --git a/native/native.tests/testData/klibIr/typealias.sig.ir.txt b/native/native.tests/testData/klibIr/typealias.sig.ir.txt new file mode 100644 index 00000000000..9124f08e454 --- /dev/null +++ b/native/native.tests/testData/klibIr/typealias.sig.ir.txt @@ -0,0 +1,11 @@ +MODULE_FRAGMENT name: + FILE fqName:test fileName:typealias.kt + CLASS CLASS name:ClassName signature:test/ClassName|null[0] modality:FINAL visibility:public superTypes:[] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:test.ClassName + CONSTRUCTOR signature:test/ClassName.|(){}[0] visibility:public <> () returnType:test.ClassName [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'UNBOUND IrConstructorPublicSymbolImpl' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:ClassName signature:test/ClassName|null[0] modality:FINAL visibility:public superTypes:[]' + TYPEALIAS name:PublicTypeAlias signature:test/PublicTypeAlias|null[0] visibility:public expandedType:test.ClassName + TYPEALIAS name:InternalTypeAlias signature:test/InternalTypeAlias|null[0] visibility:internal expandedType:test.ClassName + TYPEALIAS name:PrivateTypeAlias signature:[ File 'typealias.kt' <- test/PrivateTypeAlias|null[0] ] visibility:private expandedType:test.ClassName diff --git a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/FirNativeKLibContentsTestGenerated.java b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/FirNativeKlibContentsTestGenerated.java similarity index 99% rename from native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/FirNativeKLibContentsTestGenerated.java rename to native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/FirNativeKlibContentsTestGenerated.java index 77be6d7f87c..d0b2ec46724 100644 --- a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/FirNativeKLibContentsTestGenerated.java +++ b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/FirNativeKlibContentsTestGenerated.java @@ -22,7 +22,7 @@ import java.util.regex.Pattern; @TestDataPath("$PROJECT_ROOT") @Tag("frontend-fir") @FirPipeline() -public class FirNativeKLibContentsTestGenerated extends AbstractNativeKlibContentsTest { +public class FirNativeKlibContentsTestGenerated extends AbstractNativeKlibContentsTest { @Test public void testAllFilesPresentInKlibContents() throws Exception { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("native/native.tests/testData/klibContents"), Pattern.compile("^([^_](.+)).kt$"), null, true); diff --git a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/FirNativeKlibIrTestGenerated.java b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/FirNativeKlibIrTestGenerated.java new file mode 100644 index 00000000000..0b28ac678bd --- /dev/null +++ b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/FirNativeKlibIrTestGenerated.java @@ -0,0 +1,66 @@ +/* + * 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/klibIr") +@TestDataPath("$PROJECT_ROOT") +@Tag("frontend-fir") +@FirPipeline() +public class FirNativeKlibIrTestGenerated extends AbstractNativeKlibIrTest { + @Test + public void testAllFilesPresentInKlibIr() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("native/native.tests/testData/klibIr"), Pattern.compile("^([^_](.+)).kt$"), null, true); + } + + @Test + @TestMetadata("class.kt") + public void testClass() throws Exception { + runTest("native/native.tests/testData/klibIr/class.kt"); + } + + @Test + @TestMetadata("constructor.kt") + public void testConstructor() throws Exception { + runTest("native/native.tests/testData/klibIr/constructor.kt"); + } + + @Test + @TestMetadata("enum.kt") + public void testEnum() throws Exception { + runTest("native/native.tests/testData/klibIr/enum.kt"); + } + + @Test + @TestMetadata("field.kt") + public void testField() throws Exception { + runTest("native/native.tests/testData/klibIr/field.kt"); + } + + @Test + @TestMetadata("fun.kt") + public void testFun() throws Exception { + runTest("native/native.tests/testData/klibIr/fun.kt"); + } + + @Test + @TestMetadata("typealias.kt") + public void testTypealias() throws Exception { + runTest("native/native.tests/testData/klibIr/typealias.kt"); + } +} diff --git a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeKLibContentsTestGenerated.java b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeKlibContentsTestGenerated.java similarity index 99% rename from native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeKLibContentsTestGenerated.java rename to native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeKlibContentsTestGenerated.java index 862d765142f..9e0916647ee 100644 --- a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeKLibContentsTestGenerated.java +++ b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeKlibContentsTestGenerated.java @@ -18,7 +18,7 @@ import java.util.regex.Pattern; @SuppressWarnings("all") @TestMetadata("native/native.tests/testData/klibContents") @TestDataPath("$PROJECT_ROOT") -public class NativeKLibContentsTestGenerated extends AbstractNativeKlibContentsTest { +public class NativeKlibContentsTestGenerated extends AbstractNativeKlibContentsTest { @Test public void testAllFilesPresentInKlibContents() throws Exception { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("native/native.tests/testData/klibContents"), Pattern.compile("^([^_](.+)).kt$"), null, true); diff --git a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeKlibIrTestGenerated.java b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeKlibIrTestGenerated.java new file mode 100644 index 00000000000..e91c97e9ccc --- /dev/null +++ b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeKlibIrTestGenerated.java @@ -0,0 +1,62 @@ +/* + * 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/klibIr") +@TestDataPath("$PROJECT_ROOT") +public class NativeKlibIrTestGenerated extends AbstractNativeKlibIrTest { + @Test + public void testAllFilesPresentInKlibIr() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("native/native.tests/testData/klibIr"), Pattern.compile("^([^_](.+)).kt$"), null, true); + } + + @Test + @TestMetadata("class.kt") + public void testClass() throws Exception { + runTest("native/native.tests/testData/klibIr/class.kt"); + } + + @Test + @TestMetadata("constructor.kt") + public void testConstructor() throws Exception { + runTest("native/native.tests/testData/klibIr/constructor.kt"); + } + + @Test + @TestMetadata("enum.kt") + public void testEnum() throws Exception { + runTest("native/native.tests/testData/klibIr/enum.kt"); + } + + @Test + @TestMetadata("field.kt") + public void testField() throws Exception { + runTest("native/native.tests/testData/klibIr/field.kt"); + } + + @Test + @TestMetadata("fun.kt") + public void testFun() throws Exception { + runTest("native/native.tests/testData/klibIr/fun.kt"); + } + + @Test + @TestMetadata("typealias.kt") + public void testTypealias() throws Exception { + runTest("native/native.tests/testData/klibIr/typealias.kt"); + } +} diff --git a/native/native.tests/tests/org/jetbrains/kotlin/generators/tests/GenerateNativeTests.kt b/native/native.tests/tests/org/jetbrains/kotlin/generators/tests/GenerateNativeTests.kt index 111de7cb729..b70f1ad67d2 100644 --- a/native/native.tests/tests/org/jetbrains/kotlin/generators/tests/GenerateNativeTests.kt +++ b/native/native.tests/tests/org/jetbrains/kotlin/generators/tests/GenerateNativeTests.kt @@ -196,14 +196,14 @@ fun main() { // Klib contents tests testGroup("native/native.tests/tests-gen", "native/native.tests/testData") { testClass( - suiteTestClassName = "NativeKLibContentsTestGenerated" + suiteTestClassName = "NativeKlibContentsTestGenerated" ) { model("klibContents", pattern = "^([^_](.+)).kt$", recursive = true) } } testGroup("native/native.tests/tests-gen", "native/native.tests/testData") { testClass( - suiteTestClassName = "FirNativeKLibContentsTestGenerated", + suiteTestClassName = "FirNativeKlibContentsTestGenerated", annotations = listOf( *frontendFir() ) @@ -212,6 +212,25 @@ fun main() { } } + // Klib ir tests + testGroup("native/native.tests/tests-gen", "native/native.tests/testData") { + testClass( + suiteTestClassName = "NativeKlibIrTestGenerated", + ) { + model("klibIr", pattern = "^([^_](.+)).kt$", recursive = true) + } + } + testGroup("native/native.tests/tests-gen", "native/native.tests/testData") { + testClass( + suiteTestClassName = "FirNativeKlibIrTestGenerated", + annotations = listOf( + *frontendFir() + ) + ) { + model("klibIr", pattern = "^([^_](.+)).kt$", recursive = true) + } + } + // LLDB integration tests. testGroup("native/native.tests/tests-gen", "native/native.tests/testData") { testClass( diff --git a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/AbstractNativeKlibEvolutionTest.kt b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/AbstractNativeKlibEvolutionTest.kt index 09cf64f94ad..43792ca24f1 100644 --- a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/AbstractNativeKlibEvolutionTest.kt +++ b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/AbstractNativeKlibEvolutionTest.kt @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.konan.blackboxtest.support.runner.TestRunChecks import org.jetbrains.kotlin.konan.blackboxtest.support.settings.Binaries import org.jetbrains.kotlin.konan.blackboxtest.support.settings.CacheMode import org.jetbrains.kotlin.konan.blackboxtest.support.settings.KotlinNativeTargets +import org.jetbrains.kotlin.konan.blackboxtest.support.settings.PipelineType import org.jetbrains.kotlin.konan.blackboxtest.support.settings.Timeouts import org.jetbrains.kotlin.konan.blackboxtest.support.util.* import org.jetbrains.kotlin.test.Directives @@ -36,7 +37,7 @@ import org.jetbrains.kotlin.compatibility.binary.TestModule as TModule abstract class AbstractNativeKlibEvolutionTest : AbstractNativeSimpleTest() { // Const evaluation tests muted for FIR because FIR does const propagation. private fun isIgnoredTest(filePath: String): Boolean { - if (!this::class.java.simpleName.startsWith("Fir")) + if (testRunSettings.get() != PipelineType.K2) return false val fileName = filePath.substringAfterLast('/') diff --git a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/AbstractNativeKlibIrTest.kt b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/AbstractNativeKlibIrTest.kt new file mode 100644 index 00000000000..fdc4f117f2f --- /dev/null +++ b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/AbstractNativeKlibIrTest.kt @@ -0,0 +1,84 @@ +/* + * 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.TestDataFile +import org.jetbrains.kotlin.konan.blackboxtest.support.PackageName +import org.jetbrains.kotlin.konan.blackboxtest.support.TestCase +import org.jetbrains.kotlin.konan.blackboxtest.support.TestCaseId +import org.jetbrains.kotlin.konan.blackboxtest.support.TestCompilerArgs +import org.jetbrains.kotlin.konan.blackboxtest.support.TestFile +import org.jetbrains.kotlin.konan.blackboxtest.support.TestKind +import org.jetbrains.kotlin.konan.blackboxtest.support.TestModule +import org.jetbrains.kotlin.konan.blackboxtest.support.TestRunnerType +import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilationArtifact +import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilationResult +import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilationResult.Companion.assertSuccess +import org.jetbrains.kotlin.konan.blackboxtest.support.runner.TestRunChecks +import org.jetbrains.kotlin.konan.blackboxtest.support.settings.KotlinNativeClassLoader +import org.jetbrains.kotlin.konan.blackboxtest.support.settings.PipelineType +import org.jetbrains.kotlin.konan.blackboxtest.support.settings.Timeouts +import org.jetbrains.kotlin.konan.blackboxtest.support.util.getAbsoluteFile +import org.jetbrains.kotlin.konan.blackboxtest.support.util.getIr +import org.jetbrains.kotlin.test.services.JUnit5Assertions.assertEqualsToFile +import org.junit.jupiter.api.Tag +import java.io.File + +@Tag("klib") +abstract class AbstractNativeKlibIrTest : AbstractNativeSimpleTest() { + protected fun runTest(@TestDataFile testPath: String) { + val testPathFull = getAbsoluteFile(testPath) + muteTestIfNecessary(testPathFull) + + val testCase: TestCase = generateTestCaseWithSingleSource( + testPathFull, + listOf("-Xklib-relative-path-base=${testPathFull.parent}") + ) + val testCompilationResult: TestCompilationResult.Success = compileToLibrary(testCase) + + val testPathNoExtension = testPathFull.canonicalPath.substringBeforeLast(".") + + val firSpecificExt = + if (testRunSettings.get() == PipelineType.K2 && !firIdentical(testPathFull)) + ".fir" + else "" + + val expectedContentsNoSig = File("$testPathNoExtension.ir$firSpecificExt.txt") + assertIrMatchesExpected(testCompilationResult, expectedContentsNoSig, printSignatures = false) + + val expectedContentsWithSig = File("$testPathNoExtension.sig.ir$firSpecificExt.txt") + assertIrMatchesExpected(testCompilationResult, expectedContentsWithSig, printSignatures = true) + } + + private fun assertIrMatchesExpected( + compilationResult: TestCompilationResult, + expectedContents: File, + printSignatures: Boolean + ) { + val artifact = compilationResult.assertSuccess().resultingArtifact + val kotlinNativeClassLoader = testRunSettings.get() + val klibIr = artifact.getIr(kotlinNativeClassLoader.classLoader, printSignatures) + assertEqualsToFile(expectedContents, klibIr) + } + + private fun generateTestCaseWithSingleSource(source: File, extraArgs: List): TestCase { + val moduleName: String = source.name + val module = TestModule.Exclusive(moduleName, emptySet(), emptySet(), emptySet()) + module.files += TestFile.createCommitted(source, module) + + return TestCase( + id = TestCaseId.Named(moduleName), + kind = TestKind.STANDALONE, + modules = setOf(module), + freeCompilerArgs = TestCompilerArgs(extraArgs), + nominalPackageName = PackageName.EMPTY, + checks = TestRunChecks.Default(testRunSettings.get().executionTimeout), + extras = TestCase.WithTestRunnerExtras(TestRunnerType.DEFAULT) + ).apply { + initialize(null, null) + } + } +} diff --git a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/NativeSimpleTestUtils.kt b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/NativeSimpleTestUtils.kt index 1255917fdc0..857250ddd69 100644 --- a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/NativeSimpleTestUtils.kt +++ b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/NativeSimpleTestUtils.kt @@ -309,6 +309,9 @@ internal fun AbstractNativeSimpleTest.muteTestIfNecessary(testDataFileContents: Assumptions.assumeFalse(mutedWhenValues.any { it == pipelineType.mutedOption.name }) } +internal fun AbstractNativeSimpleTest.firIdentical(testDataFile: File) = + InTextDirectivesUtils.isDirectiveDefined(FileUtil.loadFile(testDataFile), TestDirectives.FIR_IDENTICAL.name) + internal fun AbstractNativeSimpleTest.freeCompilerArgs(testDataFile: File) = freeCompilerArgs(FileUtil.loadFile(testDataFile)) internal fun AbstractNativeSimpleTest.freeCompilerArgs(testDataFileContents: String) = directiveValues(testDataFileContents, TestDirectives.FREE_COMPILER_ARGS.name) diff --git a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/TestDirectives.kt b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/TestDirectives.kt index 0424e12d47f..4d1efc1e7aa 100644 --- a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/TestDirectives.kt +++ b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/TestDirectives.kt @@ -140,6 +140,10 @@ internal object TestDirectives : SimpleDirectivesContainer() { Usage: // MUTED_WHEN: [K1, K2] In native simple tests, specify the pipeline types to mute the test""".trimIndent(), ) + + val FIR_IDENTICAL by directive( + description = "Test behavior should be identical for FIR testing" + ) } internal enum class TestKind { diff --git a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/util/TestCompilationArtifacts.kt b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/util/TestCompilationArtifacts.kt index 5c97bbba1ae..aad3503df70 100644 --- a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/util/TestCompilationArtifacts.kt +++ b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/util/TestCompilationArtifacts.kt @@ -6,14 +6,27 @@ package org.jetbrains.kotlin.konan.blackboxtest.support.util import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilationArtifact +import java.io.File -internal fun TestCompilationArtifact.KLIB.getContents(kotlinNativeClassLoader: ClassLoader): String { +private fun invokeKlibTool(kotlinNativeClassLoader: ClassLoader, klibFile: File, functionName: String, vararg args: Any): String { val libraryClass = Class.forName("org.jetbrains.kotlin.cli.klib.Library", true, kotlinNativeClassLoader) - val entryPoint = libraryClass.declaredMethods.single { it.name == "contents" } + val entryPoint = libraryClass.declaredMethods.single { it.name == functionName } val lib = libraryClass.getDeclaredConstructor(String::class.java, String::class.java, String::class.java) .newInstance(klibFile.canonicalPath, null, "host") val output = StringBuilder() - entryPoint.invoke(lib, output, false) + entryPoint.invoke(lib, output, *args) return output.toString() + +} + +internal fun TestCompilationArtifact.KLIB.getContents(kotlinNativeClassLoader: ClassLoader): String { + return invokeKlibTool(kotlinNativeClassLoader, klibFile, "contents", false) +} + +internal fun TestCompilationArtifact.KLIB.getIr( + kotlinNativeClassLoader: ClassLoader, + printSignatures: Boolean = false, +): String { + return invokeKlibTool(kotlinNativeClassLoader, klibFile, "ir", printSignatures) }