Support instantiation of annotations in JS
#KT-47700 Fixed
This commit is contained in:
@@ -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 ->
|
||||
|
||||
+7
-5
@@ -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)
|
||||
|
||||
+3
-1
@@ -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,
|
||||
|
||||
+69
@@ -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
|
||||
|
||||
+15
-3
@@ -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
|
||||
|
||||
+5
-1
@@ -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
|
||||
|
||||
+9
-4
@@ -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"
|
||||
}
|
||||
+8
-2
@@ -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
@@ -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)<!>
|
||||
}
|
||||
-6
@@ -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 {
|
||||
|
||||
+36
@@ -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
|
||||
|
||||
+12
@@ -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
|
||||
|
||||
+12
@@ -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
|
||||
|
||||
+12
@@ -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
|
||||
|
||||
+30
@@ -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
|
||||
) {
|
||||
|
||||
js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java
Generated
+30
@@ -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")
|
||||
|
||||
+10
@@ -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")
|
||||
|
||||
Generated
+30
@@ -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")
|
||||
|
||||
Generated
+10
@@ -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")
|
||||
|
||||
Generated
+10
@@ -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")
|
||||
|
||||
Generated
+10
@@ -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")
|
||||
|
||||
js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java
Generated
+30
@@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user