From 2ed0cb2a89bcc552ef7ea25a82b68069feeeb24b Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Mon, 30 Dec 2019 09:12:28 +0100 Subject: [PATCH] Support type annotations #KT-35843 Fixed --- .../kotlin/codegen/AnnotationCodegen.java | 35 ++++++++ .../kotlin/codegen/FunctionCodegen.java | 15 +++- .../kotlin/codegen/typeAnnotationCollector.kt | 90 +++++++++++++++++++ .../arguments/K2JVMCompilerArguments.kt | 6 ++ .../jetbrains/kotlin/cli/jvm/jvmArguments.kt | 1 + .../kotlin/config/JVMConfigurationKeys.java | 3 + compiler/testData/cli/jvm/extraHelp.out | 1 + .../asmLike/typeAnnotations/complex.kt | 51 +++++++++++ .../asmLike/typeAnnotations/complex.txt | 60 +++++++++++++ .../asmLike/typeAnnotations/constructor.kt | 18 ++++ .../asmLike/typeAnnotations/constructor.txt | 28 ++++++ .../asmLike/typeAnnotations/defaultArgs.kt | 17 ++++ .../asmLike/typeAnnotations/defaultArgs.txt | 14 +++ .../typeAnnotations/enumClassConstructor.kt | 16 ++++ .../typeAnnotations/enumClassConstructor.txt | 26 ++++++ .../asmLike/typeAnnotations/extension.kt | 15 ++++ .../asmLike/typeAnnotations/extension.txt | 11 +++ .../asmLike/typeAnnotations/implicit.kt | 29 ++++++ .../asmLike/typeAnnotations/implicit.txt | 39 ++++++++ .../typeAnnotations/innerClassConstructor.kt | 13 +++ .../typeAnnotations/innerClassConstructor.txt | 14 +++ .../asmLike/typeAnnotations/jvmOverload.kt | 17 ++++ .../asmLike/typeAnnotations/jvmOverload.txt | 21 +++++ .../asmLike/typeAnnotations/jvmStatic.kt | 28 ++++++ .../asmLike/typeAnnotations/jvmStatic.txt | 40 +++++++++ .../typeAnnotations/notYetSupported.kt | 57 ++++++++++++ .../typeAnnotations/notYetSupported.txt | 55 ++++++++++++ .../asmLike/typeAnnotations/property.kt | 43 +++++++++ .../codegen/asmLike/typeAnnotations/simple.kt | 39 ++++++++ .../asmLike/typeAnnotations/simple.txt | 43 +++++++++ .../asmLike/typeAnnotations/simple2Params.kt | 20 +++++ .../asmLike/typeAnnotations/simple2Params.txt | 15 ++++ .../asmLike/typeAnnotations/staticNested.kt | 57 ++++++++++++ .../asmLike/typeAnnotations/staticNested.txt | 61 +++++++++++++ .../typeAnnotations/implicitReturn.kt | 76 ++++++++++++++++ .../typeAnnotations/methodParameters.kt | 57 ++++++++++++ .../typeAnnotations/typeUseAnnotation.kt | 65 ++++++++++++++ .../typeAnnotations/implicitReturn.kt | 76 ++++++++++++++++ .../typeAnnotations/implicitReturn.kt | 66 ++++++++++++++ .../typeAnnotations/typeAnnotationTarget6.kt | 60 +++++++++++++ .../AbstractAsmLikeInstructionListingTest.kt | 42 +++++++-- ...smLikeInstructionListingTestGenerated.java | 78 ++++++++++++++++ ...ackBoxAgainstJavaCodegenTestGenerated.java | 18 ++++ .../codegen/BlackBoxCodegenTestGenerated.java | 28 ++++++ ...mpileKotlinAgainstKotlinTestGenerated.java | 23 +++++ .../LightAnalysisModeTestGenerated.java | 28 ++++++ .../ir/FirBlackBoxCodegenTestGenerated.java | 28 ++++++ ...ackBoxAgainstJavaCodegenTestGenerated.java | 18 ++++ .../ir/IrBlackBoxCodegenTestGenerated.java | 28 ++++++ ...mpileKotlinAgainstKotlinTestGenerated.java | 23 +++++ .../IrJsCodegenBoxTestGenerated.java | 13 +++ .../semantics/JsCodegenBoxTestGenerated.java | 13 +++ 52 files changed, 1728 insertions(+), 10 deletions(-) create mode 100644 compiler/backend/src/org/jetbrains/kotlin/codegen/typeAnnotationCollector.kt create mode 100644 compiler/testData/codegen/asmLike/typeAnnotations/complex.kt create mode 100644 compiler/testData/codegen/asmLike/typeAnnotations/complex.txt create mode 100644 compiler/testData/codegen/asmLike/typeAnnotations/constructor.kt create mode 100644 compiler/testData/codegen/asmLike/typeAnnotations/constructor.txt create mode 100644 compiler/testData/codegen/asmLike/typeAnnotations/defaultArgs.kt create mode 100644 compiler/testData/codegen/asmLike/typeAnnotations/defaultArgs.txt create mode 100644 compiler/testData/codegen/asmLike/typeAnnotations/enumClassConstructor.kt create mode 100644 compiler/testData/codegen/asmLike/typeAnnotations/enumClassConstructor.txt create mode 100644 compiler/testData/codegen/asmLike/typeAnnotations/extension.kt create mode 100644 compiler/testData/codegen/asmLike/typeAnnotations/extension.txt create mode 100644 compiler/testData/codegen/asmLike/typeAnnotations/implicit.kt create mode 100644 compiler/testData/codegen/asmLike/typeAnnotations/implicit.txt create mode 100644 compiler/testData/codegen/asmLike/typeAnnotations/innerClassConstructor.kt create mode 100644 compiler/testData/codegen/asmLike/typeAnnotations/innerClassConstructor.txt create mode 100644 compiler/testData/codegen/asmLike/typeAnnotations/jvmOverload.kt create mode 100644 compiler/testData/codegen/asmLike/typeAnnotations/jvmOverload.txt create mode 100644 compiler/testData/codegen/asmLike/typeAnnotations/jvmStatic.kt create mode 100644 compiler/testData/codegen/asmLike/typeAnnotations/jvmStatic.txt create mode 100644 compiler/testData/codegen/asmLike/typeAnnotations/notYetSupported.kt create mode 100644 compiler/testData/codegen/asmLike/typeAnnotations/notYetSupported.txt create mode 100644 compiler/testData/codegen/asmLike/typeAnnotations/property.kt create mode 100644 compiler/testData/codegen/asmLike/typeAnnotations/simple.kt create mode 100644 compiler/testData/codegen/asmLike/typeAnnotations/simple.txt create mode 100644 compiler/testData/codegen/asmLike/typeAnnotations/simple2Params.kt create mode 100644 compiler/testData/codegen/asmLike/typeAnnotations/simple2Params.txt create mode 100644 compiler/testData/codegen/asmLike/typeAnnotations/staticNested.kt create mode 100644 compiler/testData/codegen/asmLike/typeAnnotations/staticNested.txt create mode 100644 compiler/testData/codegen/box/annotations/typeAnnotations/implicitReturn.kt create mode 100644 compiler/testData/codegen/box/annotations/typeAnnotations/methodParameters.kt create mode 100644 compiler/testData/codegen/box/annotations/typeAnnotations/typeUseAnnotation.kt create mode 100644 compiler/testData/codegen/boxAgainstJava/annotations/typeAnnotations/implicitReturn.kt create mode 100644 compiler/testData/compileKotlinAgainstKotlin/typeAnnotations/implicitReturn.kt create mode 100644 compiler/testData/compileKotlinAgainstKotlin/typeAnnotations/typeAnnotationTarget6.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/AnnotationCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/AnnotationCodegen.java index 91370848e2a..1eea550db0d 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/AnnotationCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/AnnotationCodegen.java @@ -21,6 +21,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper; +import org.jetbrains.kotlin.config.JVMConfigurationKeys; import org.jetbrains.kotlin.config.JvmTarget; import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.annotations.*; @@ -627,4 +628,38 @@ public abstract class AnnotationCodegen { private static AnnotationVisitor safe(@Nullable AnnotationVisitor av) { return av == null ? NO_ANNOTATION_VISITOR : av; } + + public static void writeTypeAnnotations( + @NotNull MethodVisitor mv, + @NotNull GenerationState state, + int parameterIndex, + @Nullable KotlinType type, + @NotNull InnerClassConsumer innerClassConsumer + ) { + if (type == null || + state.getTarget() == JvmTarget.JVM_1_6 || + !state.getConfiguration().getBoolean(JVMConfigurationKeys.EMIT_JVM_TYPE_ANNOTATIONS)) { + return; + } + + Iterable infos = + new TypeAnnotationCollector().collectTypeAnnotations(type, TypeReference.METHOD_FORMAL_PARAMETER); + for (TypePathInfo info : infos) { + for (AnnotationDescriptor annotationDescriptor : info.getAnnotations()) { + TypeReference typeReference = parameterIndex != -1 ? + TypeReference.newFormalParameterReference(parameterIndex) + : TypeReference.newTypeReference(TypeReference.METHOD_RETURN); + + AnnotationCodegen codegen = new AnnotationCodegen(innerClassConsumer, state) { + @NotNull + @Override + AnnotationVisitor visitAnnotation(String descr, boolean visible) { + return safe(mv.visitTypeAnnotation(typeReference.getValue(), info.getPath(), descr, visible)); + } + }; + codegen.genAnnotation(annotationDescriptor); + } + } + } + } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java index fa613bd2036..145aa264a9e 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java @@ -26,7 +26,6 @@ import org.jetbrains.kotlin.codegen.state.TypeMapperUtilsKt; import org.jetbrains.kotlin.config.JvmDefaultMode; import org.jetbrains.kotlin.config.LanguageFeature; import org.jetbrains.kotlin.descriptors.*; -import org.jetbrains.kotlin.descriptors.annotations.Annotated; import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor; import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature; @@ -56,7 +55,10 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature; import org.jetbrains.kotlin.types.KotlinType; import org.jetbrains.kotlin.types.TypeUtils; -import org.jetbrains.org.objectweb.asm.*; +import org.jetbrains.org.objectweb.asm.Label; +import org.jetbrains.org.objectweb.asm.MethodVisitor; +import org.jetbrains.org.objectweb.asm.Opcodes; +import org.jetbrains.org.objectweb.asm.Type; import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter; import org.jetbrains.org.objectweb.asm.commons.Method; import org.jetbrains.org.objectweb.asm.util.TraceMethodVisitor; @@ -531,7 +533,7 @@ public class FunctionCodegen { continue; } - Annotated annotated = + ParameterDescriptor annotated = kind == JvmMethodParameterKind.VALUE ? iterator.next() : kind == JvmMethodParameterKind.RECEIVER @@ -540,10 +542,15 @@ public class FunctionCodegen { if (annotated != null) { //noinspection ConstantConditions - AnnotationCodegen.forParameter(i - syntheticParameterCount, mv, innerClassConsumer, state) + int parameterIndex = i - syntheticParameterCount; + AnnotationCodegen.forParameter(parameterIndex, mv, innerClassConsumer, state) .genAnnotations(annotated, parameterSignature.getAsmType()); + + AnnotationCodegen.writeTypeAnnotations(mv, state, parameterIndex, annotated.getType(), innerClassConsumer); } } + + AnnotationCodegen.writeTypeAnnotations(mv, state, -1, functionDescriptor.getReturnType(), innerClassConsumer); } @Nullable diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/typeAnnotationCollector.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/typeAnnotationCollector.kt new file mode 100644 index 00000000000..4986b3777d0 --- /dev/null +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/typeAnnotationCollector.kt @@ -0,0 +1,90 @@ +/* + * Copyright 2010-2019 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.codegen + +import org.jetbrains.kotlin.builtins.KotlinBuiltIns +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor +import org.jetbrains.kotlin.load.kotlin.FileBasedKotlinClass +import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement +import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass +import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor +import org.jetbrains.kotlin.types.* +import org.jetbrains.org.objectweb.asm.Opcodes +import org.jetbrains.org.objectweb.asm.TypePath + + +class TypePathInfo( + val path: TypePath?, + val annotations: List +) + +private class State(val type: Int, val path: MutableList) { + + val results = arrayListOf() + + + fun addStep(step: String) { + path.add(step) + } + + fun removeStep(step: String) { + path.removeAt(path.lastIndex) + } + + fun rememberAnnotations(annotations: List) { + results.add(TypePathInfo(TypePath.fromString(path.joinToString("")), annotations)) + } +} + +class TypeAnnotationCollector { + + private lateinit var state: State + + fun collectTypeAnnotations(kotlinType: KotlinType, annotationType: Int): ArrayList { + state = State(annotationType, arrayListOf()) + kotlinType.collectTypeAnnotations() + return state.results + } + + private fun KotlinType.collectTypeAnnotations() { + if (isFlexible()) { + return upperIfFlexible().collectTypeAnnotations() + } else if ((this.constructor.declarationDescriptor as? ClassDescriptor)?.isInner == true) { + //skip inner classes for now it's not clear should type annotations on outer be supported or not + return + } + + typeAnnotations.takeIf { it.isNotEmpty() }?.let { state.rememberAnnotations(it) } + + arguments.forEachIndexed { index, type -> + //skip in/out variance for now it's not clear should type annotations on wildcard bound be supported or not + if (type.projectionKind == Variance.INVARIANT) { + when { + KotlinBuiltIns.isArray(this) -> type.type.process("[") + else -> type.type.process("$index;") + } + } + } + } + + fun KotlinType.process(step: String) { + state.addStep(step) + this.collectTypeAnnotations() + state.removeStep(step) + } + + + private val KotlinType.typeAnnotations + get() = annotations.filter { + //We only generate annotations which have the TYPE_USE Java target. + // Those are type annotations which were compiled with JVM target bytecode version 1.8 or greater + (it.annotationClass as? DeserializedClassDescriptor)?.let { classDescriptor -> + ((classDescriptor.source as? KotlinJvmBinarySourceElement)?.binaryClass as? FileBasedKotlinClass)?.classVersion ?: 0 >= Opcodes.V1_8 + } ?: true + } + +} \ No newline at end of file diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt index ce00755c54c..3b65dd5d8de 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt @@ -289,6 +289,12 @@ class K2JVMCompilerArguments : CommonCompilerArguments() { ) var allowNoSourceFiles: Boolean by FreezableVar(false) + @Argument( + value = "-Xemit-jvm-type-annotations", + description = "Emit JVM type annotations in bytecode" + ) + var emitJvmTypeAnnotations: Boolean by FreezableVar(false) + override fun configureAnalysisFlags(collector: MessageCollector): MutableMap, Any> { val result = super.configureAnalysisFlags(collector) result[JvmAnalysisFlags.strictMetadataVersionSemantics] = strictMetadataVersionSemantics diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/jvmArguments.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/jvmArguments.kt index fd02751d1a8..1d28c390189 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/jvmArguments.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/jvmArguments.kt @@ -152,6 +152,7 @@ fun CompilerConfiguration.configureAdvancedJvmOptions(arguments: K2JVMCompilerAr arguments.noExceptionOnExplicitEqualsForBoxedNull ) put(JVMConfigurationKeys.DISABLE_OPTIMIZATION, arguments.noOptimize) + put(JVMConfigurationKeys.EMIT_JVM_TYPE_ANNOTATIONS, arguments.emitJvmTypeAnnotations) if (!JVMConstructorCallNormalizationMode.isSupportedValue(arguments.constructorCallNormalizationMode)) { getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY).report( diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/config/JVMConfigurationKeys.java b/compiler/frontend.java/src/org/jetbrains/kotlin/config/JVMConfigurationKeys.java index b6535749ddd..593cb7d85f9 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/config/JVMConfigurationKeys.java +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/config/JVMConfigurationKeys.java @@ -110,4 +110,7 @@ public class JVMConfigurationKeys { public static final CompilerConfigurationKey ENABLE_JVM_DEFAULT = CompilerConfigurationKey.create("Allow to use '@JvmDefault'"); + + public static final CompilerConfigurationKey EMIT_JVM_TYPE_ANNOTATIONS = + CompilerConfigurationKey.create("Emit JVM type annotations in bytecode"); } diff --git a/compiler/testData/cli/jvm/extraHelp.out b/compiler/testData/cli/jvm/extraHelp.out index 7f06790b607..2ee559c9a9e 100644 --- a/compiler/testData/cli/jvm/extraHelp.out +++ b/compiler/testData/cli/jvm/extraHelp.out @@ -18,6 +18,7 @@ where advanced options include: 'enable' since language version 1.3 -Xdump-declarations-to= Path to JSON file to dump Java to Kotlin declaration mappings -Xdisable-standard-script Disable standard kotlin script support + -Xemit-jvm-type-annotations Emit JVM type annotations in bytecode -Xexpression Evaluate the given string as a Kotlin script -Xfriend-paths= Paths to output directories for friend modules (whose internals should be visible) -Xmultifile-parts-inherit Compile multifile classes as a hierarchy of parts and facade diff --git a/compiler/testData/codegen/asmLike/typeAnnotations/complex.kt b/compiler/testData/codegen/asmLike/typeAnnotations/complex.kt new file mode 100644 index 00000000000..185ca53c651 --- /dev/null +++ b/compiler/testData/codegen/asmLike/typeAnnotations/complex.kt @@ -0,0 +1,51 @@ +// KOTLIN_CONFIGURATION_FLAGS: +JVM.EMIT_JVM_TYPE_ANNOTATIONS +// TYPE_ANNOTATIONS +// IGNORE_BACKEND_FIR: JVM_IR +// TARGET_BACKEND: JVM +// JVM_TARGET: 1.8 +package foo + +@Target(AnnotationTarget.TYPE) +annotation class Ann + +@Target(AnnotationTarget.TYPE) +annotation class Ann2 + +@Target(AnnotationTarget.TYPE) +annotation class Ann3 + +@Target(AnnotationTarget.TYPE) +annotation class Ann4 + +class Bar + +class Kotlin { + + fun foo(s: @Ann Bar<@Ann2 String>) { + } + + fun foo(): @Ann Bar<@Ann2 String>? { + return null + } + + fun fooArray(s: @Ann Array<@Ann2 Bar<@Ann3 String>>) { + } + + fun fooArray(): @Ann Array<@Ann2 Bar<@Ann3 String>>? { + return null + } + + fun fooArrayArray(s: @Ann Array<@Ann2 Array<@Ann3 Bar<@Ann4 String>>>) { + } + + fun fooArrayArray(): @Ann Array<@Ann2 Array<@Ann3 Bar<@Ann4 String>>>? { + return null + } + + + fun foo(s: @Ann T) { + } + + fun fooGeneric(s: @Ann Bar<@Ann2 T>) { + } +} diff --git a/compiler/testData/codegen/asmLike/typeAnnotations/complex.txt b/compiler/testData/codegen/asmLike/typeAnnotations/complex.txt new file mode 100644 index 00000000000..49ec8e22f4a --- /dev/null +++ b/compiler/testData/codegen/asmLike/typeAnnotations/complex.txt @@ -0,0 +1,60 @@ +public abstract interface foo/Ann : java/lang/Object, java/lang/annotation/Annotation { + +} + +public abstract interface foo/Ann2 : java/lang/Object, java/lang/annotation/Annotation { + +} + +public abstract interface foo/Ann3 : java/lang/Object, java/lang/annotation/Annotation { + +} + +public abstract interface foo/Ann4 : java/lang/Object, java/lang/annotation/Annotation { + +} + +public final class foo/Bar : java/lang/Object { + public void () +} + +public final class foo/Kotlin : java/lang/Object { + public void () + + public final void foo(foo.Bar s) + @Lfoo/Ann;([]) : METHOD_FORMAL_PARAMETER 0, null + @Lfoo/Ann2;([]) : METHOD_FORMAL_PARAMETER 0, 0; + + public final foo.Bar foo() + @Lfoo/Ann;([]) : METHOD_RETURN, null + @Lfoo/Ann2;([]) : METHOD_RETURN, 0; + + public final void foo(java.lang.Object s) + @Lfoo/Ann;([]) : METHOD_FORMAL_PARAMETER 0, null + + public final void fooArray(foo.Bar[] s) + @Lfoo/Ann;([]) : METHOD_FORMAL_PARAMETER 0, null + @Lfoo/Ann2;([]) : METHOD_FORMAL_PARAMETER 0, [ + @Lfoo/Ann3;([]) : METHOD_FORMAL_PARAMETER 0, [0; + + public final foo.Bar[] fooArray() + @Lfoo/Ann;([]) : METHOD_RETURN, null + @Lfoo/Ann2;([]) : METHOD_RETURN, [ + @Lfoo/Ann3;([]) : METHOD_RETURN, [0; + + public final void fooArrayArray(foo.Bar[][] s) + @Lfoo/Ann;([]) : METHOD_FORMAL_PARAMETER 0, null + @Lfoo/Ann2;([]) : METHOD_FORMAL_PARAMETER 0, [ + @Lfoo/Ann3;([]) : METHOD_FORMAL_PARAMETER 0, [[ + @Lfoo/Ann4;([]) : METHOD_FORMAL_PARAMETER 0, [[0; + + public final foo.Bar[][] fooArrayArray() + @Lfoo/Ann;([]) : METHOD_RETURN, null + @Lfoo/Ann2;([]) : METHOD_RETURN, [ + @Lfoo/Ann3;([]) : METHOD_RETURN, [[ + @Lfoo/Ann4;([]) : METHOD_RETURN, [[0; + + public final void fooGeneric(foo.Bar s) + @Lfoo/Ann;([]) : METHOD_FORMAL_PARAMETER 0, null + @Lfoo/Ann2;([]) : METHOD_FORMAL_PARAMETER 0, 0; +} diff --git a/compiler/testData/codegen/asmLike/typeAnnotations/constructor.kt b/compiler/testData/codegen/asmLike/typeAnnotations/constructor.kt new file mode 100644 index 00000000000..4a2b7d60529 --- /dev/null +++ b/compiler/testData/codegen/asmLike/typeAnnotations/constructor.kt @@ -0,0 +1,18 @@ +// KOTLIN_CONFIGURATION_FLAGS: +JVM.EMIT_JVM_TYPE_ANNOTATIONS +// TYPE_ANNOTATIONS +// IGNORE_BACKEND_FIR: JVM_IR +// TARGET_BACKEND: JVM +// JVM_TARGET: 1.8 +package foo + +@Target(AnnotationTarget.TYPE) +annotation class TypeAnn(val name: String) + +class Kotlin(s: @TypeAnn("1") String, p: @TypeAnn("123") String) { + + private constructor(s: @TypeAnn("private") String) : this("1", "2") + + fun foo() { + { Kotlin("123") }() + } +} diff --git a/compiler/testData/codegen/asmLike/typeAnnotations/constructor.txt b/compiler/testData/codegen/asmLike/typeAnnotations/constructor.txt new file mode 100644 index 00000000000..9adbdf891e4 --- /dev/null +++ b/compiler/testData/codegen/asmLike/typeAnnotations/constructor.txt @@ -0,0 +1,28 @@ +final class foo/Kotlin$foo$1 : kotlin/jvm/internal/Lambda, kotlin/jvm/functions/Function0 { + public final static foo.Kotlin$foo$1 INSTANCE + + static void () + + void () + + public java.lang.Object invoke() + + public final foo.Kotlin invoke() +} + +public final class foo/Kotlin : java/lang/Object { + public void (java.lang.String s, java.lang.String p) + @Lfoo/TypeAnn;([name="1"]) : METHOD_FORMAL_PARAMETER 0, null + @Lfoo/TypeAnn;([name="123"]) : METHOD_FORMAL_PARAMETER 1, null + + private void (java.lang.String s) + @Lfoo/TypeAnn;([name="private"]) : METHOD_FORMAL_PARAMETER 0, null + + public void (java.lang.String s, kotlin.jvm.internal.DefaultConstructorMarker $constructor_marker) + + public final void foo() +} + +public abstract interface foo/TypeAnn : java/lang/Object, java/lang/annotation/Annotation { + public abstract java.lang.String name() +} diff --git a/compiler/testData/codegen/asmLike/typeAnnotations/defaultArgs.kt b/compiler/testData/codegen/asmLike/typeAnnotations/defaultArgs.kt new file mode 100644 index 00000000000..7aa9f258129 --- /dev/null +++ b/compiler/testData/codegen/asmLike/typeAnnotations/defaultArgs.kt @@ -0,0 +1,17 @@ +// KOTLIN_CONFIGURATION_FLAGS: +JVM.EMIT_JVM_TYPE_ANNOTATIONS +// TYPE_ANNOTATIONS +// IGNORE_BACKEND_FIR: JVM_IR +// TARGET_BACKEND: JVM +// JVM_TARGET: 1.8 +package foo + +@Target(AnnotationTarget.TYPE) +annotation class TypeAnn(val name: String) + +class Kotlin { + + fun foo(s: @TypeAnn("1") String = "1", x: @TypeAnn("2") Int = 123): @TypeAnn("return") Any? { + return null + } + +} diff --git a/compiler/testData/codegen/asmLike/typeAnnotations/defaultArgs.txt b/compiler/testData/codegen/asmLike/typeAnnotations/defaultArgs.txt new file mode 100644 index 00000000000..de5c3890fe7 --- /dev/null +++ b/compiler/testData/codegen/asmLike/typeAnnotations/defaultArgs.txt @@ -0,0 +1,14 @@ +public final class foo/Kotlin : java/lang/Object { + public void () + + public final java.lang.Object foo(java.lang.String s, int x) + @Lfoo/TypeAnn;([name="1"]) : METHOD_FORMAL_PARAMETER 0, null + @Lfoo/TypeAnn;([name="2"]) : METHOD_FORMAL_PARAMETER 1, null + @Lfoo/TypeAnn;([name="return"]) : METHOD_RETURN, null + + public static java.lang.Object foo$default(foo.Kotlin p0, java.lang.String p1, int p2, int p3, java.lang.Object p4) +} + +public abstract interface foo/TypeAnn : java/lang/Object, java/lang/annotation/Annotation { + public abstract java.lang.String name() +} \ No newline at end of file diff --git a/compiler/testData/codegen/asmLike/typeAnnotations/enumClassConstructor.kt b/compiler/testData/codegen/asmLike/typeAnnotations/enumClassConstructor.kt new file mode 100644 index 00000000000..f8dbedf4f99 --- /dev/null +++ b/compiler/testData/codegen/asmLike/typeAnnotations/enumClassConstructor.kt @@ -0,0 +1,16 @@ +// KOTLIN_CONFIGURATION_FLAGS: +JVM.EMIT_JVM_TYPE_ANNOTATIONS +// TYPE_ANNOTATIONS +// IGNORE_BACKEND_FIR: JVM_IR +// TARGET_BACKEND: JVM +// JVM_TARGET: 1.8 +package foo + + +@Target(AnnotationTarget.TYPE) +annotation class TypeAnn + +enum class Kotlin (s: @TypeAnn String) { + A("123") { + fun foo() {} + }; +} diff --git a/compiler/testData/codegen/asmLike/typeAnnotations/enumClassConstructor.txt b/compiler/testData/codegen/asmLike/typeAnnotations/enumClassConstructor.txt new file mode 100644 index 00000000000..7e9da6e1a59 --- /dev/null +++ b/compiler/testData/codegen/asmLike/typeAnnotations/enumClassConstructor.txt @@ -0,0 +1,26 @@ +final class foo/Kotlin$A : foo/Kotlin { + void (java.lang.String $enum_name_or_ordinal$0, int $enum_name_or_ordinal$1) + + public final void foo() +} + +public class foo/Kotlin : java/lang/Enum { + private final static foo.Kotlin[] $VALUES + + public final static foo.Kotlin A + + static void () + + private void (java.lang.String $enum_name_or_ordinal$0, int $enum_name_or_ordinal$1, java.lang.String s) + @Lfoo/TypeAnn;([]) : METHOD_FORMAL_PARAMETER 0, null + + public void (java.lang.String $enum_name_or_ordinal$0, int $enum_name_or_ordinal$1, java.lang.String s, kotlin.jvm.internal.DefaultConstructorMarker $constructor_marker) + + public static foo.Kotlin valueOf(java.lang.String p0) + + public static foo.Kotlin[] values() +} + +public abstract interface foo/TypeAnn : java/lang/Object, java/lang/annotation/Annotation { + +} \ No newline at end of file diff --git a/compiler/testData/codegen/asmLike/typeAnnotations/extension.kt b/compiler/testData/codegen/asmLike/typeAnnotations/extension.kt new file mode 100644 index 00000000000..398f6e8bd1f --- /dev/null +++ b/compiler/testData/codegen/asmLike/typeAnnotations/extension.kt @@ -0,0 +1,15 @@ +// KOTLIN_CONFIGURATION_FLAGS: +JVM.EMIT_JVM_TYPE_ANNOTATIONS +// TYPE_ANNOTATIONS +// IGNORE_BACKEND_FIR: JVM_IR +// TARGET_BACKEND: JVM +// JVM_TARGET: 1.8 +package foo + +@Target(AnnotationTarget.TYPE) +annotation class TypeAnn(val name: String) + +class Kotlin { + + fun @TypeAnn("ext") String.foo2(s: @TypeAnn("param") String) { + } +} diff --git a/compiler/testData/codegen/asmLike/typeAnnotations/extension.txt b/compiler/testData/codegen/asmLike/typeAnnotations/extension.txt new file mode 100644 index 00000000000..88fa86fc73c --- /dev/null +++ b/compiler/testData/codegen/asmLike/typeAnnotations/extension.txt @@ -0,0 +1,11 @@ +public final class foo/Kotlin : java/lang/Object { + public void () + + public final void foo2(java.lang.String $this$foo2, java.lang.String s) + @Lfoo/TypeAnn;([name="ext"]) : METHOD_FORMAL_PARAMETER 0, null + @Lfoo/TypeAnn;([name="param"]) : METHOD_FORMAL_PARAMETER 1, null +} + +public abstract interface foo/TypeAnn : java/lang/Object, java/lang/annotation/Annotation { + public abstract java.lang.String name() +} diff --git a/compiler/testData/codegen/asmLike/typeAnnotations/implicit.kt b/compiler/testData/codegen/asmLike/typeAnnotations/implicit.kt new file mode 100644 index 00000000000..2f93862676a --- /dev/null +++ b/compiler/testData/codegen/asmLike/typeAnnotations/implicit.kt @@ -0,0 +1,29 @@ +// KOTLIN_CONFIGURATION_FLAGS: +JVM.EMIT_JVM_TYPE_ANNOTATIONS +// TYPE_ANNOTATIONS +// IGNORE_BACKEND_FIR: JVM_IR +// TARGET_BACKEND: JVM +// JVM_TARGET: 1.8 +package foo + +@Target(AnnotationTarget.TYPE) +annotation class TypeAnn(val name: String) + +@Target(AnnotationTarget.TYPE) +@Retention(AnnotationRetention.BINARY) +annotation class TypeAnnBinary + +@Target(AnnotationTarget.TYPE) +@Retention(AnnotationRetention.SOURCE) +annotation class TypeAnnSource + +class Kotlin { + + fun foo2(): @TypeAnn("2") @TypeAnnBinary @TypeAnnSource String { + return "OK" + } + + fun foo3() = foo2() + + fun foo4() = { foo2() }() + +} diff --git a/compiler/testData/codegen/asmLike/typeAnnotations/implicit.txt b/compiler/testData/codegen/asmLike/typeAnnotations/implicit.txt new file mode 100644 index 00000000000..ed0bb275d32 --- /dev/null +++ b/compiler/testData/codegen/asmLike/typeAnnotations/implicit.txt @@ -0,0 +1,39 @@ +final class foo/Kotlin$foo4$1 : kotlin/jvm/internal/Lambda, kotlin/jvm/functions/Function0 { + final foo.Kotlin this$0 + + void (foo.Kotlin p0) + + public java.lang.Object invoke() + + public final java.lang.String invoke() + @Lfoo/TypeAnn;([name="2"]) : METHOD_RETURN, null + @Lfoo/TypeAnnBinary;([]) : METHOD_RETURN, null // invisible +} + +public final class foo/Kotlin : java/lang/Object { + public void () + + public final java.lang.String foo2() + @Lfoo/TypeAnn;([name="2"]) : METHOD_RETURN, null + @Lfoo/TypeAnnBinary;([]) : METHOD_RETURN, null // invisible + + public final java.lang.String foo3() + @Lfoo/TypeAnn;([name="2"]) : METHOD_RETURN, null + @Lfoo/TypeAnnBinary;([]) : METHOD_RETURN, null // invisible + + public final java.lang.String foo4() + @Lfoo/TypeAnn;([name="2"]) : METHOD_RETURN, null + @Lfoo/TypeAnnBinary;([]) : METHOD_RETURN, null // invisible +} + +public abstract interface foo/TypeAnn : java/lang/Object, java/lang/annotation/Annotation { + public abstract java.lang.String name() +} + +public abstract interface foo/TypeAnnBinary : java/lang/Object, java/lang/annotation/Annotation { + +} + +public abstract interface foo/TypeAnnSource : java/lang/Object, java/lang/annotation/Annotation { + +} diff --git a/compiler/testData/codegen/asmLike/typeAnnotations/innerClassConstructor.kt b/compiler/testData/codegen/asmLike/typeAnnotations/innerClassConstructor.kt new file mode 100644 index 00000000000..b73432d5186 --- /dev/null +++ b/compiler/testData/codegen/asmLike/typeAnnotations/innerClassConstructor.kt @@ -0,0 +1,13 @@ +// KOTLIN_CONFIGURATION_FLAGS: +JVM.EMIT_JVM_TYPE_ANNOTATIONS +// TYPE_ANNOTATIONS +// IGNORE_BACKEND_FIR: JVM_IR +// TARGET_BACKEND: JVM +// JVM_TARGET: 1.8 +package foo + +@Target(AnnotationTarget.TYPE) +annotation class TypeAnn + +class Kotlin { + inner class Inner(s: @TypeAnn String) {} +} \ No newline at end of file diff --git a/compiler/testData/codegen/asmLike/typeAnnotations/innerClassConstructor.txt b/compiler/testData/codegen/asmLike/typeAnnotations/innerClassConstructor.txt new file mode 100644 index 00000000000..4681f7630c6 --- /dev/null +++ b/compiler/testData/codegen/asmLike/typeAnnotations/innerClassConstructor.txt @@ -0,0 +1,14 @@ +public final class foo/Kotlin$Inner : java/lang/Object { + final foo.Kotlin this$0 + + public void (foo.Kotlin $outer, java.lang.String s) + @Lfoo/TypeAnn;([]) : METHOD_FORMAL_PARAMETER 0, null +} + +public final class foo/Kotlin : java/lang/Object { + public void () +} + +public abstract interface foo/TypeAnn : java/lang/Object, java/lang/annotation/Annotation { + +} diff --git a/compiler/testData/codegen/asmLike/typeAnnotations/jvmOverload.kt b/compiler/testData/codegen/asmLike/typeAnnotations/jvmOverload.kt new file mode 100644 index 00000000000..91dd5d47c69 --- /dev/null +++ b/compiler/testData/codegen/asmLike/typeAnnotations/jvmOverload.kt @@ -0,0 +1,17 @@ +// KOTLIN_CONFIGURATION_FLAGS: +JVM.EMIT_JVM_TYPE_ANNOTATIONS +// TYPE_ANNOTATIONS +// IGNORE_BACKEND_FIR: JVM_IR +// TARGET_BACKEND: JVM +// JVM_TARGET: 1.8 +// WITH_RUNTIME +package foo + +@Target(AnnotationTarget.TYPE) +annotation class TypeAnn(val name: String) + +class FooClass { + @JvmOverloads + fun foo(s: @TypeAnn("1") String = "1", x: @TypeAnn("2") Int = 123) : @TypeAnn("return") Any? { + return null + } +} diff --git a/compiler/testData/codegen/asmLike/typeAnnotations/jvmOverload.txt b/compiler/testData/codegen/asmLike/typeAnnotations/jvmOverload.txt new file mode 100644 index 00000000000..bc8ab3762bd --- /dev/null +++ b/compiler/testData/codegen/asmLike/typeAnnotations/jvmOverload.txt @@ -0,0 +1,21 @@ +public final class foo/FooClass : java/lang/Object { + public void () + + public final java.lang.Object foo(java.lang.String s, int x) + @Lfoo/TypeAnn;([name="1"]) : METHOD_FORMAL_PARAMETER 0, null + @Lfoo/TypeAnn;([name="2"]) : METHOD_FORMAL_PARAMETER 1, null + @Lfoo/TypeAnn;([name="return"]) : METHOD_RETURN, null + + public final java.lang.Object foo(java.lang.String s) + @Lfoo/TypeAnn;([name="1"]) : METHOD_FORMAL_PARAMETER 0, null + @Lfoo/TypeAnn;([name="return"]) : METHOD_RETURN, null + + public final java.lang.Object foo() + @Lfoo/TypeAnn;([name="return"]) : METHOD_RETURN, null + + public static java.lang.Object foo$default(foo.FooClass p0, java.lang.String p1, int p2, int p3, java.lang.Object p4) +} + +public abstract interface foo/TypeAnn : java/lang/Object, java/lang/annotation/Annotation { + public abstract java.lang.String name() +} diff --git a/compiler/testData/codegen/asmLike/typeAnnotations/jvmStatic.kt b/compiler/testData/codegen/asmLike/typeAnnotations/jvmStatic.kt new file mode 100644 index 00000000000..808d6f2d00b --- /dev/null +++ b/compiler/testData/codegen/asmLike/typeAnnotations/jvmStatic.kt @@ -0,0 +1,28 @@ +// KOTLIN_CONFIGURATION_FLAGS: +JVM.EMIT_JVM_TYPE_ANNOTATIONS +// TYPE_ANNOTATIONS +// IGNORE_BACKEND_FIR: JVM_IR +// TARGET_BACKEND: JVM +// JVM_TARGET: 1.8 +// WITH_RUNTIME +package foo + +@Target(AnnotationTarget.TYPE) +annotation class TypeAnn(val name: String) + +class FooClass { + + companion object { + @JvmStatic + fun foo(s: @TypeAnn("1") String, x: @TypeAnn("2") Int): @TypeAnn("return") Any? { + return null + } + } + +} + +object Foo { + @JvmStatic + fun foo(s: @TypeAnn("1") String , x: @TypeAnn("2") Int): @TypeAnn("return") Any? { + return null + } +} \ No newline at end of file diff --git a/compiler/testData/codegen/asmLike/typeAnnotations/jvmStatic.txt b/compiler/testData/codegen/asmLike/typeAnnotations/jvmStatic.txt new file mode 100644 index 00000000000..6c0a6384c30 --- /dev/null +++ b/compiler/testData/codegen/asmLike/typeAnnotations/jvmStatic.txt @@ -0,0 +1,40 @@ +public final class foo/Foo : java/lang/Object { + public final static foo.Foo INSTANCE + + static void () + + private void () + + public final static java.lang.Object foo(java.lang.String s, int x) + @Lfoo/TypeAnn;([name="1"]) : METHOD_FORMAL_PARAMETER 0, null + @Lfoo/TypeAnn;([name="2"]) : METHOD_FORMAL_PARAMETER 1, null + @Lfoo/TypeAnn;([name="return"]) : METHOD_RETURN, null +} + +public final class foo/FooClass$Companion : java/lang/Object { + private void () + + public void (kotlin.jvm.internal.DefaultConstructorMarker $constructor_marker) + + public final java.lang.Object foo(java.lang.String s, int x) + @Lfoo/TypeAnn;([name="1"]) : METHOD_FORMAL_PARAMETER 0, null + @Lfoo/TypeAnn;([name="2"]) : METHOD_FORMAL_PARAMETER 1, null + @Lfoo/TypeAnn;([name="return"]) : METHOD_RETURN, null +} + +public final class foo/FooClass : java/lang/Object { + public final static foo.FooClass$Companion Companion + + static void () + + public void () + + public final static java.lang.Object foo(java.lang.String s, int x) + @Lfoo/TypeAnn;([name="1"]) : METHOD_FORMAL_PARAMETER 0, null + @Lfoo/TypeAnn;([name="2"]) : METHOD_FORMAL_PARAMETER 1, null + @Lfoo/TypeAnn;([name="return"]) : METHOD_RETURN, null +} + +public abstract interface foo/TypeAnn : java/lang/Object, java/lang/annotation/Annotation { + public abstract java.lang.String name() +} \ No newline at end of file diff --git a/compiler/testData/codegen/asmLike/typeAnnotations/notYetSupported.kt b/compiler/testData/codegen/asmLike/typeAnnotations/notYetSupported.kt new file mode 100644 index 00000000000..b5e4224014c --- /dev/null +++ b/compiler/testData/codegen/asmLike/typeAnnotations/notYetSupported.kt @@ -0,0 +1,57 @@ +// KOTLIN_CONFIGURATION_FLAGS: +JVM.EMIT_JVM_TYPE_ANNOTATIONS +// TYPE_ANNOTATIONS +// IGNORE_BACKEND_FIR: JVM_IR +// TARGET_BACKEND: JVM +// JVM_TARGET: 1.8 +package foo + +@Target(AnnotationTarget.TYPE) +annotation class Ann + +@Target(AnnotationTarget.TYPE) +annotation class Ann2 + +@Target(AnnotationTarget.TYPE) +annotation class Ann3 + +@Target(AnnotationTarget.TYPE) +annotation class Ann4 + +class Bar + +class Outer { + inner class Inner +} + +class Kotlin { + + fun foo(s: @Ann Outer.Inner<@Ann2 String>) { + } + + fun foo(): @Ann Outer.Inner<@Ann2 String>? { + return null + } + + fun fooArray(s: @Ann Array<@Ann2 Outer.Inner<@Ann3 String>>) { + } + + fun fooArray(): @Ann Array<@Ann2 Outer.Inner<@Ann3 String>>? { + return null + } + + fun fooArrayIn(s: @Ann Array>) { + } + + fun fooArrayOut(): @Ann Array>? { + return null + } + + + fun fooGenericIn(s: @Ann Bar) { + } + + fun fooGenericOut(s: @Ann Bar) { + } + + +} diff --git a/compiler/testData/codegen/asmLike/typeAnnotations/notYetSupported.txt b/compiler/testData/codegen/asmLike/typeAnnotations/notYetSupported.txt new file mode 100644 index 00000000000..bc5d52cbf7a --- /dev/null +++ b/compiler/testData/codegen/asmLike/typeAnnotations/notYetSupported.txt @@ -0,0 +1,55 @@ +public abstract interface foo/Ann : java/lang/Object, java/lang/annotation/Annotation { + +} + +public abstract interface foo/Ann2 : java/lang/Object, java/lang/annotation/Annotation { + +} + +public abstract interface foo/Ann3 : java/lang/Object, java/lang/annotation/Annotation { + +} + +public abstract interface foo/Ann4 : java/lang/Object, java/lang/annotation/Annotation { + +} + +public final class foo/Bar : java/lang/Object { + public void () +} + +public final class foo/Kotlin : java/lang/Object { + public void () + + public final void foo(foo.Outer$Inner s) + + public final foo.Outer$Inner foo() + + public final void fooArray(foo.Outer$Inner[] s) + @Lfoo/Ann;([]) : METHOD_FORMAL_PARAMETER 0, null + + public final foo.Outer$Inner[] fooArray() + @Lfoo/Ann;([]) : METHOD_RETURN, null + + public final void fooArrayIn(java.lang.Object[] s) + @Lfoo/Ann;([]) : METHOD_FORMAL_PARAMETER 0, null + + public final foo.Outer$Inner[] fooArrayOut() + @Lfoo/Ann;([]) : METHOD_RETURN, null + + public final void fooGenericIn(foo.Bar s) + @Lfoo/Ann;([]) : METHOD_FORMAL_PARAMETER 0, null + + public final void fooGenericOut(foo.Bar s) + @Lfoo/Ann;([]) : METHOD_FORMAL_PARAMETER 0, null +} + +public final class foo/Outer$Inner : java/lang/Object { + final foo.Outer this$0 + + public void (foo.Outer $outer) +} + +public final class foo/Outer : java/lang/Object { + public void () +} diff --git a/compiler/testData/codegen/asmLike/typeAnnotations/property.kt b/compiler/testData/codegen/asmLike/typeAnnotations/property.kt new file mode 100644 index 00000000000..ee5cd906102 --- /dev/null +++ b/compiler/testData/codegen/asmLike/typeAnnotations/property.kt @@ -0,0 +1,43 @@ +// KOTLIN_CONFIGURATION_FLAGS: +JVM.EMIT_JVM_TYPE_ANNOTATIONS +// TYPE_ANNOTATIONS +// IGNORE_BACKEND_FIR: JVM_IR +// TARGET_BACKEND: JVM +// JVM_TARGET: 1.8 +// WITH_RUNTIME +// WITH_REFLECT +// FULL_JDK +package foo + +import java.lang.reflect.AnnotatedType +import kotlin.reflect.jvm.javaMethod +import kotlin.test.fail + +@Target(AnnotationTarget.TYPE) +annotation class TypeAnn(val name: String) + +@Target(AnnotationTarget.TYPE) +@Retention(AnnotationRetention.BINARY) +annotation class TypeAnnBinary + +@Target(AnnotationTarget.TYPE) +@Retention(AnnotationRetention.SOURCE) +annotation class TypeAnnSource + +class Kotlin { + + val valProp: @TypeAnn("1") @TypeAnnBinary @TypeAnnSource String = "123" + + var varProp: @TypeAnn("1") @TypeAnnBinary @TypeAnnSource String = "123" + + var customSetter: @TypeAnn("1") @TypeAnnBinary @TypeAnnSource String = "123" + set(field: String) {} + + @JvmField + var jvmField: @TypeAnn("1") @TypeAnnBinary @TypeAnnSource String = "123" + + lateinit var lateinitProp: @TypeAnn("1") @TypeAnnBinary @TypeAnnSource String + + companion object { + var companionVarProperty: @TypeAnn("1") @TypeAnnBinary @TypeAnnSource String = "123" + } +} diff --git a/compiler/testData/codegen/asmLike/typeAnnotations/simple.kt b/compiler/testData/codegen/asmLike/typeAnnotations/simple.kt new file mode 100644 index 00000000000..883c8ced461 --- /dev/null +++ b/compiler/testData/codegen/asmLike/typeAnnotations/simple.kt @@ -0,0 +1,39 @@ +// KOTLIN_CONFIGURATION_FLAGS: +JVM.EMIT_JVM_TYPE_ANNOTATIONS +// TYPE_ANNOTATIONS +// IGNORE_BACKEND_FIR: JVM_IR +// TARGET_BACKEND: JVM +// JVM_TARGET: 1.8 +package foo + +@Target(AnnotationTarget.TYPE) +annotation class TypeAnn(val name: String) + +@Target(AnnotationTarget.TYPE) +@Retention(AnnotationRetention.BINARY) +annotation class TypeAnnBinary + +@Target(AnnotationTarget.TYPE) +@Retention(AnnotationRetention.SOURCE) +annotation class TypeAnnSource + +class Kotlin { + + private fun foo(s: @TypeAnn("1") @TypeAnnBinary @TypeAnnSource String) { + } + + fun foo2(): @TypeAnn("2") @TypeAnnBinary @TypeAnnSource String { + return "OK" + } + + fun fooArray(s: Array<@TypeAnn("3") @TypeAnnBinary @TypeAnnSource String>) { + } + + fun fooArray2(): Array<@TypeAnn("4") @TypeAnnBinary @TypeAnnSource String>? { + { + foo2() + foo("123") + }() + return null + } + +} diff --git a/compiler/testData/codegen/asmLike/typeAnnotations/simple.txt b/compiler/testData/codegen/asmLike/typeAnnotations/simple.txt new file mode 100644 index 00000000000..1eb63b93dd4 --- /dev/null +++ b/compiler/testData/codegen/asmLike/typeAnnotations/simple.txt @@ -0,0 +1,43 @@ +final class foo/Kotlin$fooArray2$1 : kotlin/jvm/internal/Lambda, kotlin/jvm/functions/Function0 { + final foo.Kotlin this$0 + + void (foo.Kotlin p0) + + public java.lang.Object invoke() + + public final void invoke() +} + +public final class foo/Kotlin : java/lang/Object { + public void () + + public final static void access$foo(foo.Kotlin $this, java.lang.String s) + + private final void foo(java.lang.String s) + @Lfoo/TypeAnn;([name="1"]) : METHOD_FORMAL_PARAMETER 0, null + @Lfoo/TypeAnnBinary;([]) : METHOD_FORMAL_PARAMETER 0, null // invisible + + public final java.lang.String foo2() + @Lfoo/TypeAnn;([name="2"]) : METHOD_RETURN, null + @Lfoo/TypeAnnBinary;([]) : METHOD_RETURN, null // invisible + + public final void fooArray(java.lang.String[] s) + @Lfoo/TypeAnn;([name="3"]) : METHOD_FORMAL_PARAMETER 0, [ + @Lfoo/TypeAnnBinary;([]) : METHOD_FORMAL_PARAMETER 0, [ // invisible + + public final java.lang.String[] fooArray2() + @Lfoo/TypeAnn;([name="4"]) : METHOD_RETURN, [ + @Lfoo/TypeAnnBinary;([]) : METHOD_RETURN, [ // invisible +} + +public abstract interface foo/TypeAnn : java/lang/Object, java/lang/annotation/Annotation { + public abstract java.lang.String name() +} + +public abstract interface foo/TypeAnnBinary : java/lang/Object, java/lang/annotation/Annotation { + +} + +public abstract interface foo/TypeAnnSource : java/lang/Object, java/lang/annotation/Annotation { + +} diff --git a/compiler/testData/codegen/asmLike/typeAnnotations/simple2Params.kt b/compiler/testData/codegen/asmLike/typeAnnotations/simple2Params.kt new file mode 100644 index 00000000000..659e82d9a85 --- /dev/null +++ b/compiler/testData/codegen/asmLike/typeAnnotations/simple2Params.kt @@ -0,0 +1,20 @@ +// KOTLIN_CONFIGURATION_FLAGS: +JVM.EMIT_JVM_TYPE_ANNOTATIONS +// TYPE_ANNOTATIONS +// IGNORE_BACKEND_FIR: JVM_IR +// TARGET_BACKEND: JVM +// JVM_TARGET: 1.8 +package foo + +@Target(AnnotationTarget.TYPE) +annotation class TypeAnn(val name: String) + +class Kotlin { + + fun foo(s: @TypeAnn("1") String, x: @TypeAnn("2") Int) { + } + + + fun fooArray(s: Array<@TypeAnn("3") String>, i: Array<@TypeAnn("3") Int>) { + } + +} diff --git a/compiler/testData/codegen/asmLike/typeAnnotations/simple2Params.txt b/compiler/testData/codegen/asmLike/typeAnnotations/simple2Params.txt new file mode 100644 index 00000000000..a6ab94a240a --- /dev/null +++ b/compiler/testData/codegen/asmLike/typeAnnotations/simple2Params.txt @@ -0,0 +1,15 @@ +public final class foo/Kotlin : java/lang/Object { + public void () + + public final void foo(java.lang.String s, int x) + @Lfoo/TypeAnn;([name="1"]) : METHOD_FORMAL_PARAMETER 0, null + @Lfoo/TypeAnn;([name="2"]) : METHOD_FORMAL_PARAMETER 1, null + + public final void fooArray(java.lang.String[] s, java.lang.Integer[] i) + @Lfoo/TypeAnn;([name="3"]) : METHOD_FORMAL_PARAMETER 0, [ + @Lfoo/TypeAnn;([name="3"]) : METHOD_FORMAL_PARAMETER 1, [ +} + +public abstract interface foo/TypeAnn : java/lang/Object, java/lang/annotation/Annotation { + public abstract java.lang.String name() +} \ No newline at end of file diff --git a/compiler/testData/codegen/asmLike/typeAnnotations/staticNested.kt b/compiler/testData/codegen/asmLike/typeAnnotations/staticNested.kt new file mode 100644 index 00000000000..37d79655766 --- /dev/null +++ b/compiler/testData/codegen/asmLike/typeAnnotations/staticNested.kt @@ -0,0 +1,57 @@ +// KOTLIN_CONFIGURATION_FLAGS: +JVM.EMIT_JVM_TYPE_ANNOTATIONS +// TYPE_ANNOTATIONS +// IGNORE_BACKEND_FIR: JVM_IR +// TARGET_BACKEND: JVM +// JVM_TARGET: 1.8 +package foo + +@Target(AnnotationTarget.TYPE) +annotation class Ann + +@Target(AnnotationTarget.TYPE) +annotation class Ann2 + +@Target(AnnotationTarget.TYPE) +annotation class Ann3 + +@Target(AnnotationTarget.TYPE) +annotation class Ann4 + +class Bar + +class Outer { + class NestedStatic +} + +class Kotlin { + + fun foo(s: @Ann Outer.NestedStatic<@Ann2 String>) { + } + + fun foo(): @Ann Outer.NestedStatic<@Ann2 String>? { + return null + } + + fun fooArray(s: @Ann Array<@Ann2 Outer.NestedStatic<@Ann3 String>>) { + } + + fun fooArray(): @Ann Array<@Ann2 Outer.NestedStatic<@Ann3 String>>? { + return null + } + + fun fooArrayIn(s: @Ann Array>) { + } + + fun fooArrayOut(): @Ann Array>? { + return null + } + + + fun fooGenericIn(s: @Ann Bar) { + } + + fun fooGenericOut(s: @Ann Bar) { + } + + +} diff --git a/compiler/testData/codegen/asmLike/typeAnnotations/staticNested.txt b/compiler/testData/codegen/asmLike/typeAnnotations/staticNested.txt new file mode 100644 index 00000000000..ae604901475 --- /dev/null +++ b/compiler/testData/codegen/asmLike/typeAnnotations/staticNested.txt @@ -0,0 +1,61 @@ +public abstract interface foo/Ann : java/lang/Object, java/lang/annotation/Annotation { + +} + +public abstract interface foo/Ann2 : java/lang/Object, java/lang/annotation/Annotation { + +} + +public abstract interface foo/Ann3 : java/lang/Object, java/lang/annotation/Annotation { + +} + +public abstract interface foo/Ann4 : java/lang/Object, java/lang/annotation/Annotation { + +} + +public final class foo/Bar : java/lang/Object { + public void () +} + +public final class foo/Kotlin : java/lang/Object { + public void () + + public final void foo(foo.Outer$NestedStatic s) + @Lfoo/Ann;([]) : METHOD_FORMAL_PARAMETER 0, null + @Lfoo/Ann2;([]) : METHOD_FORMAL_PARAMETER 0, 0; + + public final foo.Outer$NestedStatic foo() + @Lfoo/Ann;([]) : METHOD_RETURN, null + @Lfoo/Ann2;([]) : METHOD_RETURN, 0; + + public final void fooArray(foo.Outer$NestedStatic[] s) + @Lfoo/Ann;([]) : METHOD_FORMAL_PARAMETER 0, null + @Lfoo/Ann2;([]) : METHOD_FORMAL_PARAMETER 0, [ + @Lfoo/Ann3;([]) : METHOD_FORMAL_PARAMETER 0, [0; + + public final foo.Outer$NestedStatic[] fooArray() + @Lfoo/Ann;([]) : METHOD_RETURN, null + @Lfoo/Ann2;([]) : METHOD_RETURN, [ + @Lfoo/Ann3;([]) : METHOD_RETURN, [0; + + public final void fooArrayIn(java.lang.Object[] s) + @Lfoo/Ann;([]) : METHOD_FORMAL_PARAMETER 0, null + + public final foo.Outer$NestedStatic[] fooArrayOut() + @Lfoo/Ann;([]) : METHOD_RETURN, null + + public final void fooGenericIn(foo.Bar s) + @Lfoo/Ann;([]) : METHOD_FORMAL_PARAMETER 0, null + + public final void fooGenericOut(foo.Bar s) + @Lfoo/Ann;([]) : METHOD_FORMAL_PARAMETER 0, null +} + +public final class foo/Outer$NestedStatic : java/lang/Object { + public void () +} + +public final class foo/Outer : java/lang/Object { + public void () +} diff --git a/compiler/testData/codegen/box/annotations/typeAnnotations/implicitReturn.kt b/compiler/testData/codegen/box/annotations/typeAnnotations/implicitReturn.kt new file mode 100644 index 00000000000..1465dc8fb49 --- /dev/null +++ b/compiler/testData/codegen/box/annotations/typeAnnotations/implicitReturn.kt @@ -0,0 +1,76 @@ +// KOTLIN_CONFIGURATION_FLAGS: +JVM.EMIT_JVM_TYPE_ANNOTATIONS +// TARGET_BACKEND: JVM +// IGNORE_BACKEND_FIR: JVM_IR +// IGNORE_BACKEND: JVM_IR +// JVM_TARGET: 1.8 +// WITH_REFLECT +// FULL_JDK + +// FILE: ImplicitReturn.java + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + + +public class ImplicitReturn { + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.TYPE_USE) + public @ interface TypeAnn {} + + @ImplicitReturn.TypeAnn + public String bar() { + return "OK"; + } +} + + +// FILE: Kotlin.kt + +import java.lang.reflect.AnnotatedType +import kotlin.reflect.jvm.javaMethod +import kotlin.reflect.jvm.javaField +import kotlin.test.fail + +class Kotlin { + + fun foo() = ImplicitReturn().bar() + + @JvmField + val field = ImplicitReturn().bar() +} + +fun box(): String { + + checkTypeAnnotation( + Kotlin::foo.javaMethod!!.annotatedReturnType, + "class java.lang.String", + "@ImplicitReturn\$TypeAnn()", + "foo" + ) + + checkTypeAnnotation( + Kotlin::field.javaField!!.annotatedType, + "class java.lang.String", + "@ImplicitReturn\$TypeAnn()", + "foo" + ) + + return Kotlin().foo() +} + +fun checkTypeAnnotation( + annotatedType: AnnotatedType, + type: String, + annotations: String, + message: String +) { + if (annotatedType.annotation() != annotations) fail("check $message (1): ${annotatedType.annotation()} != $annotations") + + if (annotatedType.type.toString() != type) fail("check $message (2): ${annotatedType.type} != $type") +} + + +fun AnnotatedType.annotation() = annotations.joinToString() diff --git a/compiler/testData/codegen/box/annotations/typeAnnotations/methodParameters.kt b/compiler/testData/codegen/box/annotations/typeAnnotations/methodParameters.kt new file mode 100644 index 00000000000..b01800070fe --- /dev/null +++ b/compiler/testData/codegen/box/annotations/typeAnnotations/methodParameters.kt @@ -0,0 +1,57 @@ +// KOTLIN_CONFIGURATION_FLAGS: +JVM.EMIT_JVM_TYPE_ANNOTATIONS +// TARGET_BACKEND: JVM +// IGNORE_BACKEND_FIR: JVM_IR +// IGNORE_BACKEND: JVM_IR +// JVM_TARGET: 1.8 +// WITH_REFLECT +// FULL_JDK +package foo + +import java.lang.reflect.AnnotatedType +import kotlin.reflect.jvm.javaMethod +import kotlin.test.fail + +@Target(AnnotationTarget.TYPE) +annotation class TypeAnn + +@Target(AnnotationTarget.TYPE) +@Retention(AnnotationRetention.BINARY) +annotation class TypeAnnBinary + +class Kotlin { + + fun foo(s: @TypeAnn @TypeAnnBinary String) { + } + + fun foo2(): @TypeAnn @TypeAnnBinary String { + return "OK" + } +} + +fun box(): String { + + checkTypeAnnotation( + Kotlin::foo.javaMethod!!.annotatedParameterTypes.single(), + "class java.lang.String", + "@foo.TypeAnn()", + "foo" + ) + + checkTypeAnnotation(Kotlin::foo2.javaMethod!!.annotatedReturnType, "class java.lang.String", "@foo.TypeAnn()", "foo2") + + return "OK" +} + +fun checkTypeAnnotation( + annotatedType: AnnotatedType, + type: String, + annotations: String, + message: String +) { + if (annotatedType.annotation() != annotations) fail("check $message (1): ${annotatedType.annotation()} != $annotations") + + if (annotatedType.type.toString() != type) fail("check $message (2): ${annotatedType.type} != $type") +} + + +fun AnnotatedType.annotation() = annotations.joinToString() diff --git a/compiler/testData/codegen/box/annotations/typeAnnotations/typeUseAnnotation.kt b/compiler/testData/codegen/box/annotations/typeAnnotations/typeUseAnnotation.kt new file mode 100644 index 00000000000..6484d118fd4 --- /dev/null +++ b/compiler/testData/codegen/box/annotations/typeAnnotations/typeUseAnnotation.kt @@ -0,0 +1,65 @@ +// KOTLIN_CONFIGURATION_FLAGS: +JVM.EMIT_JVM_TYPE_ANNOTATIONS +// TARGET_BACKEND: JVM +// IGNORE_BACKEND_FIR: JVM_IR +// IGNORE_BACKEND: JVM_IR +// JVM_TARGET: 1.8 +// WITH_REFLECT +// FULL_JDK + +// FILE: foo/TypeAnn.java +package foo; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE_USE) +public @interface TypeAnn {} + +// FILE: test.kt +package foo + +import java.lang.reflect.AnnotatedType +import kotlin.reflect.jvm.javaMethod +import kotlin.test.fail + +class Kotlin { + + fun foo(s: @TypeAnn String) { + } + + fun foo2(): @TypeAnn String { + return "OK" + } +} + +fun box(): String { + + checkTypeAnnotation( + Kotlin::foo.javaMethod!!.annotatedParameterTypes.single(), + "class java.lang.String", + "@foo.TypeAnn()", + "foo" + ) + + checkTypeAnnotation(Kotlin::foo2.javaMethod!!.annotatedReturnType, "class java.lang.String", "@foo.TypeAnn()", "foo2") + + return "OK" +} + +fun checkTypeAnnotation( + annotatedType: AnnotatedType, + type: String, + annotations: String, + message: String +) { + if (annotatedType.annotation() != annotations) fail("check $message (1): ${annotatedType.annotation()} != $annotations") + + if (annotatedType.type.toString() != type) fail("check $message (2): ${annotatedType.type} != $type") +} + + +fun AnnotatedType.annotation() = annotations.joinToString() diff --git a/compiler/testData/codegen/boxAgainstJava/annotations/typeAnnotations/implicitReturn.kt b/compiler/testData/codegen/boxAgainstJava/annotations/typeAnnotations/implicitReturn.kt new file mode 100644 index 00000000000..1465dc8fb49 --- /dev/null +++ b/compiler/testData/codegen/boxAgainstJava/annotations/typeAnnotations/implicitReturn.kt @@ -0,0 +1,76 @@ +// KOTLIN_CONFIGURATION_FLAGS: +JVM.EMIT_JVM_TYPE_ANNOTATIONS +// TARGET_BACKEND: JVM +// IGNORE_BACKEND_FIR: JVM_IR +// IGNORE_BACKEND: JVM_IR +// JVM_TARGET: 1.8 +// WITH_REFLECT +// FULL_JDK + +// FILE: ImplicitReturn.java + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + + +public class ImplicitReturn { + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.TYPE_USE) + public @ interface TypeAnn {} + + @ImplicitReturn.TypeAnn + public String bar() { + return "OK"; + } +} + + +// FILE: Kotlin.kt + +import java.lang.reflect.AnnotatedType +import kotlin.reflect.jvm.javaMethod +import kotlin.reflect.jvm.javaField +import kotlin.test.fail + +class Kotlin { + + fun foo() = ImplicitReturn().bar() + + @JvmField + val field = ImplicitReturn().bar() +} + +fun box(): String { + + checkTypeAnnotation( + Kotlin::foo.javaMethod!!.annotatedReturnType, + "class java.lang.String", + "@ImplicitReturn\$TypeAnn()", + "foo" + ) + + checkTypeAnnotation( + Kotlin::field.javaField!!.annotatedType, + "class java.lang.String", + "@ImplicitReturn\$TypeAnn()", + "foo" + ) + + return Kotlin().foo() +} + +fun checkTypeAnnotation( + annotatedType: AnnotatedType, + type: String, + annotations: String, + message: String +) { + if (annotatedType.annotation() != annotations) fail("check $message (1): ${annotatedType.annotation()} != $annotations") + + if (annotatedType.type.toString() != type) fail("check $message (2): ${annotatedType.type} != $type") +} + + +fun AnnotatedType.annotation() = annotations.joinToString() diff --git a/compiler/testData/compileKotlinAgainstKotlin/typeAnnotations/implicitReturn.kt b/compiler/testData/compileKotlinAgainstKotlin/typeAnnotations/implicitReturn.kt new file mode 100644 index 00000000000..196041736f5 --- /dev/null +++ b/compiler/testData/compileKotlinAgainstKotlin/typeAnnotations/implicitReturn.kt @@ -0,0 +1,66 @@ +// KOTLIN_CONFIGURATION_FLAGS: +JVM.EMIT_JVM_TYPE_ANNOTATIONS +// TARGET_BACKEND: JVM +// IGNORE_BACKEND_FIR: JVM_IR +// IGNORE_BACKEND: JVM_IR +// JVM_TARGET: 1.8 +// WITH_REFLECT +// FULL_JDK + +// FILE: A.kt + +import java.lang.reflect.AnnotatedType +import kotlin.reflect.jvm.javaMethod +import kotlin.test.fail + +@Target(AnnotationTarget.TYPE) +annotation class TypeAnn + +fun bar(): @TypeAnn String = "OK" + +// FILE: B.kt + +import java.lang.reflect.AnnotatedType +import kotlin.reflect.jvm.javaMethod +import kotlin.reflect.jvm.javaField +import kotlin.test.fail + +class Kotlin { + + fun foo() = bar() + + @JvmField + val field = bar() +} + +fun box(): String { + + checkTypeAnnotation( + Kotlin::foo.javaMethod!!.annotatedReturnType, + "class java.lang.String", + "@TypeAnn()", + "foo" + ) + + checkTypeAnnotation( + Kotlin::field.javaField!!.annotatedType, + "class java.lang.String", + "@TypeAnn()", + "foo" + ) + + return Kotlin().foo() +} + +fun checkTypeAnnotation( + annotatedType: AnnotatedType, + type: String, + annotations: String, + message: String +) { + if (annotatedType.annotation() != annotations) fail("check $message (1): ${annotatedType.annotation()} != $annotations") + + if (annotatedType.type.toString() != type) fail("check $message (2): ${annotatedType.type} != $type") +} + + +fun AnnotatedType.annotation() = annotations.joinToString() diff --git a/compiler/testData/compileKotlinAgainstKotlin/typeAnnotations/typeAnnotationTarget6.kt b/compiler/testData/compileKotlinAgainstKotlin/typeAnnotations/typeAnnotationTarget6.kt new file mode 100644 index 00000000000..d6a36726ff0 --- /dev/null +++ b/compiler/testData/compileKotlinAgainstKotlin/typeAnnotations/typeAnnotationTarget6.kt @@ -0,0 +1,60 @@ +// KOTLIN_CONFIGURATION_FLAGS: +JVM.EMIT_JVM_TYPE_ANNOTATIONS +// TARGET_BACKEND: JVM +// IGNORE_BACKEND_FIR: JVM_IR +// WITH_REFLECT +// FULL_JDK + +// FILE: A.kt +// JVM_TARGET: 1.6 + +import java.lang.reflect.AnnotatedType +import kotlin.reflect.jvm.javaMethod +import kotlin.test.fail + +@Target(AnnotationTarget.TYPE) +annotation class TypeAnn + +// FILE: B.kt +// JVM_TARGET: 1.8 + +import java.lang.reflect.AnnotatedType +import kotlin.reflect.jvm.javaMethod +import kotlin.test.fail + +class Kotlin { + + fun foo(s: @TypeAnn String) { + } + + fun foo2(): @TypeAnn String { + return "OK" + } +} + +fun box(): String { + + checkTypeAnnotation( + Kotlin::foo.javaMethod!!.annotatedParameterTypes.single(), + "class java.lang.String", + "", + "foo" + ) + + checkTypeAnnotation(Kotlin::foo2.javaMethod!!.annotatedReturnType, "class java.lang.String", "", "foo2") + + return "OK" +} + +fun checkTypeAnnotation( + annotatedType: AnnotatedType, + type: String, + annotations: String, + message: String +) { + if (annotatedType.annotation() != annotations) fail("check $message (1): ${annotatedType.annotation()} != $annotations") + + if (annotatedType.type.toString() != type) fail("check $message (2): ${annotatedType.type} != $type") +} + + +fun AnnotatedType.annotation() = annotations.joinToString() diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/AbstractAsmLikeInstructionListingTest.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/AbstractAsmLikeInstructionListingTest.kt index 9ed1984bb34..0cf734703e7 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/AbstractAsmLikeInstructionListingTest.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/AbstractAsmLikeInstructionListingTest.kt @@ -13,14 +13,17 @@ import org.jetbrains.org.objectweb.asm.Opcodes.* import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.tree.* import org.jetbrains.org.objectweb.asm.util.Printer +import org.jetbrains.org.objectweb.asm.util.Textifier +import org.jetbrains.org.objectweb.asm.util.TraceMethodVisitor import java.io.File private val LINE_SEPARATOR = System.getProperty("line.separator") abstract class AbstractAsmLikeInstructionListingTest : CodegenTestCase() { private companion object { - val CURIOUS_ABOUT_DIRECTIVE = "// CURIOUS_ABOUT " - val LOCAL_VARIABLE_TABLE_DIRECTIVE = "// LOCAL_VARIABLE_TABLE" + const val CURIOUS_ABOUT_DIRECTIVE = "// CURIOUS_ABOUT " + const val LOCAL_VARIABLE_TABLE_DIRECTIVE = "// LOCAL_VARIABLE_TABLE" + const val TYPE_ANNOTATIONS_DIRECTIVE = "// TYPE_ANNOTATIONS" } override fun doMultiFileTest(wholeFile: File, files: List) { @@ -40,15 +43,21 @@ abstract class AbstractAsmLikeInstructionListingTest : CodegenTestCase() { .flatMap { it.split(',').map { it.trim() } } val showLocalVariables = testFileLines.any { it.trim() == LOCAL_VARIABLE_TABLE_DIRECTIVE } + val showTypeAnnotations = testFileLines.any { it.trim() == TYPE_ANNOTATIONS_DIRECTIVE } KotlinTestUtils.assertEqualsToFile(txtFile, classes.joinToString(LINE_SEPARATOR.repeat(2)) { - renderClassNode(it, printBytecodeForTheseMethods, showLocalVariables) + renderClassNode(it, printBytecodeForTheseMethods, showLocalVariables, showTypeAnnotations) }) } protected open fun getExpectedTextFileName(wholeFile: File): String = wholeFile.nameWithoutExtension + ".txt" - private fun renderClassNode(clazz: ClassNode, showBytecodeForTheseMethods: List, showLocalVariables: Boolean): String { + private fun renderClassNode( + clazz: ClassNode, + showBytecodeForTheseMethods: List, + showLocalVariables: Boolean, + showTypeAnnotations: Boolean + ): String { val fields = (clazz.fields ?: emptyList()).sortedBy { it.name } val methods = (clazz.methods ?: emptyList()).sortedBy { it.name } @@ -74,7 +83,7 @@ abstract class AbstractAsmLikeInstructionListingTest : CodegenTestCase() { methods.joinTo(this, LINE_SEPARATOR.repeat(2)) { val showBytecode = showBytecodeForTheseMethods.contains(it.name) - renderMethod(it, showBytecode, showLocalVariables).withMargin() + renderMethod(it, showBytecode, showLocalVariables, showTypeAnnotations).withMargin() } appendln().append("}") @@ -88,7 +97,12 @@ abstract class AbstractAsmLikeInstructionListingTest : CodegenTestCase() { append(field.name) } - private fun renderMethod(method: MethodNode, showBytecode: Boolean, showLocalVariables: Boolean) = buildString { + private fun renderMethod( + method: MethodNode, + showBytecode: Boolean, + showLocalVariables: Boolean, + showTypeAnnotations: Boolean + ) = buildString { renderVisibilityModifiers(method.access) renderModalityModifiers(method.access) val (returnType, parameterTypes) = with(Type.getMethodType(method.desc)) { returnType to argumentTypes } @@ -100,6 +114,20 @@ abstract class AbstractAsmLikeInstructionListingTest : CodegenTestCase() { "${type.className} $name" }.joinTo(this, prefix = "(", postfix = ")") + if (showTypeAnnotations) { + val textifier = Textifier() + val visitor = TraceMethodVisitor(textifier) + method.visibleTypeAnnotations?.forEach { + it.accept(visitor.visitTypeAnnotation(it.typeRef, it.typePath, it.desc, true)) + } + method.invisibleTypeAnnotations?.forEach { + it.accept(visitor.visitTypeAnnotation(it.typeRef, it.typePath, it.desc, false)) + } + textifier.getText().takeIf { it.isNotEmpty() }?.let { + append("\n${textifier.getText().joinToString("").trimEnd()}") + } + } + val actualShowBytecode = showBytecode && (method.access and ACC_ABSTRACT) == 0 val actualShowLocalVariables = showLocalVariables && method.localVariables?.takeIf { it.isNotEmpty() } != null @@ -121,6 +149,8 @@ abstract class AbstractAsmLikeInstructionListingTest : CodegenTestCase() { } appendln().append("}") + + method.visibleTypeAnnotations } } diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/AsmLikeInstructionListingTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/AsmLikeInstructionListingTestGenerated.java index 8f3a982e44b..4aa7e0c5ddb 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/AsmLikeInstructionListingTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/AsmLikeInstructionListingTestGenerated.java @@ -111,4 +111,82 @@ public class AsmLikeInstructionListingTestGenerated extends AbstractAsmLikeInstr runTest("compiler/testData/codegen/asmLike/receiverMangling/simple.kt"); } } + + @TestMetadata("compiler/testData/codegen/asmLike/typeAnnotations") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class TypeAnnotations extends AbstractAsmLikeInstructionListingTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath); + } + + public void testAllFilesPresentInTypeAnnotations() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/asmLike/typeAnnotations"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); + } + + @TestMetadata("complex.kt") + public void testComplex() throws Exception { + runTest("compiler/testData/codegen/asmLike/typeAnnotations/complex.kt"); + } + + @TestMetadata("constructor.kt") + public void testConstructor() throws Exception { + runTest("compiler/testData/codegen/asmLike/typeAnnotations/constructor.kt"); + } + + @TestMetadata("defaultArgs.kt") + public void testDefaultArgs() throws Exception { + runTest("compiler/testData/codegen/asmLike/typeAnnotations/defaultArgs.kt"); + } + + @TestMetadata("enumClassConstructor.kt") + public void testEnumClassConstructor() throws Exception { + runTest("compiler/testData/codegen/asmLike/typeAnnotations/enumClassConstructor.kt"); + } + + @TestMetadata("extension.kt") + public void testExtension() throws Exception { + runTest("compiler/testData/codegen/asmLike/typeAnnotations/extension.kt"); + } + + @TestMetadata("implicit.kt") + public void testImplicit() throws Exception { + runTest("compiler/testData/codegen/asmLike/typeAnnotations/implicit.kt"); + } + + @TestMetadata("innerClassConstructor.kt") + public void testInnerClassConstructor() throws Exception { + runTest("compiler/testData/codegen/asmLike/typeAnnotations/innerClassConstructor.kt"); + } + + @TestMetadata("jvmOverload.kt") + public void testJvmOverload() throws Exception { + runTest("compiler/testData/codegen/asmLike/typeAnnotations/jvmOverload.kt"); + } + + @TestMetadata("jvmStatic.kt") + public void testJvmStatic() throws Exception { + runTest("compiler/testData/codegen/asmLike/typeAnnotations/jvmStatic.kt"); + } + + @TestMetadata("notYetSupported.kt") + public void testNotYetSupported() throws Exception { + runTest("compiler/testData/codegen/asmLike/typeAnnotations/notYetSupported.kt"); + } + + @TestMetadata("simple.kt") + public void testSimple() throws Exception { + runTest("compiler/testData/codegen/asmLike/typeAnnotations/simple.kt"); + } + + @TestMetadata("simple2Params.kt") + public void testSimple2Params() throws Exception { + runTest("compiler/testData/codegen/asmLike/typeAnnotations/simple2Params.kt"); + } + + @TestMetadata("staticNested.kt") + public void testStaticNested() throws Exception { + runTest("compiler/testData/codegen/asmLike/typeAnnotations/staticNested.kt"); + } + } } diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxAgainstJavaCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxAgainstJavaCodegenTestGenerated.java index b8861432ebd..2fcfe6c5252 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxAgainstJavaCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxAgainstJavaCodegenTestGenerated.java @@ -127,6 +127,24 @@ public class BlackBoxAgainstJavaCodegenTestGenerated extends AbstractBlackBoxAga runTest("compiler/testData/codegen/boxAgainstJava/annotations/kClassMapping/varargClassParameterOnJavaClass.kt"); } } + + @TestMetadata("compiler/testData/codegen/boxAgainstJava/annotations/typeAnnotations") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class TypeAnnotations extends AbstractBlackBoxAgainstJavaCodegenTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInTypeAnnotations() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxAgainstJava/annotations/typeAnnotations"), Pattern.compile("^(.+)\\.kt$"), null, true); + } + + @TestMetadata("implicitReturn.kt") + public void testImplicitReturn() throws Exception { + runTest("compiler/testData/codegen/boxAgainstJava/annotations/typeAnnotations/implicitReturn.kt"); + } + } } @TestMetadata("compiler/testData/codegen/boxAgainstJava/callableReference") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 1fa9ba6e5bb..c9a263cc156 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -248,6 +248,34 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/annotations/annotatedLambda/samLambda.kt"); } } + + @TestMetadata("compiler/testData/codegen/box/annotations/typeAnnotations") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class TypeAnnotations extends AbstractBlackBoxCodegenTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath); + } + + public void testAllFilesPresentInTypeAnnotations() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/annotations/typeAnnotations"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); + } + + @TestMetadata("implicitReturn.kt") + public void testImplicitReturn() throws Exception { + runTest("compiler/testData/codegen/box/annotations/typeAnnotations/implicitReturn.kt"); + } + + @TestMetadata("methodParameters.kt") + public void testMethodParameters() throws Exception { + runTest("compiler/testData/codegen/box/annotations/typeAnnotations/methodParameters.kt"); + } + + @TestMetadata("typeUseAnnotation.kt") + public void testTypeUseAnnotation() throws Exception { + runTest("compiler/testData/codegen/box/annotations/typeAnnotations/typeUseAnnotation.kt"); + } + } } @TestMetadata("compiler/testData/codegen/box/argumentOrder") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstKotlinTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstKotlinTestGenerated.java index 4651511184a..6f8fae51505 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstKotlinTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstKotlinTestGenerated.java @@ -469,4 +469,27 @@ public class CompileKotlinAgainstKotlinTestGenerated extends AbstractCompileKotl } } } + + @TestMetadata("compiler/testData/compileKotlinAgainstKotlin/typeAnnotations") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class TypeAnnotations extends AbstractCompileKotlinAgainstKotlinTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInTypeAnnotations() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/compileKotlinAgainstKotlin/typeAnnotations"), Pattern.compile("^(.+)\\.kt$"), null, true); + } + + @TestMetadata("implicitReturn.kt") + public void testImplicitReturn() throws Exception { + runTest("compiler/testData/compileKotlinAgainstKotlin/typeAnnotations/implicitReturn.kt"); + } + + @TestMetadata("typeAnnotationTarget6.kt") + public void testTypeAnnotationTarget6() throws Exception { + runTest("compiler/testData/compileKotlinAgainstKotlin/typeAnnotations/typeAnnotationTarget6.kt"); + } + } } diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 1c91da2919c..6ae47a56ec1 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -248,6 +248,34 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/annotations/annotatedLambda/samLambda.kt"); } } + + @TestMetadata("compiler/testData/codegen/box/annotations/typeAnnotations") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class TypeAnnotations extends AbstractLightAnalysisModeTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath); + } + + public void testAllFilesPresentInTypeAnnotations() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/annotations/typeAnnotations"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); + } + + @TestMetadata("implicitReturn.kt") + public void testImplicitReturn() throws Exception { + runTest("compiler/testData/codegen/box/annotations/typeAnnotations/implicitReturn.kt"); + } + + @TestMetadata("methodParameters.kt") + public void testMethodParameters() throws Exception { + runTest("compiler/testData/codegen/box/annotations/typeAnnotations/methodParameters.kt"); + } + + @TestMetadata("typeUseAnnotation.kt") + public void testTypeUseAnnotation() throws Exception { + runTest("compiler/testData/codegen/box/annotations/typeAnnotations/typeUseAnnotation.kt"); + } + } } @TestMetadata("compiler/testData/codegen/box/argumentOrder") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java index 5c95fa766cc..aec8c911c5e 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java @@ -248,6 +248,34 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/annotations/annotatedLambda/samLambda.kt"); } } + + @TestMetadata("compiler/testData/codegen/box/annotations/typeAnnotations") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class TypeAnnotations extends AbstractFirBlackBoxCodegenTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTestWithCustomIgnoreDirective(this::doTest, TargetBackend.JVM_IR, testDataFilePath, "// IGNORE_BACKEND_FIR: "); + } + + public void testAllFilesPresentInTypeAnnotations() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/annotations/typeAnnotations"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); + } + + @TestMetadata("implicitReturn.kt") + public void testImplicitReturn() throws Exception { + runTest("compiler/testData/codegen/box/annotations/typeAnnotations/implicitReturn.kt"); + } + + @TestMetadata("methodParameters.kt") + public void testMethodParameters() throws Exception { + runTest("compiler/testData/codegen/box/annotations/typeAnnotations/methodParameters.kt"); + } + + @TestMetadata("typeUseAnnotation.kt") + public void testTypeUseAnnotation() throws Exception { + runTest("compiler/testData/codegen/box/annotations/typeAnnotations/typeUseAnnotation.kt"); + } + } } @TestMetadata("compiler/testData/codegen/box/argumentOrder") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxAgainstJavaCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxAgainstJavaCodegenTestGenerated.java index 256f655bf73..55cd634cf24 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxAgainstJavaCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxAgainstJavaCodegenTestGenerated.java @@ -128,6 +128,24 @@ public class IrBlackBoxAgainstJavaCodegenTestGenerated extends AbstractIrBlackBo runTest("compiler/testData/codegen/boxAgainstJava/annotations/kClassMapping/varargClassParameterOnJavaClass.kt"); } } + + @TestMetadata("compiler/testData/codegen/boxAgainstJava/annotations/typeAnnotations") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class TypeAnnotations extends AbstractIrBlackBoxAgainstJavaCodegenTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM_IR, testDataFilePath); + } + + public void testAllFilesPresentInTypeAnnotations() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxAgainstJava/annotations/typeAnnotations"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); + } + + @TestMetadata("implicitReturn.kt") + public void testImplicitReturn() throws Exception { + runTest("compiler/testData/codegen/boxAgainstJava/annotations/typeAnnotations/implicitReturn.kt"); + } + } } @TestMetadata("compiler/testData/codegen/boxAgainstJava/callableReference") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 04c77a5dea5..9a19e9905e2 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -248,6 +248,34 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/annotations/annotatedLambda/samLambda.kt"); } } + + @TestMetadata("compiler/testData/codegen/box/annotations/typeAnnotations") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class TypeAnnotations extends AbstractIrBlackBoxCodegenTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM_IR, testDataFilePath); + } + + public void testAllFilesPresentInTypeAnnotations() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/annotations/typeAnnotations"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); + } + + @TestMetadata("implicitReturn.kt") + public void testImplicitReturn() throws Exception { + runTest("compiler/testData/codegen/box/annotations/typeAnnotations/implicitReturn.kt"); + } + + @TestMetadata("methodParameters.kt") + public void testMethodParameters() throws Exception { + runTest("compiler/testData/codegen/box/annotations/typeAnnotations/methodParameters.kt"); + } + + @TestMetadata("typeUseAnnotation.kt") + public void testTypeUseAnnotation() throws Exception { + runTest("compiler/testData/codegen/box/annotations/typeAnnotations/typeUseAnnotation.kt"); + } + } } @TestMetadata("compiler/testData/codegen/box/argumentOrder") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrCompileKotlinAgainstKotlinTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrCompileKotlinAgainstKotlinTestGenerated.java index df6dde089f0..bacc25b349e 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrCompileKotlinAgainstKotlinTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrCompileKotlinAgainstKotlinTestGenerated.java @@ -464,4 +464,27 @@ public class IrCompileKotlinAgainstKotlinTestGenerated extends AbstractIrCompile } } } + + @TestMetadata("compiler/testData/compileKotlinAgainstKotlin/typeAnnotations") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class TypeAnnotations extends AbstractIrCompileKotlinAgainstKotlinTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM_IR, testDataFilePath); + } + + public void testAllFilesPresentInTypeAnnotations() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/compileKotlinAgainstKotlin/typeAnnotations"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); + } + + @TestMetadata("implicitReturn.kt") + public void testImplicitReturn() throws Exception { + runTest("compiler/testData/compileKotlinAgainstKotlin/typeAnnotations/implicitReturn.kt"); + } + + @TestMetadata("typeAnnotationTarget6.kt") + public void testTypeAnnotationTarget6() throws Exception { + runTest("compiler/testData/compileKotlinAgainstKotlin/typeAnnotations/typeAnnotationTarget6.kt"); + } + } } diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index 7d734d6345a..b47a33f1f0b 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -78,6 +78,19 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/annotations/annotatedLambda"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true); } } + + @TestMetadata("compiler/testData/codegen/box/annotations/typeAnnotations") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class TypeAnnotations extends AbstractIrJsCodegenBoxTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath); + } + + public void testAllFilesPresentInTypeAnnotations() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/annotations/typeAnnotations"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true); + } + } } @TestMetadata("compiler/testData/codegen/box/argumentOrder") diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index c7022269114..a65f6bb29b6 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -78,6 +78,19 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/annotations/annotatedLambda"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true); } } + + @TestMetadata("compiler/testData/codegen/box/annotations/typeAnnotations") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class TypeAnnotations extends AbstractJsCodegenBoxTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath); + } + + public void testAllFilesPresentInTypeAnnotations() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/annotations/typeAnnotations"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true); + } + } } @TestMetadata("compiler/testData/codegen/box/argumentOrder")