[K/N] Run irText tests for K1/Native

^KT-58240
This commit is contained in:
Vladimir Sukharev
2023-08-09 22:21:59 +02:00
committed by Space Team
parent 40c9f831e2
commit 3aa6c9e74d
69 changed files with 3376 additions and 73 deletions
@@ -5,6 +5,9 @@
// IGNORE_BACKEND_K1: JS_IR
// IGNORE_BACKEND_K1: JS_IR_ES6
// KT-61141: IrSimpleFunctionPublicSymbolImpl for /Derived.foo|foo(kotlin.String){}[0] is already bound
// IGNORE_BACKEND_K1: NATIVE
open class Base<T> {
fun foo(x: T) {}
fun foo(y: String) {}
+3
View File
@@ -1,6 +1,9 @@
// IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND: JS_IR_ES6
// KT-61141: absent enum fake_overrides: finalize, getDeclaringClass, clone
// IGNORE_BACKEND: NATIVE
class TestClass
interface TestInterface
+2 -2
View File
@@ -1,7 +1,7 @@
// FIR_IDENTICAL
// SKIP_KLIB_TEST
// IGNORE_BACKEND: JS_IR, JS_IR_ES6
// STATUS: This should not work in JS, Cloneable is JVM-specific API
// TARGET_BACKEND: JVM
// STATUS: Cloneable is JVM-specific API
class A : Cloneable
+3
View File
@@ -5,6 +5,9 @@
// MUTE_SIGNATURE_COMPARISON_K2: ANY
// ^ KT-57775
// KT-61141: absent enum fake_overrides: finalize, getDeclaringClass, clone
// IGNORE_BACKEND: NATIVE
enum class TestEnum1 {
TEST1, TEST2
}
@@ -4,6 +4,9 @@
// MUTE_SIGNATURE_COMPARISON_K2: ANY
// ^ KT-57775
// KT-61141: absent enum fake_overrides: finalize, getDeclaringClass, clone
// IGNORE_BACKEND: NATIVE
enum class TestFinalEnum1 {
X1
}
@@ -4,6 +4,9 @@
// MUTE_SIGNATURE_COMPARISON_K2: ANY
// ^ KT-57775
// KT-61141: absent enum fake_overrides: finalize, getDeclaringClass, clone
// IGNORE_BACKEND: NATIVE
enum class A {
X("asd"),
Y() {
@@ -5,6 +5,9 @@
// MUTE_SIGNATURE_COMPARISON_K2: ANY
// ^ KT-57775
// KT-61141: absent enum fake_overrides: finalize(K1), getDeclaringClass(K1), clone(K2),
// IGNORE_BACKEND: NATIVE
enum class Test0(val x: Int) {
ZERO;
constructor() : this(0)
@@ -1,6 +1,9 @@
// IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND: JS_IR_ES6
// KT-61141: absent enum fake_overrides: finalize, getDeclaringClass, clone
// IGNORE_BACKEND: NATIVE
annotation class TestAnn(val x: String)
@TestAnn("class")
@@ -4,6 +4,9 @@
// SKIP_SIGNATURE_DUMP
// ^ Difference in annotations generated by K1 and K2
// KT-61141: absent enum fake_overrides: finalize, getDeclaringClass, clone
// IGNORE_BACKEND: NATIVE
annotation class TestAnn(val x: String)
enum class TestEnum {
@@ -1,6 +1,9 @@
// IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND: JS_IR_ES6
// KT-61141: absent enum fake_overrides: finalize, getDeclaringClass, clone
// IGNORE_BACKEND: NATIVE
enum class En { A, B, C, D }
annotation class TestAnn(val x: En)
@@ -1,6 +1,8 @@
// WITH_STDLIB
// IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND: JS_IR_ES6
// KT-61141: kotlin.collections.HashMap instead of java.util.HashMap
// IGNORE_BACKEND: NATIVE
class C {
val test1 = 0
@@ -1,4 +1,6 @@
// !LANGUAGE: +ContextReceivers
// KT-61141: K1/Native does not support context receivers
// IGNORE_BACKEND_K1: NATIVE
fun withContext(f: context(String) () -> String) = f("OK")
@@ -1,6 +1,9 @@
// !LANGUAGE: +ContextReceivers
// IGNORE_BACKEND: JS_IR
// KT-61141: kotlin.Comparator instead of java.util.Comparator
// IGNORE_BACKEND: NATIVE
data class Pair<A, B>(val first: A, val second: B)
context(Comparator<T>)
@@ -1,4 +1,6 @@
// !LANGUAGE: +ContextReceivers
// KT-61141: K1/Native does not support context receivers
// IGNORE_BACKEND_K1: NATIVE
class Param
class O {
@@ -1,4 +1,6 @@
// !LANGUAGE: +ContextReceivers
// KT-61141: K1/Native does not support context receivers
// IGNORE_BACKEND_K1: NATIVE
class Param
class C {
@@ -1,4 +1,6 @@
// !LANGUAGE: +ContextReceivers
// KT-61141: K1/Native does not support context receivers
// IGNORE_BACKEND_K1: NATIVE
class C {
val result = "OK"
@@ -1,6 +1,8 @@
// WITH_STDLIB
// IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND: JS_IR_ES6
// KT-61141: kotlin.collections.HashMap instead of java.util.HashMap
// IGNORE_BACKEND: NATIVE
val test1 by lazy { 42 }
+3
View File
@@ -2,6 +2,9 @@
// IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND: JS_IR_ES6
// KT-61141: throws kotlin.RuntimeException instead of java.lang.RuntimeException
// IGNORE_BACKEND: NATIVE
@Target(AnnotationTarget.TYPE)
annotation class MySerializable(val c: kotlin.reflect.KClass<*>)
@@ -2,6 +2,10 @@
// IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND: JS_IR_ES6
// KT-61141: `println (message: kotlin.Any?)` instead of `println (message: kotlin.Int)`
// KT-61141: `kotlin.collections.HashMap` instead of `java.util.HashMap`
// IGNORE_BACKEND: NATIVE
fun test1() {
val x by lazy { 42 }
println(x)
@@ -2,6 +2,9 @@
// IGNORE_BACKEND_K1: JVM_IR, JS_IR
// !LANGUAGE: +MultiPlatformProjects
// KT-61141: NO_ACTUAL_FOR_EXPECT: Expected class 'C' has no actual declaration in module <common> for Native (21,14) in /common.kt
// IGNORE_BACKEND_K1: NATIVE
// MODULE: common
// FILE: common.kt
@@ -3,6 +3,9 @@
// SKIP_KLIB_TEST
// LANGUAGE: +MultiPlatformProjects
// KT-61141: NO_ACTUAL_FOR_EXPECT: Expected class 'C1' has no actual declaration in module <common> for Native (9,19) in /common.kt
// IGNORE_BACKEND_K1: NATIVE
// MODULE: common
// FILE: common.kt
@@ -5,6 +5,9 @@
// IGNORE_BACKEND_K1: JS_IR
// IGNORE_BACKEND_K1: JS_IR_ES6
// KT-61141: absent enum fake_overrides: finalize, getDeclaringClass, clone
// IGNORE_BACKEND_K1: NATIVE
expect enum class MyEnum {
FOO,
BAR
@@ -1,6 +1,8 @@
// WITH_STDLIB
// IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND: JS_IR_ES6
// KT-61141: kotlin.collections.HashMap instead of java.util.HashMap
// IGNORE_BACKEND: NATIVE
val test1 = 0
@@ -3,6 +3,8 @@
// LANGUAGE: -ProhibitIllegalValueParameterUsageInDefaultArguments
// IGNORE_BACKEND_K1: JS_IR
// IGNORE_BACKEND_K1: JS_IR_ES6
// KT-61141: catches kotlin.Exception instead of java.lang.Exception
// IGNORE_BACKEND_K1: NATIVE
fun f(
f1: () -> String = { f2() },
@@ -4,6 +4,9 @@
// !IGNORE_ERRORS
// DIAGNOSTICS: -UNRESOLVED_REFERENCE -OVERLOAD_RESOLUTION_AMBIGUITY
// KT-61141: org.jetbrains.kotlin.psi2ir.generators.ErrorExpressionException: null: KtNameReferenceExpression: unresolved
// IGNORE_BACKEND: NATIVE
val test1 = unresolved
val test2: Unresolved =
@@ -4,6 +4,9 @@
// !IGNORE_ERRORS
// DIAGNOSTICS: -BREAK_OR_CONTINUE_OUTSIDE_A_LOOP -NOT_A_LOOP_LABEL -UNRESOLVED_REFERENCE -BREAK_OR_CONTINUE_JUMPS_ACROSS_FUNCTION_BOUNDARY
// KT-61141: java.lang.RuntimeException: Loop not found for break expression: break
// IGNORE_BACKEND: NATIVE
fun test1() {
break
continue
@@ -6,6 +6,9 @@
// DIAGNOSTICS: -NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER -BREAK_OR_CONTINUE_OUTSIDE_A_LOOP -UNEXPECTED_TRAILING_LAMBDA_ON_A_NEW_LINE -NO_VALUE_FOR_PARAMETER -NOT_A_LOOP_LABEL -UNRESOLVED_REFERENCE -TYPE_MISMATCH -BREAK_OR_CONTINUE_JUMPS_ACROSS_FUNCTION_BOUNDARY
// WITH_STDLIB
// KT-61141: NPE at org.jetbrains.kotlin.psi2ir.generators.ArgumentsGenerationUtilsKt.pregenerateValueArgumentsUsing()
// IGNORE_BACKEND: NATIVE
inline fun foo(block: () -> Unit) { block() }
inline fun bar(block1: () -> Unit, noinline block2: () -> Unit) {
@@ -2,6 +2,9 @@
// IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND: JS_IR_ES6
// KT-61141: throws kotlin.AssertionError instead of java.lang.AssertionError
// IGNORE_BACKEND: NATIVE
fun testBreakFor() {
val xs = IntArray(10) { i -> i }
var k = 0
@@ -2,5 +2,8 @@
// IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND: JS_IR_ES6
// KT-61141: rethrows kotlin.Exception instead of java.lang.Exception
// IGNORE_BACKEND: NATIVE
fun test(f: () -> Unit) =
try { f() } catch (e: Exception) { throw e }
@@ -4,6 +4,9 @@
// MUTE_SIGNATURE_COMPARISON_K2: ANY
// ^ KT-57427, KT-57430
// KT-61141: absent enum fake_overrides: finalize, getDeclaringClass, clone
// IGNORE_BACKEND: NATIVE
enum class X {
B {
@@ -4,6 +4,9 @@
// SKIP_SIGNATURE_DUMP
// ^ Types of properties of anonymous classes generated by K1 and K2 are different
// KT-61141: absent enum fake_overrides: finalize, getDeclaringClass, clone
// IGNORE_BACKEND: NATIVE
enum class MyEnum {
Z {
var counter = 0
@@ -1,6 +1,9 @@
// IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND: JS_IR_ES6
// KT-61141: absent enum fake_overrides: finalize, getDeclaringClass, clone
// IGNORE_BACKEND: NATIVE
enum class A { V1 }
fun testVariableAssignment_throws(a: A) {
+3
View File
@@ -2,6 +2,9 @@
// IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND: JS_IR_ES6
// KT-61141: `println (message: kotlin.Any?)` instead of `println (message: kotlin.Int)`
// IGNORE_BACKEND: NATIVE
fun testEmpty(ss: List<String>) {
for (s in ss);
}
@@ -2,6 +2,9 @@
// IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND: JS_IR_ES6
// KT-61141: `println (message: kotlin.Any?)` instead of `println (message: kotlin.Int)`
// IGNORE_BACKEND: NATIVE
object FiveTimes
class IntCell(var value: Int)
@@ -7,6 +7,10 @@ fun interface Foo : Function0<Int> {
// Mangled name: Foo#invoke(){}kotlin.Int
// Public signature: /Foo.invoke|906964710558498066[0]
// Public signature debug description: invoke(){}kotlin.Int
// CHECK JS_IR NATIVE:
// Mangled name: Foo#invoke(){}
// Public signature: /Foo.invoke|-4663091332620260873[0]
// Public signature debug description: invoke(){}
abstract /* fake */ override operator fun invoke(): Int
}
@@ -15,6 +19,10 @@ fun interface Foo : Function0<Int> {
// Mangled name: #id(Foo){}kotlin.Any
// Public signature: /id|-7816997914602483733[0]
// Public signature debug description: id(Foo){}kotlin.Any
// CHECK JS_IR NATIVE:
// Mangled name: #id(Foo){}
// Public signature: /id|-443964874282345181[0]
// Public signature debug description: id(Foo){}
fun id(foo: Foo): Any
// CHECK:
+1 -1
View File
@@ -1,5 +1,5 @@
// WITH_STDLIB
// IGNORE_BACKEND_K2: JS_IR, JS_IR_ES6
// IGNORE_BACKEND_K2: JS_IR, JS_IR_ES6, NATIVE
// ^ the order of fake overrides is different on K2
interface X {
+3
View File
@@ -1,6 +1,9 @@
// IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND: JS_IR_ES6
// KT-61141: throws kotlin.Exception instead of java.lang.Exception
// IGNORE_BACKEND: NATIVE
fun <T> magic(): T = throw Exception()
fun <T> test(value: T, value2: T) {
+3
View File
@@ -2,6 +2,9 @@
// IGNORE_BACKEND: JS_IR_ES6
// ISSUE: KT-48708
// KT-61141: throws kotlin.Exception instead of java.lang.Exception
// IGNORE_BACKEND: NATIVE
fun test(b: Boolean) {
val x = if (b) {
3
+3
View File
@@ -3,6 +3,9 @@
// IGNORE_BACKEND: JS_IR_ES6
// ISSUE: KT-48806
// KT-61141: throws kotlin.RuntimeException instead of java.lang.RuntimeException, and catches kotlin.Exception instead of java.lang.Exception
// IGNORE_BACKEND: NATIVE
class A {
val test_1: Int = try{
throw RuntimeException()
@@ -1,6 +1,9 @@
// IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND: JS_IR_ES6
// KT-61141: absent enum fake_overrides: finalize, getDeclaringClass, clone
// IGNORE_BACKEND: NATIVE
object A
enum class En { X }
@@ -4,6 +4,9 @@
// IGNORE_BACKEND_K1: JS_IR
// IGNORE_BACKEND_K1: JS_IR_ES6
// KT-61141: Extra invocations of toLong(), toShort(), etc.. after unaryMinus()
// IGNORE_BACKEND_K1: NATIVE
val test1: Long = 42
val test2: Short = 42
val test3: Byte = 42
+2
View File
@@ -3,6 +3,8 @@
// IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND: JS_IR_ES6
// KT-61141: `println (message: kotlin.Any?)` instead of `println (message: kotlin.Int)`
// IGNORE_BACKEND: NATIVE
fun expectsString(s: String) {}
fun expectsInt(i: Int) {}
@@ -1,6 +1,9 @@
// IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND: JS_IR_ES6
// KT-61141: absent enum fake_overrides: finalize, getDeclaringClass, clone
// IGNORE_BACKEND: NATIVE
val n: Any? = null
enum class En(val x: String?) {
+3
View File
@@ -1,6 +1,9 @@
// IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND: JS_IR_ES6
// KT-61141: absent enum fake_overrides: finalize, getDeclaringClass, clone
// IGNORE_BACKEND: NATIVE
enum class Enum { A }
object A
val a = 0
@@ -1,6 +1,9 @@
// IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND: JS_IR_ES6
// KT-61141: absent enum fake_overrides: finalize, getDeclaringClass, clone
// IGNORE_BACKEND: NATIVE
enum class En { A, B, C }
fun test() {
+3
View File
@@ -3,6 +3,9 @@
// IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND: JS_IR_ES6
// KT-61141: `set()` throws kotlin.IllegalStateException instead of java.lang.IllegalStateException
// IGNORE_BACKEND: NATIVE
sealed class ArrayMap<T : Any> : Iterable<T> {
abstract val size: Int
@@ -7,6 +7,9 @@
// MUTE_SIGNATURE_COMPARISON_K2: ANY
// ^ KT-57788
// KT-61141: ImplicitReceiverStack & PersistentImplicitReceiverStack miss fake overrides `forEach` & `spliterator`
// IGNORE_BACKEND: NATIVE
interface SymbolOwner<E : SymbolOwner<E>>
interface Symbol<E : SymbolOwner<E>>
+3
View File
@@ -4,6 +4,9 @@
// MUTE_SIGNATURE_COMPARISON_K2: JVM_IR
// ^ KT-57755
// KT-61141: `println (message: kotlin.Any?)` instead of `println (message: kotlin.Int)`
// IGNORE_BACKEND_K1: NATIVE
fun main() {
val (a: Any, _) = 1 to 2
println(a)
@@ -7,6 +7,9 @@
// MUTE_SIGNATURE_COMPARISON_K2: ANY
// ^ KT-57427
// KT-61141: absent enum fake_overrides: finalize, getDeclaringClass, clone
// IGNORE_BACKEND: NATIVE
class Wrapper(var baseUrl: String)
enum class ConfigurationParameter {
@@ -2,6 +2,9 @@
// IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND: JS_IR_ES6
// KT-61141: absent enum fake_overrides: finalize, getDeclaringClass, clone
// IGNORE_BACKEND: NATIVE
enum class EE(val myName: String = this.toString().lowercase()) {
ENTRY;
}
@@ -2,6 +2,9 @@
// IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND: JS_IR_ES6
// KT-61141: mustCheckInImports throws kotlin.IllegalStateException instead of java.lang.IllegalStateException
// IGNORE_BACKEND: NATIVE
abstract class Visibility(val name: String, val isPublicAPI: Boolean) {
open val internalDisplayName: String
get() = name
@@ -1,5 +1,5 @@
// SKIP_KLIB_TEST
// IGNORE_BACKEND: JS_IR
// TARGET_BACKEND: JVM
// WITH_STDLIB
// LANGUAGE: +ValueClasses
+3
View File
@@ -3,6 +3,9 @@
// IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND: JS_IR_ES6
// KT-61141: In testLrmFoo1 and testLrmFoo2, `print (message: kotlin.Any?)` instead of `print (message: kotlin.Int)`
// IGNORE_BACKEND: NATIVE
fun test0() {
run {
return
+3
View File
@@ -4,6 +4,9 @@
// MUTE_SIGNATURE_COMPARISON_K2: ANY
// ^ KT-57775, KT-57430
// KT-61141: absent enum fake_overrides: finalize, getDeclaringClass, clone
// IGNORE_BACKEND: NATIVE
enum class Z {
ENTRY {
fun test() {}
@@ -2,6 +2,8 @@
// IGNORE_BACKEND_K1: JS_IR
// IGNORE_BACKEND_K1: JS_IR_ES6
// KT-61141: difference in IR for implicit cast
// IGNORE_BACKEND_K1: NATIVE
interface X
interface Z
+3
View File
@@ -3,6 +3,9 @@
// IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND: JS_IR_ES6
// KT-61141: For result of `+`, Native backend inferred type Comparable instead of Nothing
// IGNORE_BACKEND: NATIVE
fun test(): Boolean {
val ref = (listOf('a') + "-")::contains
return ref('a')
@@ -1,6 +1,9 @@
// KT-42036
// IGNORE_BACKEND: JS_IR
// KT-61141: getTag() throws kotlin.Exception instead of java.lang.Exception
// IGNORE_BACKEND: NATIVE
typealias Action<RenderingT> = (@UnsafeVariance RenderingT) -> Unit
data class Tag<out RenderingT>(val action: Action<RenderingT>)
@@ -142,4 +142,18 @@ sealed class IrBackendInput : ResultingArtifact.BackendInput<IrBackendInput>() {
override val diagnosticReporter: BaseDiagnosticsCollector
get() = state.diagnosticReporter as BaseDiagnosticsCollector
}
// Actually, class won't be used as a real input for the Native backend during blackbox testing, since such testing is done via a different engine.
// In irText tests, this class is used only as Native-specific FIR2IR output to render and dump IR.
// So, no source files, icData, error flag, serialization lambda, etc are needed.
class NativeBackendInput(
override val irModuleFragment: IrModuleFragment,
override val dependentIrModuleFragments: List<IrModuleFragment>,
override val irPluginContext: IrPluginContext,
override val diagnosticReporter: BaseDiagnosticsCollector,
override val descriptorMangler: KotlinMangler.DescriptorMangler,
override val irMangler: KotlinMangler.IrMangler,
override val firMangler: FirMangler?,
override var irActualizerResult: IrActualizedResult? = null,
) : IrBackendInput()
}
@@ -16,7 +16,7 @@ import org.jetbrains.kotlin.backend.common.CommonKLibResolver
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.jvm.JvmBuiltIns
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns
import org.jetbrains.kotlin.cli.js.klib.TopDownAnalyzerFacadeForJSIR
import org.jetbrains.kotlin.cli.js.klib.TopDownAnalyzerFacadeForWasm
import org.jetbrains.kotlin.cli.jvm.compiler.JvmPackagePartProvider
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.container.get
import org.jetbrains.kotlin.context.ModuleContext
import org.jetbrains.kotlin.context.ProjectContext
import org.jetbrains.kotlin.context.withModule
import org.jetbrains.kotlin.descriptors.ModuleCapability
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
import org.jetbrains.kotlin.descriptors.impl.CompositePackageFragmentProvider
@@ -42,34 +43,32 @@ import org.jetbrains.kotlin.incremental.components.EnumWhenTracker
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
import org.jetbrains.kotlin.incremental.components.InlineConstTracker
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.ir.backend.js.*
import org.jetbrains.kotlin.ir.backend.js.JsFactories
import org.jetbrains.kotlin.ir.backend.js.resolverLogger
import org.jetbrains.kotlin.js.analyze.TopDownAnalyzerFacadeForJS
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
import org.jetbrains.kotlin.js.config.WasmTarget
import org.jetbrains.kotlin.library.metadata.CurrentKlibModuleOrigin
import org.jetbrains.kotlin.library.metadata.KlibMetadataFactories
import org.jetbrains.kotlin.library.metadata.KlibModuleOrigin
import org.jetbrains.kotlin.library.metadata.NullFlexibleTypeDeserializer
import org.jetbrains.kotlin.library.unresolvedDependencies
import org.jetbrains.kotlin.load.java.lazy.SingleModuleClassResolver
import org.jetbrains.kotlin.load.kotlin.ModuleVisibilityManager
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.native.FakeTopDownAnalyzerFacadeForNative
import org.jetbrains.kotlin.platform.CommonPlatforms
import org.jetbrains.kotlin.platform.*
import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlin.platform.isCommon
import org.jetbrains.kotlin.platform.isJs
import org.jetbrains.kotlin.platform.isWasm
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.platform.jvm.isJvm
import org.jetbrains.kotlin.platform.konan.isNative
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.LazyTopDownAnalyzer
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
import org.jetbrains.kotlin.resolve.TargetEnvironment
import org.jetbrains.kotlin.resolve.TopDownAnalysisMode
import org.jetbrains.kotlin.resolve.*
import org.jetbrains.kotlin.resolve.jvm.JavaDescriptorResolver
import org.jetbrains.kotlin.resolve.lazy.KotlinCodeAnalyzer
import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory
import org.jetbrains.kotlin.storage.LockBasedStorageManager
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.test.directives.ConfigurationDirectives
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives
import org.jetbrains.kotlin.test.model.DependencyRelation
import org.jetbrains.kotlin.test.model.FrontendFacade
@@ -275,7 +274,11 @@ class ClassicFrontendFacade(
)
}
private fun loadKlib(names: List<String>, configuration: CompilerConfiguration): List<ModuleDescriptor> {
private fun loadKlib(
factories: KlibMetadataFactories,
names: List<String>,
configuration: CompilerConfiguration
): List<ModuleDescriptor> {
val resolvedLibraries = CommonKLibResolver.resolve(
names,
configuration.resolverLogger
@@ -289,7 +292,7 @@ class ClassicFrontendFacade(
val storageManager = LockBasedStorageManager("ModulesStructure")
val isBuiltIns = resolvedLibrary.library.unresolvedDependencies.isEmpty()
val moduleDescriptor = JsFactories.DefaultDeserializedDescriptorFactory.createDescriptorOptionalBuiltIns(
val moduleDescriptor = factories.DefaultDeserializedDescriptorFactory.createDescriptorOptionalBuiltIns(
resolvedLibrary.library,
configuration.languageVersionSettings,
storageManager,
@@ -317,7 +320,7 @@ class ClassicFrontendFacade(
friendsDescriptors: List<ModuleDescriptor>,
): AnalysisResult {
val runtimeKlibsNames = JsEnvironmentConfigurator.getRuntimePathsForModule(module, testServices)
val runtimeKlibs = loadKlib(runtimeKlibsNames, configuration)
val runtimeKlibs = loadKlib(JsFactories, runtimeKlibsNames, configuration)
val transitiveLibraries = getDependencies(module, testServices, DependencyRelation.RegularDependency)
val friendLibraries = getDependencies(module, testServices, DependencyRelation.FriendDependency)
val allDependencies = runtimeKlibs + dependencyDescriptors + friendLibraries + friendsDescriptors + transitiveLibraries
@@ -359,7 +362,7 @@ class ClassicFrontendFacade(
File(it).absolutePath
}
val runtimeKlibs = loadKlib(runtimeKlibsNames, configuration)
val runtimeKlibs = loadKlib(JsFactories, runtimeKlibsNames, configuration)
val transitiveLibraries = getDependencies(module, testServices, DependencyRelation.RegularDependency)
val friendLibraries = getDependencies(module, testServices, DependencyRelation.FriendDependency)
val allDependencies = runtimeKlibs + dependencyDescriptors + friendLibraries + friendsDescriptors + transitiveLibraries
@@ -391,15 +394,23 @@ class ClassicFrontendFacade(
): AnalysisResult {
val moduleTrace = NoScopeRecordCliBindingTrace()
val runtimeKlibsNames = NativeEnvironmentConfigurator.getRuntimePathsForModule(module, testServices)
val runtimeKlibs = loadKlib(runtimeKlibsNames, configuration).mapNotNull { it as? ModuleDescriptorImpl }
val nativeFactories = KlibMetadataFactories(::KonanBuiltIns, NullFlexibleTypeDeserializer)
val runtimeKlibs = loadKlib(nativeFactories, runtimeKlibsNames, configuration).mapNotNull { it as? ModuleDescriptorImpl }
val stdlibBuiltInsModule = runtimeKlibs.single { it.name == Name.special("<stdlib>") }.builtIns.builtInsModule
val moduleContext = createModuleContext(
module, project,
dependencyDescriptors = dependencyDescriptors + runtimeKlibs,
friendsDescriptors = friendsDescriptors,
dependsOnDescriptors = dependsOnDescriptors
dependsOnDescriptors = dependsOnDescriptors,
capabilities = mapOf(
// provides `klibModuleOrigin` capability needed in `ModuleDescriptor.isFromInteropLibrary()`
KlibModuleOrigin.CAPABILITY to CurrentKlibModuleOrigin,
),
) {
DefaultBuiltIns()
KonanBuiltIns(it).apply {
builtInsModule = stdlibBuiltInsModule
}
}
return FakeTopDownAnalyzerFacadeForNative.analyzeFilesWithGivenTrace(
files,
@@ -472,18 +483,21 @@ class ClassicFrontendFacade(
dependencyDescriptors: List<ModuleDescriptorImpl>,
friendsDescriptors: List<ModuleDescriptorImpl>,
dependsOnDescriptors: List<ModuleDescriptorImpl>,
capabilities: Map<ModuleCapability<*>, Any?> = emptyMap(),
builtInsFactory: (StorageManager) -> KotlinBuiltIns,
): ModuleContext {
val projectContext = ProjectContext(project, "test project context")
val storageManager = projectContext.storageManager
val builtIns = builtInsFactory(storageManager)
val moduleDescriptor = ModuleDescriptorImpl(Name.special("<${module.name}>"), storageManager, builtIns, module.targetPlatform)
val dependencies = buildList {
val moduleDescriptor = ModuleDescriptorImpl(
Name.special("<${module.name}>"), storageManager, builtIns, module.targetPlatform, capabilities
)
val dependencies = buildSet {
add(moduleDescriptor)
add(moduleDescriptor.builtIns.builtInsModule)
addAll(dependencyDescriptors)
}
}.toList()
moduleDescriptor.setDependencies(
ModuleDependenciesImpl(
allDependencies = dependencies,
@@ -77,11 +77,6 @@ public class KlibIrTextTestCaseGenerated extends AbstractKlibIrTextTestCase {
runTest("compiler/testData/ir/irText/classes/classes.kt");
}
@TestMetadata("cloneable.kt")
public void testCloneable() throws Exception {
runTest("compiler/testData/ir/irText/classes/cloneable.kt");
}
@TestMetadata("companionObject.kt")
public void testCompanionObject() throws Exception {
runTest("compiler/testData/ir/irText/classes/companionObject.kt");
@@ -2163,11 +2158,6 @@ public class KlibIrTextTestCaseGenerated extends AbstractKlibIrTextTestCase {
runTest("compiler/testData/ir/irText/firProblems/typeVariableAfterBuildMap.kt");
}
@TestMetadata("valueClassEquals.kt")
public void testValueClassEquals() throws Exception {
runTest("compiler/testData/ir/irText/firProblems/valueClassEquals.kt");
}
@TestMetadata("VarInInit.kt")
public void testVarInInit() throws Exception {
runTest("compiler/testData/ir/irText/firProblems/VarInInit.kt");
@@ -76,12 +76,6 @@ public class FirLightTreeJsIrTextTestGenerated extends AbstractFirLightTreeJsIrT
runTest("compiler/testData/ir/irText/classes/classes.kt");
}
@Test
@TestMetadata("cloneable.kt")
public void testCloneable() throws Exception {
runTest("compiler/testData/ir/irText/classes/cloneable.kt");
}
@Test
@TestMetadata("companionObject.kt")
public void testCompanionObject() throws Exception {
@@ -2484,12 +2478,6 @@ public class FirLightTreeJsIrTextTestGenerated extends AbstractFirLightTreeJsIrT
runTest("compiler/testData/ir/irText/firProblems/typeVariableAfterBuildMap.kt");
}
@Test
@TestMetadata("valueClassEquals.kt")
public void testValueClassEquals() throws Exception {
runTest("compiler/testData/ir/irText/firProblems/valueClassEquals.kt");
}
@Test
@TestMetadata("VarInInit.kt")
public void testVarInInit() throws Exception {
@@ -76,12 +76,6 @@ public class FirPsiJsIrTextTestGenerated extends AbstractFirPsiJsIrTextTest {
runTest("compiler/testData/ir/irText/classes/classes.kt");
}
@Test
@TestMetadata("cloneable.kt")
public void testCloneable() throws Exception {
runTest("compiler/testData/ir/irText/classes/cloneable.kt");
}
@Test
@TestMetadata("companionObject.kt")
public void testCompanionObject() throws Exception {
@@ -2484,12 +2478,6 @@ public class FirPsiJsIrTextTestGenerated extends AbstractFirPsiJsIrTextTest {
runTest("compiler/testData/ir/irText/firProblems/typeVariableAfterBuildMap.kt");
}
@Test
@TestMetadata("valueClassEquals.kt")
public void testValueClassEquals() throws Exception {
runTest("compiler/testData/ir/irText/firProblems/valueClassEquals.kt");
}
@Test
@TestMetadata("VarInInit.kt")
public void testVarInInit() throws Exception {
@@ -76,12 +76,6 @@ public class ClassicJsIrTextTestGenerated extends AbstractClassicJsIrTextTest {
runTest("compiler/testData/ir/irText/classes/classes.kt");
}
@Test
@TestMetadata("cloneable.kt")
public void testCloneable() throws Exception {
runTest("compiler/testData/ir/irText/classes/cloneable.kt");
}
@Test
@TestMetadata("companionObject.kt")
public void testCompanionObject() throws Exception {
@@ -2484,12 +2478,6 @@ public class ClassicJsIrTextTestGenerated extends AbstractClassicJsIrTextTest {
runTest("compiler/testData/ir/irText/firProblems/typeVariableAfterBuildMap.kt");
}
@Test
@TestMetadata("valueClassEquals.kt")
public void testValueClassEquals() throws Exception {
runTest("compiler/testData/ir/irText/firProblems/valueClassEquals.kt");
}
@Test
@TestMetadata("VarInInit.kt")
public void testVarInInit() throws Exception {
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.konan.blackboxtest.support.group.UsePartialLinkage
import org.jetbrains.kotlin.konan.diagnostics.AbstractDiagnosticsNativeTest
import org.jetbrains.kotlin.konan.diagnostics.AbstractFirLightTreeNativeDiagnosticsTest
import org.jetbrains.kotlin.konan.diagnostics.AbstractFirPsiNativeDiagnosticsTest
import org.jetbrains.kotlin.konan.irtext.AbstractClassicNativeIrTextTest
import org.jetbrains.kotlin.test.TargetBackend
import org.jetbrains.kotlin.test.utils.CUSTOM_TEST_DATA_EXTENSION_PATTERN
import org.junit.jupiter.api.Tag
@@ -76,6 +77,9 @@ fun main() {
model("codegen/box", targetBackend = TargetBackend.NATIVE)
model("codegen/boxInline", targetBackend = TargetBackend.NATIVE)
}
testClass<AbstractClassicNativeIrTextTest> {
model("ir/irText")
}
}
// Samples (how to utilize the abilities of new test infrastructure).
@@ -0,0 +1,155 @@
/*
* 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
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContextImpl
import org.jetbrains.kotlin.backend.common.linkage.issues.checkNoUnboundSymbols
import org.jetbrains.kotlin.backend.common.serialization.DescriptorByIdSignatureFinderImpl
import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
import org.jetbrains.kotlin.ir.linkage.IrDeserializer
import org.jetbrains.kotlin.ir.linkage.partial.partialLinkageConfig
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.konan.blackboxtest.support.CastCompatibleKotlinNativeClassLoader
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi2ir.Psi2IrConfiguration
import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator
import org.jetbrains.kotlin.psi2ir.generators.DeclarationStubGeneratorImpl
import org.jetbrains.kotlin.test.TargetBackend
import org.jetbrains.kotlin.test.backend.ir.IrBackendInput
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendOutputArtifact
import org.jetbrains.kotlin.test.model.BackendKinds
import org.jetbrains.kotlin.test.model.Frontend2BackendConverter
import org.jetbrains.kotlin.test.model.FrontendKinds
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.*
import kotlin.reflect.KClass
class ClassicFrontend2NativeIrConverter(
testServices: TestServices,
) : Frontend2BackendConverter<ClassicFrontendOutputArtifact, IrBackendInput>(
testServices,
FrontendKinds.ClassicFrontend,
BackendKinds.IrBackend
) {
override val additionalServices: List<ServiceRegistrationData>
get() = listOf(service(::LibraryProvider))
override fun transform(module: TestModule, inputArtifact: ClassicFrontendOutputArtifact): IrBackendInput {
return when (module.targetBackend) {
TargetBackend.NATIVE -> transformToNativeIr(module, inputArtifact)
else -> testServices.assertions.fail { "Target backend ${module.targetBackend} is not supported for transformation into IR" }
}
}
/**
* Mostly mimics [org.jetbrains.kotlin.backend.konan.psiToIr], since direct call is impossible due to:
* - prohibited import of module `:kotlin-native:backend.native` here to `:native:native.tests`
* - invocation via reflection is complicated due to moving [com.intellij.openapi.project.Project] to another subpackage during compiler
* JAR embedding.
*
* It's unlikely that [org.jetbrains.kotlin.backend.konan.psiToIr] would be ever significantly changed before reaching its end-of-life,
* so it's plausible to have a reduced copy here in the test pipeline.
*/
private fun transformToNativeIr(module: TestModule, inputArtifact: ClassicFrontendOutputArtifact): IrBackendInput {
val (psiFiles, analysisResult, project, _) = inputArtifact
val configuration = testServices.compilerConfigurationProvider.getCompilerConfiguration(module)
val sourceFiles: List<KtFile> = psiFiles.values.toList()
val translator = Psi2IrTranslator(
configuration.languageVersionSettings,
Psi2IrConfiguration(ignoreErrors = false, configuration.partialLinkageConfig.isEnabled),
configuration.irMessageLogger::checkNoUnboundSymbols
)
val konanManglerDescClass = kotlinNativeClass("org.jetbrains.kotlin.backend.konan.serialization.KonanManglerDesc")
val manglerDesc = konanManglerDescClass.objectInstance as KotlinMangler.DescriptorMangler
val konanIdSignaturerClass = kotlinNativeClass("org.jetbrains.kotlin.backend.konan.serialization.KonanIdSignaturer")
val konanIdSignaturerConstructor = konanIdSignaturerClass.constructors.single()
val konanIdSignaturerClassInstance = konanIdSignaturerConstructor.call(manglerDesc) as IdSignatureComposer
val symbolTable = SymbolTable(konanIdSignaturerClassInstance, IrFactoryImpl)
val generatorContext = translator.createGeneratorContext(
analysisResult.moduleDescriptor,
analysisResult.bindingContext,
symbolTable
)
val konanStubGeneratorExtensionsClass = kotlinNativeClass("org.jetbrains.kotlin.backend.konan.KonanStubGeneratorExtensions")
val stubGenerator = DeclarationStubGeneratorImpl(
analysisResult.moduleDescriptor, symbolTable,
generatorContext.irBuiltIns,
DescriptorByIdSignatureFinderImpl(analysisResult.moduleDescriptor, manglerDesc),
konanStubGeneratorExtensionsClass.objectInstance as StubGeneratorExtensions
).apply {
unboundSymbolGeneration = true
}
val irDeserializer = object : IrDeserializer {
override fun getDeclaration(symbol: IrSymbol) = stubGenerator.getDeclaration(symbol)
override fun resolveBySignatureInModule(
signature: IdSignature,
kind: IrDeserializer.TopLevelSymbolKind,
moduleName: Name
): IrSymbol {
error("Should not be called")
}
override fun postProcess(inOrAfterLinkageStep: Boolean) = Unit
}
val pluginExtensions = IrGenerationExtension.getInstances(project)
val moduleFragment = translator.generateModuleFragment(
generatorContext,
sourceFiles,
irProviders = listOf(irDeserializer),
linkerExtensions = pluginExtensions,
).toKonanModule()
val pluginContext = IrPluginContextImpl(
generatorContext.moduleDescriptor,
generatorContext.bindingContext,
generatorContext.languageVersionSettings,
generatorContext.symbolTable,
generatorContext.typeTranslator,
generatorContext.irBuiltIns,
linker = irDeserializer,
diagnosticReporter = configuration.irMessageLogger
)
val konanManglerIrClassKotlin = kotlinNativeClass("org.jetbrains.kotlin.backend.konan.serialization.KonanManglerIr")
val konanIrMangler = konanManglerIrClassKotlin.objectInstance as KotlinMangler.IrMangler
return IrBackendInput.NativeBackendInput(
moduleFragment,
dependentIrModuleFragments = emptyList(),
pluginContext,
diagnosticReporter = DiagnosticReporterFactory.createReporter(),
descriptorMangler = (pluginContext.symbolTable as SymbolTable).signaturer.mangler,
irMangler = konanIrMangler,
firMangler = null,
)
}
private fun IrModuleFragment.toKonanModule(): IrModuleFragment {
val konanIrModuleFragmentImplClass = kotlinNativeClass("org.jetbrains.kotlin.backend.konan.serialization.KonanIrModuleFragmentImpl")
return konanIrModuleFragmentImplClass.constructors.single().call(descriptor, irBuiltins, files) as IrModuleFragment
}
private fun kotlinNativeClass(name: String): KClass<out Any> {
// KT-61248: TODO Replace reflection for direct import, when classes would be extracted out of `backend.native` module
return Class.forName(
name,
true,
CastCompatibleKotlinNativeClassLoader.kotlinNativeClassLoader.classLoader
).kotlin
}
}
@@ -70,6 +70,10 @@ class NativeSimpleTestSupport : BeforeEachCallback {
}
}
internal object CastCompatibleKotlinNativeClassLoader {
val kotlinNativeClassLoader = NativeTestSupport.computeNativeClassLoader(this::class.java.classLoader)
}
private object NativeTestSupport {
private val NAMESPACE = ExtensionContext.Namespace.create(NativeTestSupport::class.java.simpleName)
@@ -93,14 +97,24 @@ private object NativeTestSupport {
private fun computeNativeHome(): KotlinNativeHome = KotlinNativeHome(File(ProcessLevelProperty.KOTLIN_NATIVE_HOME.readValue()))
private fun computeNativeClassLoader(): KotlinNativeClassLoader = KotlinNativeClassLoader(
/**
* - For Codegen native tests, no parent classloader should be provided,
* since compiler `class K2Native: CLICompiler` is invoked via reflection with kotlinNativeClassLoader,
* so both classes K2Native and CLICompiler need to be loaded with same nativeclassloader.
* This way, `K2Native.doExecute()` method would define abstract method `CLICompiler.doExecute()`.
* With parent classloader, these two classes would be loaded by different classloaders and AbstractMethodError is thrown
* - For irText tests, classloaded mangler instance is passed to generate mangles to IR dumps files.
* For this, a cast of mangler object(within K/N classloader) to mangler interface(within app classloader) is needed,
* which is possible when app classloader is provided as parent.
*/
fun computeNativeClassLoader(parent: ClassLoader? = null): KotlinNativeClassLoader = KotlinNativeClassLoader(
lazy {
val nativeClassPath = ProcessLevelProperty.COMPILER_CLASSPATH.readValue()
.split(':', ';')
.map { File(it).toURI().toURL() }
.toTypedArray()
URLClassLoader(nativeClassPath, /* no parent class loader */ null).apply { setDefaultAssertionStatus(true) }
URLClassLoader(nativeClassPath, parent).apply { setDefaultAssertionStatus(true) }
}
)
@@ -0,0 +1,27 @@
/*
* 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.irtext
import org.jetbrains.kotlin.konan.ClassicFrontend2NativeIrConverter
import org.jetbrains.kotlin.test.Constructor
import org.jetbrains.kotlin.test.backend.ir.IrBackendInput
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendFacade
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendOutputArtifact
import org.jetbrains.kotlin.test.model.Frontend2BackendConverter
import org.jetbrains.kotlin.test.model.FrontendFacade
import org.jetbrains.kotlin.test.model.FrontendKind
import org.jetbrains.kotlin.test.model.FrontendKinds
open class AbstractClassicNativeIrTextTest: AbstractNativeIrTextTestBase<ClassicFrontendOutputArtifact>() {
override val frontend: FrontendKind<*>
get() = FrontendKinds.ClassicFrontend
override val frontendFacade: Constructor<FrontendFacade<ClassicFrontendOutputArtifact>>
get() = ::ClassicFrontendFacade
override val converter: Constructor<Frontend2BackendConverter<ClassicFrontendOutputArtifact, IrBackendInput>>
get() = ::ClassicFrontend2NativeIrConverter
}
@@ -0,0 +1,40 @@
/*
* 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.irtext
import org.jetbrains.kotlin.platform.konan.NativePlatforms
import org.jetbrains.kotlin.test.TargetBackend
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.directives.ConfigurationDirectives
import org.jetbrains.kotlin.test.model.ResultingArtifact
import org.jetbrains.kotlin.test.runners.ir.AbstractIrTextTest
import org.jetbrains.kotlin.test.services.LibraryProvider
import org.jetbrains.kotlin.test.services.configuration.CommonEnvironmentConfigurator
import org.jetbrains.kotlin.test.services.configuration.NativeEnvironmentConfigurator
abstract class AbstractNativeIrTextTestBase<FrontendOutput : ResultingArtifact.FrontendOutput<FrontendOutput>> :
AbstractIrTextTest<FrontendOutput>(NativePlatforms.unspecifiedNativePlatform, TargetBackend.NATIVE) {
final override fun TestConfigurationBuilder.applyConfigurators() {
useConfigurators(
::CommonEnvironmentConfigurator,
::NativeEnvironmentConfigurator,
)
useAdditionalService(::LibraryProvider)
}
override fun configure(builder: TestConfigurationBuilder) {
super.configure(builder)
with(builder) {
defaultDirectives {
// Kotlin/Native does not have "minimal" stdlib(like other backends do), so full stdlib is needed to resolve
// `Any`, `String`, `println`, etc.
+ConfigurationDirectives.WITH_STDLIB
}
}
}
}