Instantiation of annotations for JVM IR with the corresponding feature flag
Seperate checker for platforms that do not support this language feature yet Synthetic implementations of annotations are generated on-demand with proper equals, hashCode, and annotationType methods #KT-47699 Fixed
This commit is contained in:
+6
@@ -1103,6 +1103,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
||||
runTest("compiler/testData/diagnostics/tests/annotations/ConstructorCall.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("ConstructorCallAllowed.kt")
|
||||
public void testConstructorCallAllowed() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/annotations/ConstructorCallAllowed.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("DanglingMixed.kt")
|
||||
public void testDanglingMixed() throws Exception {
|
||||
|
||||
+6
@@ -1103,6 +1103,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
||||
runTest("compiler/testData/diagnostics/tests/annotations/ConstructorCall.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("ConstructorCallAllowed.kt")
|
||||
public void testConstructorCallAllowed() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/annotations/ConstructorCallAllowed.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("DanglingMixed.kt")
|
||||
public void testDanglingMixed() throws Exception {
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
+70
@@ -380,6 +380,76 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/box/annotations/instances")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class Instances {
|
||||
@Test
|
||||
public void testAllFilesPresentInInstances() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/annotations/instances"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("annotationEnclosingName.kt")
|
||||
public void testAnnotationEnclosingName() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/annotationEnclosingName.kt");
|
||||
}
|
||||
|
||||
@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("annotationType.kt")
|
||||
public void testAnnotationType() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/annotationType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("javaAnnotation.kt")
|
||||
public void testJavaAnnotation() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/javaAnnotation.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("multifileEqHc.kt")
|
||||
public void testMultifileEqHc() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/multifileEqHc.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("multimoduleInlining.kt")
|
||||
public void testMultimoduleInlining() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/multimoduleInlining.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("multiplatformInstantiation.kt")
|
||||
public void testMultiplatformInstantiation() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/multiplatformInstantiation.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/box/annotations/kClassMapping")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
|
||||
+22
@@ -25,6 +25,28 @@ public class FirBlackBoxInlineCodegenTestGenerated extends AbstractFirBlackBoxIn
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxInline"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/boxInline/annotations")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class Annotations {
|
||||
@Test
|
||||
public void testAllFilesPresentInAnnotations() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxInline/annotations"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_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
|
||||
@TestMetadata("compiler/testData/codegen/boxInline/anonymousObject")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* 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.resolve.calls
|
||||
@@ -238,7 +227,8 @@ class CallExpressionResolver(
|
||||
if (functionDescriptor is ConstructorDescriptor) {
|
||||
val constructedClass = functionDescriptor.constructedClass
|
||||
if (DescriptorUtils.isAnnotationClass(constructedClass) && !canInstantiateAnnotationClass(callExpression, context.trace)) {
|
||||
context.trace.report(ANNOTATION_CLASS_CONSTRUCTOR_CALL.on(callExpression))
|
||||
val supported = context.languageVersionSettings.supportsFeature(LanguageFeature.InstantiationOfAnnotationClasses) && constructedClass.declaredTypeParameters.isEmpty()
|
||||
if (!supported) context.trace.report(ANNOTATION_CLASS_CONSTRUCTOR_CALL.on(callExpression))
|
||||
}
|
||||
if (DescriptorUtils.isEnumClass(constructedClass)) {
|
||||
context.trace.report(ENUM_CLASS_CONSTRUCTOR_CALL.on(callExpression))
|
||||
@@ -515,7 +505,7 @@ class CallExpressionResolver(
|
||||
|
||||
companion object {
|
||||
|
||||
private fun canInstantiateAnnotationClass(expression: KtCallExpression, trace: BindingTrace): Boolean {
|
||||
fun canInstantiateAnnotationClass(expression: KtCallExpression, trace: BindingTrace): Boolean {
|
||||
//noinspection unchecked
|
||||
var parent: PsiElement? = PsiTreeUtil.getParentOfType(expression, KtValueArgument::class.java, KtParameter::class.java)
|
||||
if (parent is KtValueArgument) {
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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.resolve.calls.checkers
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.psi.KtCallExpression
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.calls.CallExpressionResolver
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
|
||||
/**
|
||||
* Additional checker that prohibits usage of LanguageFeature.InstantiationOfAnnotationClasses on backends
|
||||
* that do not support this feature yet
|
||||
*/
|
||||
object InstantiationOfAnnotationClassesCallChecker : CallChecker {
|
||||
override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) {
|
||||
if (!context.languageVersionSettings.supportsFeature(LanguageFeature.InstantiationOfAnnotationClasses)) return
|
||||
val calledDescriptor = resolvedCall.resultingDescriptor as? ConstructorDescriptor ?: return
|
||||
val constructedClass = calledDescriptor.constructedClass
|
||||
val expression = resolvedCall.call.callElement as? KtCallExpression ?: return
|
||||
if (DescriptorUtils.isAnnotationClass(constructedClass) && !CallExpressionResolver.canInstantiateAnnotationClass(
|
||||
expression,
|
||||
context.trace
|
||||
)
|
||||
) {
|
||||
val supported = constructedClass.declaredTypeParameters.isEmpty()
|
||||
if (supported) {
|
||||
context.trace.report(Errors.ANNOTATION_CLASS_CONSTRUCTOR_CALL.on(expression))
|
||||
} else {
|
||||
// already reported in CallExpressionResolver.getCallExpressionTypeInfoWithoutFinalTypeCheck
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+208
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* 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.backend.common.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.BackendContext
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
|
||||
import org.jetbrains.kotlin.backend.common.deepCopyWithVariables
|
||||
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.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.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.isKClass
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
val ANNOTATION_IMPLEMENTATION = object : IrDeclarationOriginImpl("ANNOTATION_IMPLEMENTATION", isSynthetic = true) {}
|
||||
|
||||
class AnnotationImplementationLowering(
|
||||
val transformer: (IrFile) -> AnnotationImplementationTransformer
|
||||
) : FileLoweringPass {
|
||||
override fun lower(irFile: IrFile) {
|
||||
val tf = transformer(irFile)
|
||||
irFile.transformChildrenVoid(tf)
|
||||
tf.implementations.values.forEach {
|
||||
val parentClass = it.parent as IrDeclarationContainer
|
||||
parentClass.declarations += it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open class AnnotationImplementationTransformer(val context: BackendContext, val irFile: IrFile) : IrElementTransformerVoidWithContext() {
|
||||
internal val implementations: MutableMap<IrClass, IrClass> = mutableMapOf()
|
||||
|
||||
override fun visitConstructorCall(expression: IrConstructorCall): IrExpression {
|
||||
val constructedClass = expression.type.classOrNull?.owner ?: return expression
|
||||
if (!constructedClass.isAnnotationClass) return expression
|
||||
if (constructedClass.typeParameters.isNotEmpty()) return expression // Not supported yet
|
||||
|
||||
val implClass = implementations.getOrPut(constructedClass) { createAnnotationImplementation(constructedClass) }
|
||||
val ctor = implClass.constructors.single()
|
||||
val newCall = IrConstructorCallImpl.fromSymbolOwner(
|
||||
expression.startOffset,
|
||||
expression.endOffset,
|
||||
implClass.defaultType,
|
||||
ctor.symbol,
|
||||
)
|
||||
newCall.copyTypeAndValueArgumentsFrom(expression)
|
||||
newCall.transformChildrenVoid() // for annotations in annotations
|
||||
return newCall
|
||||
}
|
||||
|
||||
private fun createAnnotationImplementation(annotationClass: IrClass): IrClass {
|
||||
val localDeclarationParent = currentClass?.scope?.getLocalDeclarationParent() as? IrClass
|
||||
val parentFqName = annotationClass.fqNameWhenAvailable!!.asString().replace('.', '_')
|
||||
val wrapperName = Name.identifier("annotationImpl\$$parentFqName$0")
|
||||
val subclass = context.irFactory.buildClass {
|
||||
name = wrapperName
|
||||
origin = ANNOTATION_IMPLEMENTATION
|
||||
// It can be seen from inline functions and multiple classes within one file
|
||||
// JavaDescriptorVisibilities.PACKAGE_VISIBILITY also can be used here, like in SAM, but that's not a big difference
|
||||
// since declaration is synthetic anyway
|
||||
visibility = DescriptorVisibilities.INTERNAL
|
||||
}.apply {
|
||||
parent = localDeclarationParent ?: irFile
|
||||
createImplicitParameterDeclarationWithWrappedDescriptor()
|
||||
superTypes = listOf(annotationClass.defaultType)
|
||||
}
|
||||
|
||||
val ctor = subclass.addConstructor {
|
||||
visibility = DescriptorVisibilities.PUBLIC
|
||||
}
|
||||
val (originalProps, implementationProps) = implementAnnotationProperties(subclass, annotationClass, ctor)
|
||||
implementEqualsAndHashCode(annotationClass, subclass, originalProps, implementationProps)
|
||||
implementPlatformSpecificParts(annotationClass, subclass)
|
||||
return subclass
|
||||
}
|
||||
|
||||
fun implementAnnotationProperties(implClass: IrClass, annotationClass: IrClass, generatedConstructor: IrConstructor): Pair<List<IrProperty>, List<IrProperty>> {
|
||||
val ctorBody = context.irFactory.createBlockBody(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET, listOf(
|
||||
IrDelegatingConstructorCallImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET, context.irBuiltIns.unitType, context.irBuiltIns.anyClass.constructors.single(),
|
||||
typeArgumentsCount = 0, valueArgumentsCount = 0
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
generatedConstructor.body = ctorBody
|
||||
|
||||
val properties = annotationClass.getAnnotationProperties()
|
||||
|
||||
return properties to properties.map { property ->
|
||||
|
||||
val propType = property.getter!!.returnType
|
||||
val propName = property.name
|
||||
val field = context.irFactory.buildField {
|
||||
name = propName
|
||||
type = propType
|
||||
origin = ANNOTATION_IMPLEMENTATION
|
||||
isFinal = true
|
||||
visibility = DescriptorVisibilities.PRIVATE
|
||||
}.also { it.parent = implClass }
|
||||
|
||||
val parameter = generatedConstructor.addValueParameter(propName.asString(), propType)
|
||||
// VALUE_FROM_PARAMETER
|
||||
val originalParameter = ((property.backingField?.initializer?.expression as? IrGetValue)?.symbol?.owner as? IrValueParameter)
|
||||
if (originalParameter?.defaultValue != null) {
|
||||
parameter.defaultValue = originalParameter.defaultValue!!.deepCopyWithVariables().also { it.transformChildrenVoid() }
|
||||
}
|
||||
|
||||
ctorBody.statements += IrSetFieldImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET, field.symbol,
|
||||
IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, implClass.thisReceiver!!.symbol),
|
||||
IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, parameter.symbol),
|
||||
context.irBuiltIns.unitType,
|
||||
)
|
||||
|
||||
val prop = implClass.addProperty {
|
||||
name = propName
|
||||
isVar = false
|
||||
origin = ANNOTATION_IMPLEMENTATION
|
||||
}.apply {
|
||||
backingField = field
|
||||
parent = implClass
|
||||
}
|
||||
|
||||
prop.addGetter {
|
||||
name = propName // Annotation value getter should be named 'x', not 'getX'
|
||||
returnType = propType.kClassToJClassIfNeeded() // On JVM, annotation store j.l.Class even if declared with KClass
|
||||
origin = ANNOTATION_IMPLEMENTATION
|
||||
visibility = DescriptorVisibilities.PUBLIC
|
||||
modality = Modality.FINAL
|
||||
}.apply {
|
||||
dispatchReceiverParameter = implClass.thisReceiver!!.copyTo(this)
|
||||
body = context.createIrBuilder(symbol).irBlockBody {
|
||||
var value: IrExpression = irGetField(irGet(dispatchReceiverParameter!!), field)
|
||||
if (propType.isKClass()) value = this.kClassExprToJClassIfNeeded(value)
|
||||
+irReturn(value)
|
||||
}
|
||||
}
|
||||
|
||||
prop
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun IrClass.getAnnotationProperties(): List<IrProperty> {
|
||||
// For some weird reason, annotations defined in other IrFiles, do not have IrProperties in declarations.
|
||||
// (although annotations imported from Java do have)
|
||||
val props = declarations.filterIsInstance<IrProperty>()
|
||||
if (props.isNotEmpty()) return props
|
||||
return declarations.filterIsInstance<IrSimpleFunction>().filter { it.origin == IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR }
|
||||
.mapNotNull { it.correspondingPropertySymbol?.owner }
|
||||
}
|
||||
|
||||
open fun IrType.kClassToJClassIfNeeded(): IrType = this
|
||||
|
||||
open fun IrBuilderWithScope.kClassExprToJClassIfNeeded(irExpression: IrExpression): IrExpression = irExpression
|
||||
|
||||
open fun generatedEquals(irBuilder: IrBlockBodyBuilder, type: IrType, arg1: IrExpression, arg2: IrExpression): IrExpression =
|
||||
irBuilder.irEquals(arg1, arg2)
|
||||
|
||||
@Suppress("UNUSED_VARIABLE")
|
||||
fun implementEqualsAndHashCode(annotationClass: IrClass, implClass: IrClass, originalProps: List<IrProperty>, childProps: List<IrProperty>) {
|
||||
val creator = MethodsFromAnyGeneratorForLowerings(context, implClass, ANNOTATION_IMPLEMENTATION)
|
||||
val generator =
|
||||
creator.LoweringDataClassMemberGenerator(
|
||||
nameForToString = "@" + annotationClass.fqNameWhenAvailable!!.asString(),
|
||||
typeForEquals = annotationClass.defaultType
|
||||
) { type, a, b ->
|
||||
generatedEquals(this, type, a, b)
|
||||
}
|
||||
|
||||
// Manual implementation of equals is required for two reasons:
|
||||
// 1. `other` should be casted to interface instead of implementation
|
||||
// 2. Properties should be retrieved using getters without accessing backing fields
|
||||
// (DataClassMembersGenerator typically tries to access fields)
|
||||
val eqFun = creator.createEqualsMethodDeclaration()
|
||||
generator.generateEqualsUsingGetters(eqFun, annotationClass.defaultType, originalProps)
|
||||
|
||||
val hcFun = creator.createHashCodeMethodDeclaration()
|
||||
generator.generateHashCodeMethod(hcFun, childProps)
|
||||
|
||||
val toStringFun = creator.createToStringMethodDeclaration()
|
||||
generator.generateToStringMethod(toStringFun, childProps)
|
||||
}
|
||||
|
||||
open fun implementPlatformSpecificParts(annotationClass: IrClass, implClass: IrClass) {}
|
||||
}
|
||||
|
||||
+127
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* 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.backend.common.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.BackendContext
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.addFunction
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.addValueParameter
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
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.getClass
|
||||
import org.jetbrains.kotlin.ir.types.isArray
|
||||
import org.jetbrains.kotlin.ir.util.DataClassMembersGenerator
|
||||
import org.jetbrains.kotlin.ir.util.functions
|
||||
import org.jetbrains.kotlin.ir.util.isPrimitiveArray
|
||||
|
||||
class MethodsFromAnyGeneratorForLowerings(val context: BackendContext, val irClass: IrClass, val origin: IrDeclarationOrigin) {
|
||||
fun createToStringMethodDeclaration(): IrSimpleFunction = irClass.addFunction("toString", context.irBuiltIns.stringType).apply {
|
||||
overriddenSymbols = irClass.collectOverridenSymbols { it.isToString() }
|
||||
}
|
||||
|
||||
fun createHashCodeMethodDeclaration(): IrSimpleFunction = irClass.addFunction("hashCode", context.irBuiltIns.intType).apply {
|
||||
overriddenSymbols = irClass.collectOverridenSymbols { it.isHashCode() }
|
||||
}
|
||||
|
||||
fun createEqualsMethodDeclaration(): IrSimpleFunction = irClass.addFunction("equals", context.irBuiltIns.booleanType).apply {
|
||||
overriddenSymbols = irClass.collectOverridenSymbols { it.isEquals(context) }
|
||||
addValueParameter("other", context.irBuiltIns.anyNType)
|
||||
}
|
||||
|
||||
inner class LoweringDataClassMemberGenerator(
|
||||
val nameForToString: String,
|
||||
val typeForEquals: IrType,
|
||||
val selectEquals: IrBlockBodyBuilder.(IrType, IrExpression, IrExpression) -> IrExpression,
|
||||
) :
|
||||
DataClassMembersGenerator(
|
||||
IrLoweringContext(context),
|
||||
context.ir.symbols.externalSymbolTable,
|
||||
irClass,
|
||||
origin
|
||||
) {
|
||||
|
||||
override fun declareSimpleFunction(startOffset: Int, endOffset: Int, functionDescriptor: FunctionDescriptor): IrFunction {
|
||||
error("Descriptor API shouldn't be used in lowerings")
|
||||
}
|
||||
|
||||
override fun generateSyntheticFunctionParameterDeclarations(irFunction: IrFunction) {
|
||||
// no-op — irFunction from lowering should already have necessary parameters
|
||||
}
|
||||
|
||||
override fun getProperty(parameter: ValueParameterDescriptor?, irValueParameter: IrValueParameter?): IrProperty? {
|
||||
error("Descriptor API shouldn't be used in lowerings")
|
||||
}
|
||||
|
||||
override fun transform(typeParameterDescriptor: TypeParameterDescriptor): IrType {
|
||||
error("Descriptor API shouldn't be used in lowerings")
|
||||
}
|
||||
|
||||
override val intPlusSymbol: IrSimpleFunctionSymbol =
|
||||
context.irBuiltIns.intClass.functions.single { it.owner.name.asString() == "plus" && it.owner.valueParameters[0].type == context.irBuiltIns.intType }
|
||||
|
||||
override val intTimesSymbol: IrSimpleFunctionSymbol =
|
||||
context.irBuiltIns.intClass.functions.single { it.owner.name.asString() == "times" && it.owner.valueParameters[0].type == context.irBuiltIns.intType }
|
||||
|
||||
override fun getHashCodeFunctionInfo(type: IrType): HashCodeFunctionInfo {
|
||||
val symbol = if (type.isArray() || type.isPrimitiveArray()) {
|
||||
context.irBuiltIns.dataClassArrayMemberHashCodeSymbol
|
||||
} else {
|
||||
context.irBuiltIns.anyClass.functions.single { it.owner.name.asString() == "hashCode" }
|
||||
}
|
||||
return object : HashCodeFunctionInfo {
|
||||
override val symbol: IrSimpleFunctionSymbol = symbol
|
||||
|
||||
override fun commitSubstituted(irMemberAccessExpression: IrMemberAccessExpression<*>) {}
|
||||
}
|
||||
}
|
||||
|
||||
override fun IrClass.classNameForToString(): String = nameForToString
|
||||
|
||||
fun generateEqualsUsingGetters(equalsFun: IrSimpleFunction, typeForEquals: IrType, properties: List<IrProperty>) = equalsFun.apply {
|
||||
body = this@MethodsFromAnyGeneratorForLowerings.context.createIrBuilder(symbol).irBlockBody {
|
||||
val irType = typeForEquals
|
||||
fun irOther() = irGet(valueParameters[0])
|
||||
fun irThis() = irGet(dispatchReceiverParameter!!)
|
||||
fun IrProperty.get(receiver: IrExpression) = irCall(getter!!).apply {
|
||||
dispatchReceiver = receiver
|
||||
}
|
||||
|
||||
+irIfThenReturnFalse(irNotIs(irOther(), irType))
|
||||
val otherWithCast = irTemporary(irAs(irOther(), irType), "other_with_cast")
|
||||
for (property in properties) {
|
||||
val arg1 = property.get(irThis())
|
||||
val arg2 = property.get(irGet(irType, otherWithCast.symbol))
|
||||
+irIfThenReturnFalse(irNot(selectEquals(property.getter?.returnType ?: property.backingField!!.type, arg1, arg2)))
|
||||
}
|
||||
+irReturnTrue()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun IrFunction.isToString(): Boolean =
|
||||
name.asString() == "toString" && extensionReceiverParameter == null && valueParameters.isEmpty()
|
||||
|
||||
fun IrFunction.isHashCode() =
|
||||
name.asString() == "hashCode" && extensionReceiverParameter == null && valueParameters.isEmpty()
|
||||
|
||||
fun IrFunction.isEquals(context: BackendContext) =
|
||||
name.asString() == "equals" &&
|
||||
extensionReceiverParameter == null &&
|
||||
valueParameters.singleOrNull()?.type == context.irBuiltIns.anyNType
|
||||
|
||||
|
||||
fun IrClass.collectOverridenSymbols(predicate: (IrFunction) -> Boolean): List<IrSimpleFunctionSymbol> =
|
||||
superTypes.mapNotNull { it.getClass()?.functions?.singleOrNull(predicate)?.symbol }
|
||||
|
||||
}
|
||||
}
|
||||
+11
-24
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.backend.common.ScopeWithIr
|
||||
import org.jetbrains.kotlin.backend.common.ir.addFakeOverrides
|
||||
import org.jetbrains.kotlin.backend.common.ir.copyTo
|
||||
import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.lower.MethodsFromAnyGeneratorForLowerings.Companion.isHashCode
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
|
||||
@@ -273,8 +274,9 @@ class SamEqualsHashCodeMethodsGenerator(
|
||||
|
||||
fun generate() {
|
||||
generateGetFunctionDelegate()
|
||||
generateEquals()
|
||||
generateHashCode()
|
||||
val anyGenerator = MethodsFromAnyGeneratorForLowerings(context, klass, IrDeclarationOrigin.SYNTHETIC_GENERATED_SAM_IMPLEMENTATION)
|
||||
generateEquals(anyGenerator)
|
||||
generateHashCode(anyGenerator)
|
||||
}
|
||||
|
||||
private fun generateGetFunctionDelegate() {
|
||||
@@ -286,17 +288,9 @@ class SamEqualsHashCodeMethodsGenerator(
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateEquals() {
|
||||
klass.addFunction("equals", builtIns.booleanType).apply {
|
||||
overriddenSymbols = klass.superTypes.mapNotNull {
|
||||
it.getClass()?.functions?.singleOrNull {
|
||||
it.name.asString() == "equals" &&
|
||||
it.extensionReceiverParameter == null &&
|
||||
it.valueParameters.singleOrNull()?.type == builtIns.anyNType
|
||||
}?.symbol
|
||||
}
|
||||
|
||||
val other = addValueParameter("other", builtIns.anyNType)
|
||||
private fun generateEquals(anyGenerator: MethodsFromAnyGeneratorForLowerings) {
|
||||
anyGenerator.createEqualsMethodDeclaration().apply {
|
||||
val other = valueParameters[0]
|
||||
body = context.createIrBuilder(symbol).run {
|
||||
irExprBody(
|
||||
irIfThenElse(
|
||||
@@ -322,16 +316,9 @@ class SamEqualsHashCodeMethodsGenerator(
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateHashCode() {
|
||||
klass.addFunction("hashCode", builtIns.intType).apply {
|
||||
|
||||
fun isHashCode(function: IrSimpleFunction) =
|
||||
function.name.asString() == "hashCode" && function.extensionReceiverParameter == null && function.valueParameters.isEmpty()
|
||||
|
||||
overriddenSymbols = klass.superTypes.mapNotNull {
|
||||
it.getClass()?.functions?.singleOrNull(::isHashCode)?.symbol
|
||||
}
|
||||
val hashCode = context.irBuiltIns.functionClass.owner.functions.single(::isHashCode).symbol
|
||||
private fun generateHashCode(anyGenerator: MethodsFromAnyGeneratorForLowerings) {
|
||||
anyGenerator.createHashCodeMethodDeclaration().apply {
|
||||
val hashCode = context.irBuiltIns.functionClass.owner.functions.single{ it.isHashCode() }.symbol
|
||||
body = context.createIrBuilder(symbol).run {
|
||||
irExprBody(
|
||||
irCall(hashCode).also {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@@ -324,6 +324,7 @@ private val jvmFilePhases = listOf(
|
||||
inventNamesForLocalClassesPhase,
|
||||
kCallableNamePropertyPhase,
|
||||
annotationPhase,
|
||||
annotationImplementationPhase,
|
||||
polymorphicSignaturePhase,
|
||||
varargPhase,
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@@ -802,19 +802,30 @@ class JvmSymbols(
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrClass.addArraysEqualsFunction(arrayType: IrSimpleType) {
|
||||
addFunction("equals", irBuiltIns.booleanType, isStatic = true).apply {
|
||||
addValueParameter("a", arrayType)
|
||||
addValueParameter("b", arrayType)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
val arraysClass: IrClassSymbol =
|
||||
createClass(FqName("java.util.Arrays")) { irClass ->
|
||||
irClass.addArraysCopyOfFunction(booleanArrayType)
|
||||
irClass.addArraysCopyOfFunction(byteArrayType)
|
||||
irClass.addArraysCopyOfFunction(charArrayType)
|
||||
irClass.addArraysCopyOfFunction(shortArrayType)
|
||||
irClass.addArraysCopyOfFunction(intArrayType)
|
||||
irClass.addArraysCopyOfFunction(longArrayType)
|
||||
irClass.addArraysCopyOfFunction(floatArrayType)
|
||||
irClass.addArraysCopyOfFunction(doubleArrayType)
|
||||
|
||||
// public static <T> T[] copyOf(T[] original, int newLength)
|
||||
irClass.addArraysCopyOfFunction(arrayOfAnyNType)
|
||||
for (type in listOf(
|
||||
booleanArrayType,
|
||||
byteArrayType,
|
||||
charArrayType,
|
||||
shortArrayType,
|
||||
intArrayType,
|
||||
longArrayType,
|
||||
floatArrayType,
|
||||
doubleArrayType,
|
||||
arrayOfAnyNType
|
||||
)) {
|
||||
irClass.addArraysCopyOfFunction(type)
|
||||
irClass.addArraysEqualsFunction(type)
|
||||
}
|
||||
}
|
||||
|
||||
fun getArraysCopyOfFunction(arrayType: IrSimpleType): IrSimpleFunctionSymbol {
|
||||
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* 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.backend.jvm.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.lower.ANNOTATION_IMPLEMENTATION
|
||||
import org.jetbrains.kotlin.backend.common.lower.AnnotationImplementationLowering
|
||||
import org.jetbrains.kotlin.backend.common.lower.AnnotationImplementationTransformer
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.lower.FunctionReferenceLowering.Companion.javaClassReference
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.addFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.defaultType
|
||||
import org.jetbrains.kotlin.ir.util.findDeclaration
|
||||
import org.jetbrains.kotlin.ir.util.isPrimitiveArray
|
||||
import org.jetbrains.kotlin.ir.util.render
|
||||
|
||||
internal val annotationImplementationPhase = makeIrFilePhase<JvmBackendContext>(
|
||||
{ ctxt -> AnnotationImplementationLowering { JvmAnnotationImplementationTransformer(ctxt, it) } },
|
||||
name = "AnnotationImplementation",
|
||||
description = "Create synthetic annotations implementations and use them in annotations constructor calls"
|
||||
)
|
||||
|
||||
class JvmAnnotationImplementationTransformer(val jvmContext: JvmBackendContext, file: IrFile) :
|
||||
AnnotationImplementationTransformer(jvmContext, file) {
|
||||
override fun IrType.kClassToJClassIfNeeded(): IrType = when {
|
||||
this.isKClass() -> jvmContext.ir.symbols.javaLangClass.starProjectedType
|
||||
this.isKClassArray() -> jvmContext.irBuiltIns.arrayClass.typeWith(
|
||||
jvmContext.ir.symbols.javaLangClass.starProjectedType
|
||||
)
|
||||
else -> this
|
||||
}
|
||||
|
||||
private fun IrType.isKClassArray() =
|
||||
this is IrSimpleType && isArray() && arguments.single().typeOrNull?.isKClass() == true
|
||||
|
||||
override fun IrBuilderWithScope.kClassExprToJClassIfNeeded(irExpression: IrExpression): IrExpression {
|
||||
with(this) {
|
||||
return irGet(
|
||||
jvmContext.ir.symbols.javaLangClass.starProjectedType,
|
||||
null,
|
||||
jvmContext.ir.symbols.kClassJava.owner.getter!!.symbol
|
||||
).apply {
|
||||
extensionReceiver = irExpression
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun generatedEquals(irBuilder: IrBlockBodyBuilder, type: IrType, arg1: IrExpression, arg2: IrExpression): IrExpression {
|
||||
return if (type.isArray() || type.isPrimitiveArray()) {
|
||||
val targetType = if (type.isPrimitiveArray()) type else jvmContext.ir.symbols.arrayOfAnyNType
|
||||
val requiredSymbol = jvmContext.ir.symbols.arraysClass.owner.findDeclaration<IrFunction> {
|
||||
it.name.asString() == "equals" && it.valueParameters.size == 2 && it.valueParameters.first().type == targetType
|
||||
}
|
||||
requireNotNull(requiredSymbol) { "Can't find Arrays.equals method for type ${targetType.render()}" }
|
||||
irBuilder.irCall(
|
||||
requiredSymbol.symbol
|
||||
).apply {
|
||||
putValueArgument(0, arg1)
|
||||
putValueArgument(1, arg2)
|
||||
}
|
||||
} else super.generatedEquals(irBuilder, type, arg1, arg2)
|
||||
}
|
||||
|
||||
override fun implementPlatformSpecificParts(annotationClass: IrClass, implClass: IrClass) {
|
||||
implClass.addFunction(
|
||||
name = "annotationType",
|
||||
returnType = jvmContext.ir.symbols.javaLangClass.starProjectedType,
|
||||
origin = ANNOTATION_IMPLEMENTATION,
|
||||
isStatic = false
|
||||
).apply {
|
||||
body = jvmContext.createIrBuilder(symbol).irBlockBody {
|
||||
+irReturn(javaClassReference(annotationClass.defaultType, jvmContext))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@@ -16,9 +16,7 @@ import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.mapTypeParameters
|
||||
import org.jetbrains.kotlin.ir.expressions.mapValueParameters
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.*
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.classifierOrNull
|
||||
@@ -34,7 +32,7 @@ import org.jetbrains.kotlin.name.Name
|
||||
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
||||
abstract class DataClassMembersGenerator(
|
||||
val context: IrGeneratorContext,
|
||||
val symbolTable: SymbolTable,
|
||||
val symbolTable: ReferenceSymbolTable,
|
||||
val irClass: IrClass,
|
||||
val origin: IrDeclarationOrigin
|
||||
) {
|
||||
@@ -43,11 +41,24 @@ abstract class DataClassMembersGenerator(
|
||||
|
||||
inline fun <T : IrDeclaration> T.buildWithScope(builder: (T) -> Unit): T =
|
||||
also { irDeclaration ->
|
||||
symbolTable.withScope(irDeclaration) {
|
||||
symbolTable.withReferenceScope(irDeclaration) {
|
||||
builder(irDeclaration)
|
||||
}
|
||||
}
|
||||
|
||||
private val intClass = context.builtIns.int
|
||||
private val intType = context.builtIns.intType
|
||||
|
||||
open val intTimesSymbol: IrSimpleFunctionSymbol =
|
||||
intClass.unsubstitutedMemberScope.findFirstFunction("times") {
|
||||
KotlinTypeChecker.DEFAULT.equalTypes(it.valueParameters[0].type, intType)
|
||||
}.let { symbolTable.referenceSimpleFunction(it) }
|
||||
|
||||
open val intPlusSymbol: IrSimpleFunctionSymbol =
|
||||
intClass.unsubstitutedMemberScope.findFirstFunction("plus") {
|
||||
KotlinTypeChecker.DEFAULT.equalTypes(it.valueParameters[0].type, intType)
|
||||
}.let { symbolTable.referenceSimpleFunction(it) }
|
||||
|
||||
private inner class MemberFunctionBuilder(
|
||||
startOffset: Int = UNDEFINED_OFFSET,
|
||||
endOffset: Int = UNDEFINED_OFFSET,
|
||||
@@ -206,7 +217,7 @@ abstract class DataClassMembersGenerator(
|
||||
|
||||
fun generateToStringMethodBody(properties: List<IrProperty>) {
|
||||
val irConcat = irConcat()
|
||||
irConcat.addArgument(irString(irClass.name.asString() + "("))
|
||||
irConcat.addArgument(irString(irClass.classNameForToString() + "("))
|
||||
var first = true
|
||||
for (property in properties) {
|
||||
if (!first) irConcat.addArgument(irString(", "))
|
||||
@@ -362,4 +373,6 @@ abstract class DataClassMembersGenerator(
|
||||
generateToStringMethodBody(properties)
|
||||
}
|
||||
}
|
||||
|
||||
open fun IrClass.classNameForToString(): String = irClass.name.asString()
|
||||
}
|
||||
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
|
||||
// WITH_RUNTIME
|
||||
// !LANGUAGE: +InstantiationOfAnnotationClasses
|
||||
|
||||
// FILE: a.kt
|
||||
|
||||
package test
|
||||
|
||||
annotation class A1
|
||||
|
||||
annotation class A2
|
||||
|
||||
fun interface I {
|
||||
fun run(): A1
|
||||
}
|
||||
|
||||
// FILE: test.kt
|
||||
|
||||
package test
|
||||
|
||||
class E {
|
||||
fun insideClass(): A1 = A1()
|
||||
fun insideLammbda(): A1 = run { A1() }
|
||||
fun insideSAM(): I = I { A1() }
|
||||
}
|
||||
|
||||
class G {
|
||||
// test that we can reuse instance in different classes from same file
|
||||
fun insideClassAgain(): A1 = A1()
|
||||
}
|
||||
|
||||
fun outsideClass(): A2 = A2()
|
||||
|
||||
fun test(instance: Any, parent: String, fqa: String) {
|
||||
val clz = instance.javaClass
|
||||
assert(clz.getName().startsWith(parent))
|
||||
assert(clz.getName().contains(fqa))
|
||||
assert(clz.getEnclosingMethod() == null)
|
||||
assert(clz.getEnclosingClass().getName() == parent)
|
||||
// SAM treated as anonymous because of Origin or something else, see ClassCodegen#IrClass.isAnonymousInnerClass
|
||||
// assert(clz.getDeclaringClass() == null)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
test(E().insideClass(), "test.E", "test_A1")
|
||||
test(E().insideLammbda(), "test.E", "test_A1")
|
||||
test(E().insideSAM().run(), "test.E", "test_A1")
|
||||
test(G().insideClassAgain(), "test.E", "test_A1")
|
||||
test(outsideClass(), "test.TestKt", "test_A2")
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
|
||||
// WITH_RUNTIME
|
||||
// !LANGUAGE: +InstantiationOfAnnotationClasses
|
||||
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
annotation class Bar(val i:Int, val s: String, val f: Float)
|
||||
|
||||
annotation class Foo(
|
||||
val int: Int,
|
||||
val s: String,
|
||||
val arr: Array<String>,
|
||||
val arr2: IntArray,
|
||||
val kClass: KClass<*>,
|
||||
val bar: Bar
|
||||
)
|
||||
|
||||
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"
|
||||
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"
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
|
||||
// WITH_RUNTIME
|
||||
// !LANGUAGE: +InstantiationOfAnnotationClasses
|
||||
|
||||
// note: taken from ../parameters.kt and ../parametersWithPrimitiveValues.kt
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
enum class E { E0 }
|
||||
annotation class Empty
|
||||
|
||||
annotation class A(
|
||||
val b: Byte,
|
||||
val s: Short,
|
||||
val i: Int,
|
||||
val f: Float,
|
||||
val d: Double,
|
||||
val l: Long,
|
||||
val c: Char,
|
||||
val bool: Boolean
|
||||
)
|
||||
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
annotation class Anno(
|
||||
val s: String,
|
||||
val i: Int,
|
||||
val f: Double,
|
||||
val u: UInt,
|
||||
val e: E,
|
||||
val a: A,
|
||||
val k: KClass<*>,
|
||||
val arr: Array<String>,
|
||||
val intArr: IntArray,
|
||||
val arrOfE: Array<E>,
|
||||
val arrOfA: Array<Empty>,
|
||||
val arrOfK: Array<KClass<*>>
|
||||
)
|
||||
|
||||
|
||||
fun box(): String {
|
||||
val anno = Anno(
|
||||
"OK", 42, 2.718281828, 43u, E.E0,
|
||||
A(1, 1, 1, 1.0.toFloat(), 1.0, 1, 'c', true),
|
||||
A::class, emptyArray(), intArrayOf(1, 2), arrayOf(E.E0), arrayOf(Empty()), arrayOf(E::class, Empty::class)
|
||||
)
|
||||
assertEquals(anno.s, "OK")
|
||||
assertEquals(anno.i, 42)
|
||||
assert(anno.f > 2.0 && anno.f < 3.0)
|
||||
assertEquals(anno.u, 43u)
|
||||
assertEquals(anno.e, E.E0)
|
||||
assert(anno.a is A)
|
||||
assert(anno.k == A::class)
|
||||
assert(anno.arr.isEmpty())
|
||||
assert(anno.intArr.contentEquals(intArrayOf(1, 2)))
|
||||
assert(anno.arrOfE.contentEquals(arrayOf(E.E0)))
|
||||
assert(anno.arrOfA.size == 1)
|
||||
// assert(anno.arrOfK.size == 2) TODO(KT-47703): Array<KClass> to Array<j.l.Class> conversion
|
||||
val ann = anno.a
|
||||
assertEquals(ann.b, 1.toByte())
|
||||
assertEquals(ann.s, 1.toShort())
|
||||
assertEquals(ann.i, 1)
|
||||
assertEquals(ann.f, 1.toFloat())
|
||||
assertEquals(ann.d, 1.0)
|
||||
assertEquals(ann.l, 1.toLong())
|
||||
assertEquals(ann.c, 'c')
|
||||
assert(ann.bool)
|
||||
return "OK"
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
|
||||
// WITH_RUNTIME
|
||||
// !LANGUAGE: +InstantiationOfAnnotationClasses
|
||||
|
||||
package test
|
||||
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
enum class E { A, B }
|
||||
|
||||
annotation class A()
|
||||
|
||||
annotation class B(val a: A = A())
|
||||
|
||||
annotation class C(
|
||||
val i: Int = 42,
|
||||
val b: B = B(),
|
||||
val kClass: KClass<*> = B::class,
|
||||
val e: E = E.B,
|
||||
val aS: Array<String> = arrayOf("a", "b"),
|
||||
val aI: IntArray = intArrayOf(1, 2)
|
||||
)
|
||||
|
||||
annotation class Partial(
|
||||
val i: Int = 42,
|
||||
val s: String = "foo",
|
||||
val e: E = E.A
|
||||
)
|
||||
|
||||
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])")
|
||||
val p = Partial(e = E.B, s = "bar")
|
||||
assert(p.toString() == "@test.Partial(i=42, s=bar, e=B)")
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
|
||||
// WITH_RUNTIME
|
||||
// !LANGUAGE: +InstantiationOfAnnotationClasses
|
||||
|
||||
package test
|
||||
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
enum class E { E0 }
|
||||
annotation class Empty
|
||||
|
||||
annotation class A(
|
||||
val b: Byte,
|
||||
val s: Short,
|
||||
val i: Int,
|
||||
val f: Float,
|
||||
val d: Double,
|
||||
val l: Long,
|
||||
val c: Char,
|
||||
val bool: Boolean
|
||||
)
|
||||
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
annotation class Anno(
|
||||
val s: String,
|
||||
val i: Int,
|
||||
val f: Double,
|
||||
val u: UInt,
|
||||
val e: E,
|
||||
val a: A,
|
||||
val k: KClass<*>,
|
||||
val arr: Array<String>,
|
||||
val intArr: IntArray,
|
||||
val arrOfE: Array<E>,
|
||||
val arrOfA: Array<Empty>,
|
||||
)
|
||||
|
||||
fun box(): String {
|
||||
val anno = Anno(
|
||||
"OK", 42, 2.718281828, 43u, E.E0,
|
||||
A(1, 1, 1, 1.0.toFloat(), 1.0, 1, 'c', true),
|
||||
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), " +
|
||||
"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"
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
|
||||
// WITH_RUNTIME
|
||||
// !LANGUAGE: +InstantiationOfAnnotationClasses
|
||||
|
||||
annotation class Foo(
|
||||
val int: Int,
|
||||
)
|
||||
|
||||
fun box(): String {
|
||||
val foo = Foo(42)
|
||||
val jClass = (foo as java.lang.annotation.Annotation).annotationType()
|
||||
val kClass = foo.annotationClass
|
||||
if (kClass != Foo::class) return "FAIL $kClass"
|
||||
if (jClass != Foo::class.java) return "FAIL $jClass"
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
|
||||
// WITH_RUNTIME
|
||||
// !LANGUAGE: +InstantiationOfAnnotationClasses
|
||||
|
||||
// FILE: A.java
|
||||
|
||||
public @interface A {}
|
||||
|
||||
// FILE: B.java
|
||||
|
||||
public @interface B {
|
||||
String value();
|
||||
}
|
||||
|
||||
// FILE: C.java
|
||||
|
||||
public @interface C {
|
||||
int[] v1();
|
||||
String v2();
|
||||
}
|
||||
|
||||
// FILE: D.java
|
||||
|
||||
public @interface D {
|
||||
String value() default "hello";
|
||||
}
|
||||
|
||||
// FILE: b.kt
|
||||
|
||||
fun box(): String {
|
||||
val a = A()
|
||||
val b = B("OK")
|
||||
assert(b.value == "OK")
|
||||
val c = C(v2 = "v2", v1 = intArrayOf(1))
|
||||
assert(c.v2 == "v2")
|
||||
// TODO(KT-47702): Looks like we have to force users either to pass default java parameters explicitly
|
||||
// or hack LazyJavaClassDescriptor/JavaPropertyDescriptor to load annotation param default value,
|
||||
// because it is not stored currently anywhere.
|
||||
// val d = D()
|
||||
val d = D("OK").value
|
||||
return d
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
|
||||
// WITH_RUNTIME
|
||||
// !LANGUAGE: +InstantiationOfAnnotationClasses
|
||||
|
||||
|
||||
// FILE: a.kt
|
||||
package a
|
||||
|
||||
annotation class A(val i: Int)
|
||||
|
||||
fun createInOtherFile(): A = A(10)
|
||||
|
||||
// FILE: b.kt
|
||||
|
||||
import a.*
|
||||
|
||||
fun here(): A = A(10)
|
||||
|
||||
fun box(): String {
|
||||
if (here() != createInOtherFile()) return "Fail equals"
|
||||
if (here().hashCode() != createInOtherFile().hashCode()) return "Fail hashCode"
|
||||
if (here().toString() != createInOtherFile().toString()) return "Fail toString"
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// IGNORE_DEXING
|
||||
|
||||
// WITH_RUNTIME
|
||||
// !LANGUAGE: +InstantiationOfAnnotationClasses
|
||||
|
||||
// MODULE: lib
|
||||
// FILE: lib.kt
|
||||
|
||||
package a
|
||||
|
||||
annotation class A(val i: Int)
|
||||
|
||||
inline fun foo(i: Int): A = A(i)
|
||||
|
||||
inline fun bar(f: () -> Int): A = A(f())
|
||||
|
||||
// MODULE: app(lib)
|
||||
// FILE: app.kt
|
||||
|
||||
package test
|
||||
|
||||
import a.*
|
||||
|
||||
class C {
|
||||
fun one(): A = foo(1)
|
||||
fun two(): A = bar { 2 }
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val one = C().one()
|
||||
val two = C().two()
|
||||
assert(one.i == 1)
|
||||
assert(two.i == 2)
|
||||
// Just like SAM wrappers, annotation implementation classes should be copied from inline functions
|
||||
// into current module to avoid compatibility problems when inline fun implementation in origin module
|
||||
// has changed (e.g. do not instantiate annotation anymore)
|
||||
assert(one.javaClass.getEnclosingClass().getName() == "test.C")
|
||||
assert(two.javaClass.getEnclosingClass().getName() == "test.C")
|
||||
return "OK"
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
|
||||
// WITH_RUNTIME
|
||||
// !LANGUAGE: +InstantiationOfAnnotationClasses +MultiPlatformProjects
|
||||
|
||||
// MODULE: lib
|
||||
// FILE: common.kt
|
||||
|
||||
expect annotation class A(val value: String)
|
||||
|
||||
fun createCommon(): A = A("OK")
|
||||
|
||||
// FILE: platform.kt
|
||||
|
||||
actual annotation class A(actual val value: String)
|
||||
|
||||
fun createPlatform(): A = A("OK")
|
||||
|
||||
// MODULE: main(lib)
|
||||
// FILE: main.kt
|
||||
|
||||
fun createApp(): A = A("OK")
|
||||
|
||||
fun box(): String {
|
||||
if (createApp().value != "OK") return "FAIL app"
|
||||
if (createCommon().value != "OK") return "FAIL common"
|
||||
if (createPlatform().value != "OK") return "FAIL platform"
|
||||
return "OK"
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
// 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
|
||||
// WITH_RUNTIME
|
||||
// !LANGUAGE: +InstantiationOfAnnotationClasses
|
||||
// IGNORE_DEXING
|
||||
// TODO: D8 fails with AssertionError and does not print reason, need further investigation
|
||||
|
||||
// FILE: 1.kt
|
||||
|
||||
package a
|
||||
|
||||
annotation class A(val i: Int)
|
||||
|
||||
inline fun foo(i: Int): A = A(i)
|
||||
|
||||
inline fun bar(f: () -> Int): A = A(f())
|
||||
|
||||
// FILE: 2.kt
|
||||
|
||||
import a.*
|
||||
|
||||
class C {
|
||||
fun one(): A {
|
||||
return foo(1)
|
||||
}
|
||||
}
|
||||
|
||||
fun two(): A {
|
||||
return bar { 2 }
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val one = C().one()
|
||||
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"
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
// 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
|
||||
// WITH_RUNTIME
|
||||
// !LANGUAGE: +InstantiationOfAnnotationClasses
|
||||
// IGNORE_DEXING
|
||||
// TODO: D8 fails with AssertionError and does not print reason, need further investigation
|
||||
|
||||
// FILE: 1.kt
|
||||
|
||||
package a
|
||||
|
||||
annotation class A(val i: String)
|
||||
|
||||
interface I {
|
||||
fun g(): A
|
||||
}
|
||||
|
||||
inline fun foo(i: String): I = object : I {
|
||||
override fun g(): A {
|
||||
return A(i)
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: 2.kt
|
||||
|
||||
import a.*
|
||||
|
||||
class C() {
|
||||
fun one(): A = foo("OK").g()
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
return C().one().i
|
||||
}
|
||||
Vendored
+11
@@ -0,0 +1,11 @@
|
||||
// WITH_RUNTIME
|
||||
// IGNORE_BACKEND: JVM
|
||||
// !LANGUAGE: +InstantiationOfAnnotationClasses
|
||||
|
||||
annotation class Foo(val int: Int)
|
||||
|
||||
annotation class Bar
|
||||
|
||||
fun box() {
|
||||
val foo = Foo(42)
|
||||
}
|
||||
Vendored
+32
@@ -0,0 +1,32 @@
|
||||
@kotlin.Metadata
|
||||
public synthetic final class AnnotationCtorCallGenerateSyntheticKt$annotationImpl$Foo$0 {
|
||||
// source: 'annotationCtorCallGenerateSynthetic.kt'
|
||||
private synthetic final field int: int
|
||||
public method <init>(p0: int): void
|
||||
public synthetic final method annotationType(): java.lang.Class
|
||||
public final method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean
|
||||
public final method hashCode(): int
|
||||
public synthetic final method int(): int
|
||||
public final @org.jetbrains.annotations.NotNull method toString(): java.lang.String
|
||||
public synthetic inner class AnnotationCtorCallGenerateSyntheticKt$annotationImpl$Foo$0
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class AnnotationCtorCallGenerateSyntheticKt {
|
||||
// source: 'annotationCtorCallGenerateSynthetic.kt'
|
||||
public final static method box(): void
|
||||
public synthetic inner class AnnotationCtorCallGenerateSyntheticKt$annotationImpl$Foo$0
|
||||
}
|
||||
|
||||
@java.lang.annotation.Retention
|
||||
@kotlin.Metadata
|
||||
public annotation class Bar {
|
||||
// source: 'annotationCtorCallGenerateSynthetic.kt'
|
||||
}
|
||||
|
||||
@java.lang.annotation.Retention
|
||||
@kotlin.Metadata
|
||||
public annotation class Foo {
|
||||
// source: 'annotationCtorCallGenerateSynthetic.kt'
|
||||
public abstract method int(): int
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// WITH_RUNTIME
|
||||
// !LANGUAGE: +InstantiationOfAnnotationClasses
|
||||
|
||||
annotation class Foo(val bar: Bar)
|
||||
|
||||
annotation class Bar
|
||||
|
||||
@Foo(Bar())
|
||||
fun box() {
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
@kotlin.Metadata
|
||||
public final class AnnotationCtorCallNoSyntheticKt {
|
||||
// source: 'annotationCtorCallNoSynthetic.kt'
|
||||
public final static @Foo method box(): void
|
||||
}
|
||||
|
||||
@java.lang.annotation.Retention
|
||||
@kotlin.Metadata
|
||||
public annotation class Bar {
|
||||
// source: 'annotationCtorCallNoSynthetic.kt'
|
||||
}
|
||||
|
||||
@java.lang.annotation.Retention
|
||||
@kotlin.Metadata
|
||||
public annotation class Foo {
|
||||
// source: 'annotationCtorCallNoSynthetic.kt'
|
||||
public abstract method bar(): Bar
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||
// WITH_RUNTIME
|
||||
// SKIP_TXT
|
||||
// !LANGUAGE: +InstantiationOfAnnotationClasses
|
||||
|
||||
// FILE: test.kt
|
||||
|
||||
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)<!>
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
// 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)<!>
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
// 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 = A()
|
||||
val b = B(4)
|
||||
val c = C()
|
||||
val foo = <!ANNOTATION_CLASS_CONSTRUCTOR_CALL!>G(Int::class)<!>
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
// !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)<!>
|
||||
}
|
||||
Generated
+6
@@ -1103,6 +1103,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
runTest("compiler/testData/diagnostics/tests/annotations/ConstructorCall.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("ConstructorCallAllowed.kt")
|
||||
public void testConstructorCallAllowed() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/annotations/ConstructorCallAllowed.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("DanglingInScript.kts")
|
||||
public void testDanglingInScript() throws Exception {
|
||||
|
||||
+6
@@ -24,6 +24,12 @@ public class DiagnosticsNativeTestGenerated extends AbstractDiagnosticsNativeTes
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/nativeTests"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("annotationConstructorCallNative.kt")
|
||||
public void testAnnotationConstructorCallNative() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/nativeTests/annotationConstructorCallNative.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("sharedImmutable.kt")
|
||||
public void testSharedImmutable() throws Exception {
|
||||
|
||||
+6
@@ -24,6 +24,12 @@ 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 {
|
||||
|
||||
+10
@@ -380,6 +380,16 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/box/annotations/instances")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class Instances {
|
||||
@Test
|
||||
public void testAllFilesPresentInInstances() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/annotations/instances"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/box/annotations/kClassMapping")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
|
||||
+10
@@ -25,6 +25,16 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxInline"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/boxInline/annotations")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class Annotations {
|
||||
@Test
|
||||
public void testAllFilesPresentInAnnotations() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxInline/annotations"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/boxInline/anonymousObject")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
|
||||
+12
@@ -316,6 +316,18 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeListing/annotations"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("annotationCtorCallGenerateSynthetic.kt")
|
||||
public void testAnnotationCtorCallGenerateSynthetic() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeListing/annotations/annotationCtorCallGenerateSynthetic.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("annotationCtorCallNoSynthetic.kt")
|
||||
public void testAnnotationCtorCallNoSynthetic() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeListing/annotations/annotationCtorCallNoSynthetic.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("annotationsOnDelegatedMembers.kt")
|
||||
public void testAnnotationsOnDelegatedMembers() throws Exception {
|
||||
|
||||
+10
@@ -25,6 +25,16 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxInline"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/boxInline/annotations")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class Annotations {
|
||||
@Test
|
||||
public void testAllFilesPresentInAnnotations() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxInline/annotations"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/boxInline/anonymousObject")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
|
||||
+70
@@ -380,6 +380,76 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/box/annotations/instances")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class Instances {
|
||||
@Test
|
||||
public void testAllFilesPresentInInstances() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/annotations/instances"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("annotationEnclosingName.kt")
|
||||
public void testAnnotationEnclosingName() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/annotationEnclosingName.kt");
|
||||
}
|
||||
|
||||
@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("annotationType.kt")
|
||||
public void testAnnotationType() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/annotationType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("javaAnnotation.kt")
|
||||
public void testJavaAnnotation() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/javaAnnotation.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("multifileEqHc.kt")
|
||||
public void testMultifileEqHc() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/multifileEqHc.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("multimoduleInlining.kt")
|
||||
public void testMultimoduleInlining() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/multimoduleInlining.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("multiplatformInstantiation.kt")
|
||||
public void testMultiplatformInstantiation() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/multiplatformInstantiation.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/box/annotations/kClassMapping")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
|
||||
+22
@@ -25,6 +25,28 @@ public class IrBlackBoxInlineCodegenTestGenerated extends AbstractIrBlackBoxInli
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxInline"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/boxInline/annotations")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class Annotations {
|
||||
@Test
|
||||
public void testAllFilesPresentInAnnotations() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxInline/annotations"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_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
|
||||
@TestMetadata("compiler/testData/codegen/boxInline/anonymousObject")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
|
||||
+12
@@ -316,6 +316,18 @@ public class IrBytecodeListingTestGenerated extends AbstractIrBytecodeListingTes
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeListing/annotations"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("annotationCtorCallGenerateSynthetic.kt")
|
||||
public void testAnnotationCtorCallGenerateSynthetic() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeListing/annotations/annotationCtorCallGenerateSynthetic.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("annotationCtorCallNoSynthetic.kt")
|
||||
public void testAnnotationCtorCallNoSynthetic() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeListing/annotations/annotationCtorCallNoSynthetic.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("annotationsOnDelegatedMembers.kt")
|
||||
public void testAnnotationsOnDelegatedMembers() throws Exception {
|
||||
|
||||
+22
@@ -25,6 +25,28 @@ public class IrCompileKotlinAgainstInlineKotlinTestGenerated extends AbstractIrC
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxInline"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/boxInline/annotations")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class Annotations {
|
||||
@Test
|
||||
public void testAllFilesPresentInAnnotations() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxInline/annotations"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_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
|
||||
@TestMetadata("compiler/testData/codegen/boxInline/anonymousObject")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
|
||||
+22
@@ -25,6 +25,28 @@ public class JvmIrAgainstOldBoxInlineTestGenerated extends AbstractJvmIrAgainstO
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxInline"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_MULTI_MODULE_IR_AGAINST_OLD, true);
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/boxInline/annotations")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class Annotations {
|
||||
@Test
|
||||
public void testAllFilesPresentInAnnotations() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxInline/annotations"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_MULTI_MODULE_IR_AGAINST_OLD, 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
|
||||
@TestMetadata("compiler/testData/codegen/boxInline/anonymousObject")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
|
||||
+10
@@ -25,6 +25,16 @@ public class JvmOldAgainstIrBoxInlineTestGenerated extends AbstractJvmOldAgainst
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxInline"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_MULTI_MODULE_OLD_AGAINST_IR, true);
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/boxInline/annotations")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class Annotations {
|
||||
@Test
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/boxInline/anonymousObject")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
|
||||
+13
@@ -335,6 +335,19 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/annotations/instances")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Instances extends AbstractLightAnalysisModeTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInInstances() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/annotations/instances"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/annotations/kClassMapping")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@@ -220,6 +220,8 @@ enum class LanguageFeature(
|
||||
|
||||
ProhibitNonExhaustiveWhenOnAlgebraicTypes(KOTLIN_1_7, kind = BUG_FIX),
|
||||
|
||||
InstantiationOfAnnotationClasses(KOTLIN_1_6),
|
||||
|
||||
// Temporarily disabled, see KT-27084/KT-22379
|
||||
SoundSmartcastFromLoopConditionForLoopAssignedVariables(sinceVersion = null, kind = BUG_FIX),
|
||||
|
||||
|
||||
+6
@@ -1103,6 +1103,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
|
||||
runTest("compiler/testData/diagnostics/tests/annotations/ConstructorCall.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("ConstructorCallAllowed.kt")
|
||||
public void testConstructorCallAllowed() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/annotations/ConstructorCallAllowed.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("DanglingMixed.kt")
|
||||
public void testDanglingMixed() throws Exception {
|
||||
|
||||
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.js.analyze.JsNativeDiagnosticSuppressor
|
||||
import org.jetbrains.kotlin.js.naming.NameSuggestion
|
||||
import org.jetbrains.kotlin.js.resolve.diagnostics.*
|
||||
import org.jetbrains.kotlin.resolve.PlatformConfiguratorBase
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.InstantiationOfAnnotationClassesCallChecker
|
||||
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker
|
||||
import org.jetbrains.kotlin.resolve.deprecation.CoroutineCompatibilitySupport
|
||||
import org.jetbrains.kotlin.types.DynamicTypesAllowed
|
||||
@@ -29,9 +30,10 @@ object JsPlatformConfigurator : PlatformConfiguratorBase(
|
||||
JsExportDeclarationChecker
|
||||
),
|
||||
additionalCallCheckers = listOf(
|
||||
JsModuleCallChecker,
|
||||
JsDynamicCallChecker,
|
||||
JsDefinedExternallyCallChecker,
|
||||
JsModuleCallChecker,
|
||||
JsDynamicCallChecker,
|
||||
JsDefinedExternallyCallChecker,
|
||||
InstantiationOfAnnotationClassesCallChecker
|
||||
),
|
||||
identifierChecker = JsIdentifierChecker
|
||||
) {
|
||||
|
||||
js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java
Generated
+13
@@ -80,6 +80,19 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/annotations/instances")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Instances extends AbstractIrJsCodegenBoxES6Test {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR_ES6, testDataFilePath);
|
||||
}
|
||||
|
||||
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("compiler/testData/codegen/box/annotations/kClassMapping")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
+13
@@ -30,6 +30,19 @@ public class IrJsCodegenInlineES6TestGenerated extends AbstractIrJsCodegenInline
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxInline"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxInline/annotations")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Annotations extends AbstractIrJsCodegenInlineES6Test {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR_ES6, testDataFilePath);
|
||||
}
|
||||
|
||||
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("compiler/testData/codegen/boxInline/anonymousObject")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
Generated
+13
@@ -80,6 +80,19 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/annotations/instances")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Instances extends AbstractIrJsCodegenBoxTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath);
|
||||
}
|
||||
|
||||
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("compiler/testData/codegen/box/annotations/kClassMapping")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
Generated
+13
@@ -30,6 +30,19 @@ public class IrJsCodegenInlineTestGenerated extends AbstractIrJsCodegenInlineTes
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxInline"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxInline/annotations")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Annotations extends AbstractIrJsCodegenInlineTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath);
|
||||
}
|
||||
|
||||
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("compiler/testData/codegen/boxInline/anonymousObject")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
Generated
+13
@@ -80,6 +80,19 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/annotations/instances")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Instances extends AbstractJsCodegenBoxTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath);
|
||||
}
|
||||
|
||||
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("compiler/testData/codegen/box/annotations/kClassMapping")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
Generated
+13
@@ -30,6 +30,19 @@ public class JsCodegenInlineTestGenerated extends AbstractJsCodegenInlineTest {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxInline"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true);
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxInline/annotations")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Annotations extends AbstractJsCodegenInlineTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInAnnotations() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxInline/annotations"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxInline/anonymousObject")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java
Generated
+13
@@ -75,6 +75,19 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/annotations/instances")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Instances extends AbstractIrCodegenBoxWasmTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest0(this::doTest, TargetBackend.WASM, testDataFilePath);
|
||||
}
|
||||
|
||||
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("compiler/testData/codegen/box/annotations/kClassMapping")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
+2
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtCallableDeclaration
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.PlatformConfiguratorBase
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.InstantiationOfAnnotationClassesCallChecker
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.TypeOfChecker
|
||||
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker
|
||||
import org.jetbrains.kotlin.resolve.inline.ReasonableInlineRule
|
||||
@@ -25,6 +26,7 @@ import org.jetbrains.kotlin.resolve.konan.diagnostics.NativeTopLevelSingletonChe
|
||||
object NativePlatformConfigurator : PlatformConfiguratorBase(
|
||||
additionalCallCheckers = listOf(
|
||||
SuperCallWithDefaultArgumentsChecker(),
|
||||
InstantiationOfAnnotationClassesCallChecker
|
||||
),
|
||||
additionalDeclarationCheckers = listOf(
|
||||
NativeThrowsChecker, NativeSharedImmutableChecker,
|
||||
|
||||
Reference in New Issue
Block a user