Support instantiation of annotations in JS

#KT-47700 Fixed
This commit is contained in:
Leonid Startsev
2021-07-30 13:35:12 +03:00
committed by Space
parent a342c81a9f
commit 1932546a90
30 changed files with 406 additions and 51 deletions
@@ -170,7 +170,7 @@ open class BuiltinSymbolsBase(val irBuiltIns: IrBuiltIns, private val symbolTabl
private val binaryOperatorCache = mutableMapOf<Triple<Name, IrType, IrType>, IrSimpleFunctionSymbol>()
fun getBinaryOperator(name: Name, lhsType: IrType, rhsType: IrType): IrSimpleFunctionSymbol =
fun getBinaryOperator(name: Name, lhsType: IrType, rhsType: IrType): IrSimpleFunctionSymbol =
irBuiltIns.getBinaryOperator(name, lhsType, rhsType)
fun getUnaryOperator(name: Name, receiverType: IrType): IrSimpleFunctionSymbol = irBuiltIns.getUnaryOperator(name, receiverType)
@@ -232,6 +232,8 @@ abstract class Symbols<out T : CommonBackendContext>(
open val setWithoutBoundCheckName: Name? = null
open val arraysContentEquals: Map<IrType, IrSimpleFunctionSymbol>? = null
companion object {
fun isLateinitIsInitializedPropertyGetter(symbol: IrFunctionSymbol): Boolean =
symbol is IrSimpleFunctionSymbol && symbol.owner.let { function ->
@@ -13,19 +13,19 @@ import org.jetbrains.kotlin.backend.common.ir.copyTo
import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.builders.declarations.*
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrGetValue
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrDelegatingConstructorCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrSetFieldImpl
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.classOrNull
import org.jetbrains.kotlin.ir.types.isArray
import org.jetbrains.kotlin.ir.types.isKClass
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
@@ -46,7 +46,7 @@ class AnnotationImplementationLowering(
}
}
open class AnnotationImplementationTransformer(val context: BackendContext, val irFile: IrFile) : IrElementTransformerVoidWithContext() {
open class AnnotationImplementationTransformer(val context: BackendContext, val irFile: IrFile?) : IrElementTransformerVoidWithContext() {
internal val implementations: MutableMap<IrClass, IrClass> = mutableMapOf()
override fun visitConstructorCall(expression: IrConstructorCall): IrExpression {
@@ -79,7 +79,7 @@ open class AnnotationImplementationTransformer(val context: BackendContext, val
// since declaration is synthetic anyway
visibility = DescriptorVisibilities.INTERNAL
}.apply {
parent = localDeclarationParent ?: irFile
parent = localDeclarationParent ?: irFile ?: error("irFile in transformer should be specified when creating synthetic implementation")
createImplicitParameterDeclarationWithWrappedDescriptor()
superTypes = listOf(annotationClass.defaultType)
}
@@ -138,6 +138,7 @@ open class AnnotationImplementationTransformer(val context: BackendContext, val
isVar = false
origin = ANNOTATION_IMPLEMENTATION
}.apply {
field.correspondingPropertySymbol = this.symbol
backingField = field
parent = implClass
}
@@ -149,6 +150,7 @@ open class AnnotationImplementationTransformer(val context: BackendContext, val
visibility = DescriptorVisibilities.PUBLIC
modality = Modality.FINAL
}.apply {
correspondingPropertySymbol = prop.symbol
dispatchReceiverParameter = implClass.thisReceiver!!.copyTo(this)
body = context.createIrBuilder(symbol).irBlockBody {
var value: IrExpression = irGetField(irGet(dispatchReceiverParameter!!), field)
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.classOrNull
import org.jetbrains.kotlin.ir.types.getClass
import org.jetbrains.kotlin.ir.types.isArray
import org.jetbrains.kotlin.ir.util.DataClassMembersGenerator
@@ -69,7 +70,8 @@ class MethodsFromAnyGeneratorForLowerings(val context: BackendContext, val irCla
val symbol = if (type.isArray() || type.isPrimitiveArray()) {
context.irBuiltIns.dataClassArrayMemberHashCodeSymbol
} else {
context.irBuiltIns.anyClass.functions.single { it.owner.name.asString() == "hashCode" }
type.classOrNull?.functions?.singleOrNull { it.owner.isHashCode() } ?:
context.irBuiltIns.anyClass.functions.single { it.owner.name.asString() == "hashCode" }
}
return object : HashCodeFunctionInfo {
override val symbol: IrSimpleFunctionSymbol = symbol
@@ -44,6 +44,7 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.isNullable
class JsIrBackendContext(
val module: ModuleDescriptor,
@@ -230,6 +231,16 @@ class JsIrBackendContext(
).filterNot { it.isExpect }.single().getter!!
)
private val _arraysContentEquals = getFunctions(FqName("kotlin.collections.contentEquals")).mapNotNull {
if (it.extensionReceiverParameter != null && it.extensionReceiverParameter!!.type.isNullable())
symbolTable.referenceSimpleFunction(it)
else null
}
// Can't use .owner until ExternalStubGenerator is invoked, hence get() = here.
override val arraysContentEquals: Map<IrType, IrSimpleFunctionSymbol>
get() = _arraysContentEquals.associateBy { it.owner.extensionReceiverParameter!!.type.makeNotNull() }
override val getContinuation = symbolTable.referenceSimpleFunction(getJsInternalFunction("getContinuation"))
override val coroutineContextGetter = symbolTable.referenceSimpleFunction(context.coroutineContextProperty.getter!!)
@@ -152,6 +152,12 @@ val createScriptFunctionsPhase = makeJsModulePhase(
description = "Create functions for initialize and evaluate script"
).toModuleLowering()
private val annotationInstantiationLowering = makeDeclarationTransformerPhase(
::JsAnnotationImplementationTransformer,
name = "AnnotationImplementation",
description = "Create synthetic annotations implementations and use them in annotations constructor calls"
)
private val expectDeclarationsRemovingPhase = makeDeclarationTransformerPhase(
::ExpectDeclarationsRemoveLowering,
name = "ExpectDeclarationsRemoving",
@@ -746,6 +752,7 @@ private val jsSuspendArityStorePhase = makeDeclarationTransformerPhase(
private val loweringList = listOf<Lowering>(
scriptRemoveReceiverLowering,
validateIrBeforeLowering,
annotationInstantiationLowering,
expectDeclarationsRemovingPhase,
stripTypeAliasDeclarationsPhase,
jsCodeOutliningPhase,
@@ -0,0 +1,69 @@
/*
* Copyright 2010-2021 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.ir.backend.js.lower
import org.jetbrains.kotlin.backend.common.DeclarationTransformer
import org.jetbrains.kotlin.backend.common.lower.AnnotationImplementationTransformer
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
import org.jetbrains.kotlin.ir.builders.IrBlockBodyBuilder
import org.jetbrains.kotlin.ir.builders.irCall
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.isArray
import org.jetbrains.kotlin.ir.util.isAnnotationClass
import org.jetbrains.kotlin.ir.util.isPrimitiveArray
import org.jetbrains.kotlin.ir.util.render
// JS PIR (and IC) requires DeclarationTransformer instead of FileLoweringPass
class JsAnnotationImplementationTransformer(val jsContext: JsIrBackendContext) :
AnnotationImplementationTransformer(jsContext, null),
DeclarationTransformer {
override fun transformFlat(declaration: IrDeclaration): List<IrDeclaration>? =
if (declaration is IrClass && declaration.isAnnotationClass) listOf(visitClassNew(declaration))
else null
override fun visitConstructorCall(expression: IrConstructorCall): IrExpression {
// No-op
return expression
}
override fun visitClassNew(declaration: IrClass): IrClass {
if (!declaration.isAnnotationClass) return declaration
val properties = declaration.getAnnotationProperties()
context.irFactory.stageController.unrestrictDeclarationListsAccess {
implementEqualsAndHashCode(declaration, declaration, properties, properties)
}
return declaration
}
private val arraysContentEquals: Map<IrType, IrSimpleFunctionSymbol> =
requireNotNull(jsContext.ir.symbols.arraysContentEquals) { "contentEquals symbols should be defined in JS IR context" }
override fun generatedEquals(irBuilder: IrBlockBodyBuilder, type: IrType, arg1: IrExpression, arg2: IrExpression): IrExpression {
return if (type.isArray() || type.isPrimitiveArray()) {
val requiredSymbol =
if (type.isPrimitiveArray())
arraysContentEquals[type]
else
arraysContentEquals.entries.singleOrNull { (k, _) -> k.isArray() }?.value
if (requiredSymbol == null) {
error("Can't find an Arrays.contentEquals method for array type ${type.render()}")
}
irBuilder.irCall(
requiredSymbol
).apply {
extensionReceiver = arg1
putValueArgument(0, arg2)
}
} else super.generatedEquals(irBuilder, type, arg1, arg2)
}
}
@@ -1,5 +1,8 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM_IR
// IGNORE_BACKEND: JVM
// IGNORE_BACKEND: NATIVE
// IGNORE_BACKEND: WASM
// DONT_TARGET_EXACT_BACKEND: JS
// WITH_RUNTIME
// !LANGUAGE: +InstantiationOfAnnotationClasses
@@ -22,7 +25,7 @@ data class BarLike(val i:Int, val s: String, val f: Float)
fun box(): String {
val foo1 = Foo(42, "foo", arrayOf("a", "b"), intArrayOf(1,2), Bar::class, Bar(10, "bar", Float.NaN))
val foo2 = Foo(42, "foo", arrayOf("a", "b"), intArrayOf(1,2), Bar::class, Bar(10, "bar", Float.NaN))
if (foo1 != foo2) return "Failed equals"
if (foo1 != foo2) return "Failed equals ${foo1.toString()} ${foo2.toString()}"
val barlike = BarLike(10, "bar", Float.NaN)
if (barlike.hashCode() != foo1.bar.hashCode()) return "Failed HC1"
if (barlike.hashCode() != foo2.bar.hashCode()) return "Failed HC2"
@@ -1,5 +1,10 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM_IR
// IGNORE_BACKEND: JVM
// IGNORE_BACKEND: NATIVE
// IGNORE_BACKEND: WASM
// (supported: JVM_IR, JS_IR(_E6))
// Regular JS works too, but without proper hashCode or equals
// WITH_RUNTIME
// !LANGUAGE: +InstantiationOfAnnotationClasses
@@ -7,6 +12,7 @@
// note: taken from ../parameters.kt and ../parametersWithPrimitiveValues.kt
import kotlin.reflect.KClass
import kotlin.test.assertEquals
import kotlin.test.assertTrue as assert
enum class E { E0 }
annotation class Empty
@@ -1,5 +1,8 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM_IR
// IGNORE_BACKEND: JVM
// IGNORE_BACKEND: NATIVE
// IGNORE_BACKEND: WASM
// DONT_TARGET_EXACT_BACKEND: JS
// WITH_RUNTIME
// !LANGUAGE: +InstantiationOfAnnotationClasses
@@ -7,6 +10,8 @@
package test
import kotlin.reflect.KClass
import kotlin.test.assertTrue as assert
import kotlin.test.assertEquals
enum class E { A, B }
@@ -31,8 +36,15 @@ annotation class Partial(
fun box(): String {
val c = C()
assert(c.toString() == "@test.C(i=42, b=@test.B(a=@test.A()), kClass=interface test.B (Kotlin reflection is not available), e=B, aS=[a, b], aI=[1, 2])")
assertEquals(42, c.i)
assertEquals(A(), c.b.a)
assertEquals(B::class, c.kClass)
assertEquals(E.B, c.e)
assert(arrayOf("a", "b").contentEquals(c.aS))
assert(intArrayOf(1, 2).contentEquals(c.aI))
val p = Partial(e = E.B, s = "bar")
assert(p.toString() == "@test.Partial(i=42, s=bar, e=B)")
assertEquals(42, p.i)
assertEquals("bar", p.s)
assertEquals(E.B, p.e)
return "OK"
}
@@ -1,5 +1,8 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM_IR
// IGNORE_BACKEND: JVM
// IGNORE_BACKEND: NATIVE
// IGNORE_BACKEND: WASM
// DONT_TARGET_EXACT_BACKEND: JS
// WITH_RUNTIME
// !LANGUAGE: +InstantiationOfAnnotationClasses
@@ -22,7 +25,6 @@ annotation class A(
val bool: Boolean
)
@Retention(AnnotationRetention.RUNTIME)
annotation class Anno(
val s: String,
val i: Int,
@@ -44,7 +46,8 @@ fun box(): String {
A::class, emptyArray(), intArrayOf(1, 2), arrayOf(E.E0), arrayOf(Empty())
)
val s = anno.toString()
val target = "@test.Anno(s=OK, i=42, f=2.718281828, u=43, e=E0, a=@test.A(b=1, s=1, i=1, f=1.0, d=1.0, l=1, c=c, bool=true), " +
val targetJVM = "@test.Anno(s=OK, i=42, f=2.718281828, u=43, e=E0, a=@test.A(b=1, s=1, i=1, f=1.0, d=1.0, l=1, c=c, bool=true), " +
"k=interface test.A (Kotlin reflection is not available), arr=[], intArr=[1, 2], arrOfE=[E0], arrOfA=[@test.Empty()])"
return if (s == target) "OK" else "FAILED, got string $s"
val targetJS = "@test.Anno(s=OK, i=42, f=2.718281828, u=43, e=E0, a=@test.A(b=1, s=1, i=1, f=1, d=1, l=1, c=c, bool=true), k=class A, arr=[...], intArr=[...], arrOfE=[...], arrOfA=[...])"
return if (s == targetJS || s == targetJVM) "OK" else "FAILED, got string $s"
}
@@ -1,5 +1,10 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM_IR
// IGNORE_BACKEND: JVM
// IGNORE_BACKEND: NATIVE
// IGNORE_BACKEND: WASM
// DONT_TARGET_EXACT_BACKEND: JS
// (supported: JVM_IR, JS_IR(_E6))
// WITH_RUNTIME
// !LANGUAGE: +InstantiationOfAnnotationClasses
@@ -1,5 +1,9 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM_IR
// IGNORE_BACKEND: JVM
// IGNORE_BACKEND: NATIVE
// IGNORE_BACKEND: WASM
// (supported: JVM_IR, JS_IR(_E6))
// WITH_RUNTIME
// !LANGUAGE: +InstantiationOfAnnotationClasses +MultiPlatformProjects
@@ -1,8 +1,14 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM_IR
// IGNORE_BACKEND_MULTI_MODULE: JVM_MULTI_MODULE_OLD_AGAINST_IR, JVM_MULTI_MODULE_IR_AGAINST_OLD
// IGNORE_BACKEND: JVM
// IGNORE_BACKEND: NATIVE
// IGNORE_BACKEND: WASM
// IGNORE_BACKEND_MULTI_MODULE: JVM, JVM_MULTI_MODULE_IR_AGAINST_OLD
// (supported: JVM_IR, JS_IR(_E6))
// WITH_RUNTIME
// !LANGUAGE: +InstantiationOfAnnotationClasses
// IGNORE_DEXING
// TODO: D8 fails with AssertionError and does not print reason, need further investigation
@@ -19,6 +25,7 @@ inline fun bar(f: () -> Int): A = A(f())
// FILE: 2.kt
import a.*
import kotlin.test.assertTrue as assert
class C {
fun one(): A {
@@ -35,7 +42,5 @@ fun box(): String {
assert(one.i == 1)
val two = two()
assert(two.i == 2)
// During cross-module inlining, anonymous classes are copied
// println(one.javaClass.getName().startsWith("a._1Kt"))
return "OK"
}
@@ -1,8 +1,14 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM_IR
// IGNORE_BACKEND_MULTI_MODULE: JVM_MULTI_MODULE_OLD_AGAINST_IR, JVM_MULTI_MODULE_IR_AGAINST_OLD
// IGNORE_BACKEND: JVM
// IGNORE_BACKEND: NATIVE
// IGNORE_BACKEND: WASM
// IGNORE_BACKEND_MULTI_MODULE: JVM, JVM_MULTI_MODULE_IR_AGAINST_OLD
// (supported: JVM_IR, JS_IR(_E6))
// WITH_RUNTIME
// !LANGUAGE: +InstantiationOfAnnotationClasses
// IGNORE_DEXING
// TODO: D8 fails with AssertionError and does not print reason, need further investigation
@@ -1,19 +0,0 @@
// !DIAGNOSTICS: -UNUSED_VARIABLE
// WITH_RUNTIME
// SKIP_TXT
// !LANGUAGE: +InstantiationOfAnnotationClasses
import kotlin.reflect.KClass
annotation class A
annotation class B(val int: Int)
annotation class C(val int: Int = 42)
annotation class G<T: Any>(val int: KClass<T>)
fun box() {
val a = <!ANNOTATION_CLASS_CONSTRUCTOR_CALL!>A()<!>
val b = <!ANNOTATION_CLASS_CONSTRUCTOR_CALL!>B(4)<!>
val c = <!ANNOTATION_CLASS_CONSTRUCTOR_CALL!>C()<!>
val foo = <!ANNOTATION_CLASS_CONSTRUCTOR_CALL!>G(Int::class)<!>
}
@@ -24,12 +24,6 @@ public class DiagnosticsTestWithJsStdLibGenerated extends AbstractDiagnosticsTes
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithJsStdLib"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@Test
@TestMetadata("annotationConstructorCallJs.kt")
public void testAnnotationConstructorCallJs() throws Exception {
runTest("compiler/testData/diagnostics/testsWithJsStdLib/annotationConstructorCallJs.kt");
}
@Test
@TestMetadata("funConstructorCallJS.kt")
public void testFunConstructorCallJS() throws Exception {
@@ -388,6 +388,42 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
public void testAllFilesPresentInInstances() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/annotations/instances"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
}
@Test
@TestMetadata("annotationEqHc.kt")
public void testAnnotationEqHc() throws Exception {
runTest("compiler/testData/codegen/box/annotations/instances/annotationEqHc.kt");
}
@Test
@TestMetadata("annotationInstances.kt")
public void testAnnotationInstances() throws Exception {
runTest("compiler/testData/codegen/box/annotations/instances/annotationInstances.kt");
}
@Test
@TestMetadata("annotationInstancesEmptyDefault.kt")
public void testAnnotationInstancesEmptyDefault() throws Exception {
runTest("compiler/testData/codegen/box/annotations/instances/annotationInstancesEmptyDefault.kt");
}
@Test
@TestMetadata("annotationToString.kt")
public void testAnnotationToString() throws Exception {
runTest("compiler/testData/codegen/box/annotations/instances/annotationToString.kt");
}
@Test
@TestMetadata("multifileEqHc.kt")
public void testMultifileEqHc() throws Exception {
runTest("compiler/testData/codegen/box/annotations/instances/multifileEqHc.kt");
}
@Test
@TestMetadata("multiplatformInstantiation.kt")
public void testMultiplatformInstantiation() throws Exception {
runTest("compiler/testData/codegen/box/annotations/instances/multiplatformInstantiation.kt");
}
}
@Nested
@@ -33,6 +33,18 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo
public void testAllFilesPresentInAnnotations() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxInline/annotations"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
}
@Test
@TestMetadata("annotationInstanceInlining.kt")
public void testAnnotationInstanceInlining() throws Exception {
runTest("compiler/testData/codegen/boxInline/annotations/annotationInstanceInlining.kt");
}
@Test
@TestMetadata("instanceInAnonymousClass.kt")
public void testInstanceInAnonymousClass() throws Exception {
runTest("compiler/testData/codegen/boxInline/annotations/instanceInAnonymousClass.kt");
}
}
@Nested
@@ -33,6 +33,18 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi
public void testAllFilesPresentInAnnotations() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxInline/annotations"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
}
@Test
@TestMetadata("annotationInstanceInlining.kt")
public void testAnnotationInstanceInlining() throws Exception {
runTest("compiler/testData/codegen/boxInline/annotations/annotationInstanceInlining.kt");
}
@Test
@TestMetadata("instanceInAnonymousClass.kt")
public void testInstanceInAnonymousClass() throws Exception {
runTest("compiler/testData/codegen/boxInline/annotations/instanceInAnonymousClass.kt");
}
}
@Nested
@@ -33,6 +33,18 @@ public class JvmOldAgainstIrBoxInlineTestGenerated extends AbstractJvmOldAgainst
public void testAllFilesPresentInAnnotations() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxInline/annotations"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_MULTI_MODULE_OLD_AGAINST_IR, true);
}
@Test
@TestMetadata("annotationInstanceInlining.kt")
public void testAnnotationInstanceInlining() throws Exception {
runTest("compiler/testData/codegen/boxInline/annotations/annotationInstanceInlining.kt");
}
@Test
@TestMetadata("instanceInAnonymousClass.kt")
public void testInstanceInAnonymousClass() throws Exception {
runTest("compiler/testData/codegen/boxInline/annotations/instanceInAnonymousClass.kt");
}
}
@Nested
@@ -339,6 +339,36 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Instances extends AbstractLightAnalysisModeTest {
@TestMetadata("annotationEqHc.kt")
public void ignoreAnnotationEqHc() throws Exception {
runTest("compiler/testData/codegen/box/annotations/instances/annotationEqHc.kt");
}
@TestMetadata("annotationInstances.kt")
public void ignoreAnnotationInstances() throws Exception {
runTest("compiler/testData/codegen/box/annotations/instances/annotationInstances.kt");
}
@TestMetadata("annotationInstancesEmptyDefault.kt")
public void ignoreAnnotationInstancesEmptyDefault() throws Exception {
runTest("compiler/testData/codegen/box/annotations/instances/annotationInstancesEmptyDefault.kt");
}
@TestMetadata("annotationToString.kt")
public void ignoreAnnotationToString() throws Exception {
runTest("compiler/testData/codegen/box/annotations/instances/annotationToString.kt");
}
@TestMetadata("multifileEqHc.kt")
public void ignoreMultifileEqHc() throws Exception {
runTest("compiler/testData/codegen/box/annotations/instances/multifileEqHc.kt");
}
@TestMetadata("multiplatformInstantiation.kt")
public void ignoreMultiplatformInstantiation() throws Exception {
runTest("compiler/testData/codegen/box/annotations/instances/multiplatformInstantiation.kt");
}
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
}
@@ -32,7 +32,6 @@ object JsPlatformConfigurator : PlatformConfiguratorBase(
JsModuleCallChecker,
JsDynamicCallChecker,
JsDefinedExternallyCallChecker,
InstantiationOfAnnotationClassesCallChecker
),
identifierChecker = JsIdentifierChecker
) {
@@ -91,6 +91,36 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
public void testAllFilesPresentInInstances() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/annotations/instances"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
}
@TestMetadata("annotationEqHc.kt")
public void testAnnotationEqHc() throws Exception {
runTest("compiler/testData/codegen/box/annotations/instances/annotationEqHc.kt");
}
@TestMetadata("annotationInstances.kt")
public void testAnnotationInstances() throws Exception {
runTest("compiler/testData/codegen/box/annotations/instances/annotationInstances.kt");
}
@TestMetadata("annotationInstancesEmptyDefault.kt")
public void testAnnotationInstancesEmptyDefault() throws Exception {
runTest("compiler/testData/codegen/box/annotations/instances/annotationInstancesEmptyDefault.kt");
}
@TestMetadata("annotationToString.kt")
public void testAnnotationToString() throws Exception {
runTest("compiler/testData/codegen/box/annotations/instances/annotationToString.kt");
}
@TestMetadata("multifileEqHc.kt")
public void testMultifileEqHc() throws Exception {
runTest("compiler/testData/codegen/box/annotations/instances/multifileEqHc.kt");
}
@TestMetadata("multiplatformInstantiation.kt")
public void testMultiplatformInstantiation() throws Exception {
runTest("compiler/testData/codegen/box/annotations/instances/multiplatformInstantiation.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/annotations/kClassMapping")
@@ -41,6 +41,16 @@ public class IrJsCodegenInlineES6TestGenerated extends AbstractIrJsCodegenInline
public void testAllFilesPresentInAnnotations() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxInline/annotations"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
}
@TestMetadata("annotationInstanceInlining.kt")
public void testAnnotationInstanceInlining() throws Exception {
runTest("compiler/testData/codegen/boxInline/annotations/annotationInstanceInlining.kt");
}
@TestMetadata("instanceInAnonymousClass.kt")
public void testInstanceInAnonymousClass() throws Exception {
runTest("compiler/testData/codegen/boxInline/annotations/instanceInAnonymousClass.kt");
}
}
@TestMetadata("compiler/testData/codegen/boxInline/anonymousObject")
@@ -91,6 +91,36 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
public void testAllFilesPresentInInstances() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/annotations/instances"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
}
@TestMetadata("annotationEqHc.kt")
public void testAnnotationEqHc() throws Exception {
runTest("compiler/testData/codegen/box/annotations/instances/annotationEqHc.kt");
}
@TestMetadata("annotationInstances.kt")
public void testAnnotationInstances() throws Exception {
runTest("compiler/testData/codegen/box/annotations/instances/annotationInstances.kt");
}
@TestMetadata("annotationInstancesEmptyDefault.kt")
public void testAnnotationInstancesEmptyDefault() throws Exception {
runTest("compiler/testData/codegen/box/annotations/instances/annotationInstancesEmptyDefault.kt");
}
@TestMetadata("annotationToString.kt")
public void testAnnotationToString() throws Exception {
runTest("compiler/testData/codegen/box/annotations/instances/annotationToString.kt");
}
@TestMetadata("multifileEqHc.kt")
public void testMultifileEqHc() throws Exception {
runTest("compiler/testData/codegen/box/annotations/instances/multifileEqHc.kt");
}
@TestMetadata("multiplatformInstantiation.kt")
public void testMultiplatformInstantiation() throws Exception {
runTest("compiler/testData/codegen/box/annotations/instances/multiplatformInstantiation.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/annotations/kClassMapping")
@@ -41,6 +41,16 @@ public class IrJsCodegenInlineTestGenerated extends AbstractIrJsCodegenInlineTes
public void testAllFilesPresentInAnnotations() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxInline/annotations"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
}
@TestMetadata("annotationInstanceInlining.kt")
public void testAnnotationInstanceInlining() throws Exception {
runTest("compiler/testData/codegen/boxInline/annotations/annotationInstanceInlining.kt");
}
@TestMetadata("instanceInAnonymousClass.kt")
public void testInstanceInAnonymousClass() throws Exception {
runTest("compiler/testData/codegen/boxInline/annotations/instanceInAnonymousClass.kt");
}
}
@TestMetadata("compiler/testData/codegen/boxInline/anonymousObject")
@@ -91,6 +91,16 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
public void testAllFilesPresentInInstances() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/annotations/instances"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true);
}
@TestMetadata("annotationInstances.kt")
public void testAnnotationInstances() throws Exception {
runTest("compiler/testData/codegen/box/annotations/instances/annotationInstances.kt");
}
@TestMetadata("multiplatformInstantiation.kt")
public void testMultiplatformInstantiation() throws Exception {
runTest("compiler/testData/codegen/box/annotations/instances/multiplatformInstantiation.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/annotations/kClassMapping")
@@ -41,6 +41,16 @@ public class JsCodegenInlineTestGenerated extends AbstractJsCodegenInlineTest {
public void testAllFilesPresentInAnnotations() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxInline/annotations"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true);
}
@TestMetadata("annotationInstanceInlining.kt")
public void testAnnotationInstanceInlining() throws Exception {
runTest("compiler/testData/codegen/boxInline/annotations/annotationInstanceInlining.kt");
}
@TestMetadata("instanceInAnonymousClass.kt")
public void testInstanceInAnonymousClass() throws Exception {
runTest("compiler/testData/codegen/boxInline/annotations/instanceInAnonymousClass.kt");
}
}
@TestMetadata("compiler/testData/codegen/boxInline/anonymousObject")
@@ -86,6 +86,36 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
public void testAllFilesPresentInInstances() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/annotations/instances"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true);
}
@TestMetadata("annotationEqHc.kt")
public void testAnnotationEqHc() throws Exception {
runTest("compiler/testData/codegen/box/annotations/instances/annotationEqHc.kt");
}
@TestMetadata("annotationInstances.kt")
public void testAnnotationInstances() throws Exception {
runTest("compiler/testData/codegen/box/annotations/instances/annotationInstances.kt");
}
@TestMetadata("annotationInstancesEmptyDefault.kt")
public void testAnnotationInstancesEmptyDefault() throws Exception {
runTest("compiler/testData/codegen/box/annotations/instances/annotationInstancesEmptyDefault.kt");
}
@TestMetadata("annotationToString.kt")
public void testAnnotationToString() throws Exception {
runTest("compiler/testData/codegen/box/annotations/instances/annotationToString.kt");
}
@TestMetadata("multifileEqHc.kt")
public void testMultifileEqHc() throws Exception {
runTest("compiler/testData/codegen/box/annotations/instances/multifileEqHc.kt");
}
@TestMetadata("multiplatformInstantiation.kt")
public void testMultiplatformInstantiation() throws Exception {
runTest("compiler/testData/codegen/box/annotations/instances/multiplatformInstantiation.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/annotations/kClassMapping")
@@ -0,0 +1,12 @@
/*
* Copyright 2010-2021 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 kotlin.collections
@SinceKotlin("1.4")
@library("arrayEquals")
public infix fun <T> Array<out T>?.contentEquals(other: Array<out T>?): Boolean {
definedExternally
}