Support type annotations
#KT-35843 Fixed
This commit is contained in:
@@ -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<TypePathInfo> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<AnnotationDescriptor>
|
||||
)
|
||||
|
||||
private class State(val type: Int, val path: MutableList<String>) {
|
||||
|
||||
val results = arrayListOf<TypePathInfo>()
|
||||
|
||||
|
||||
fun addStep(step: String) {
|
||||
path.add(step)
|
||||
}
|
||||
|
||||
fun removeStep(step: String) {
|
||||
path.removeAt(path.lastIndex)
|
||||
}
|
||||
|
||||
fun rememberAnnotations(annotations: List<AnnotationDescriptor>) {
|
||||
results.add(TypePathInfo(TypePath.fromString(path.joinToString("")), annotations))
|
||||
}
|
||||
}
|
||||
|
||||
class TypeAnnotationCollector {
|
||||
|
||||
private lateinit var state: State
|
||||
|
||||
fun collectTypeAnnotations(kotlinType: KotlinType, annotationType: Int): ArrayList<TypePathInfo> {
|
||||
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
|
||||
}
|
||||
|
||||
}
|
||||
+6
@@ -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<AnalysisFlag<*>, Any> {
|
||||
val result = super.configureAnalysisFlags(collector)
|
||||
result[JvmAnalysisFlags.strictMetadataVersionSemantics] = strictMetadataVersionSemantics
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -110,4 +110,7 @@ public class JVMConfigurationKeys {
|
||||
|
||||
public static final CompilerConfigurationKey<Boolean> ENABLE_JVM_DEFAULT =
|
||||
CompilerConfigurationKey.create("Allow to use '@JvmDefault'");
|
||||
|
||||
public static final CompilerConfigurationKey<Boolean> EMIT_JVM_TYPE_ANNOTATIONS =
|
||||
CompilerConfigurationKey.create("Emit JVM type annotations in bytecode");
|
||||
}
|
||||
|
||||
+1
@@ -18,6 +18,7 @@ where advanced options include:
|
||||
'enable' since language version 1.3
|
||||
-Xdump-declarations-to=<path> 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=<path> 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
|
||||
|
||||
@@ -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<T>
|
||||
|
||||
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 <T> foo(s: @Ann T) {
|
||||
}
|
||||
|
||||
fun <T> fooGeneric(s: @Ann Bar<@Ann2 T>) {
|
||||
}
|
||||
}
|
||||
@@ -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 <init>()
|
||||
}
|
||||
|
||||
public final class foo/Kotlin : java/lang/Object {
|
||||
public void <init>()
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -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") }()
|
||||
}
|
||||
}
|
||||
@@ -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 <clinit>()
|
||||
|
||||
void <init>()
|
||||
|
||||
public java.lang.Object invoke()
|
||||
|
||||
public final foo.Kotlin invoke()
|
||||
}
|
||||
|
||||
public final class foo/Kotlin : java/lang/Object {
|
||||
public void <init>(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 <init>(java.lang.String s)
|
||||
@Lfoo/TypeAnn;([name="private"]) : METHOD_FORMAL_PARAMETER 0, null
|
||||
|
||||
public void <init>(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()
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
public final class foo/Kotlin : java/lang/Object {
|
||||
public void <init>()
|
||||
|
||||
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()
|
||||
}
|
||||
@@ -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() {}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
final class foo/Kotlin$A : foo/Kotlin {
|
||||
void <init>(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 <clinit>()
|
||||
|
||||
private void <init>(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 <init>(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 {
|
||||
|
||||
}
|
||||
@@ -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) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
public final class foo/Kotlin : java/lang/Object {
|
||||
public void <init>()
|
||||
|
||||
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()
|
||||
}
|
||||
@@ -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() }()
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
final class foo/Kotlin$foo4$1 : kotlin/jvm/internal/Lambda, kotlin/jvm/functions/Function0 {
|
||||
final foo.Kotlin this$0
|
||||
|
||||
void <init>(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 <init>()
|
||||
|
||||
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 {
|
||||
|
||||
}
|
||||
@@ -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) {}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
public final class foo/Kotlin$Inner : java/lang/Object {
|
||||
final foo.Kotlin this$0
|
||||
|
||||
public void <init>(foo.Kotlin $outer, java.lang.String s)
|
||||
@Lfoo/TypeAnn;([]) : METHOD_FORMAL_PARAMETER 0, null
|
||||
}
|
||||
|
||||
public final class foo/Kotlin : java/lang/Object {
|
||||
public void <init>()
|
||||
}
|
||||
|
||||
public abstract interface foo/TypeAnn : java/lang/Object, java/lang/annotation/Annotation {
|
||||
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
public final class foo/FooClass : java/lang/Object {
|
||||
public void <init>()
|
||||
|
||||
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()
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
public final class foo/Foo : java/lang/Object {
|
||||
public final static foo.Foo INSTANCE
|
||||
|
||||
static void <clinit>()
|
||||
|
||||
private void <init>()
|
||||
|
||||
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 <init>()
|
||||
|
||||
public void <init>(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 <clinit>()
|
||||
|
||||
public void <init>()
|
||||
|
||||
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()
|
||||
}
|
||||
@@ -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<T>
|
||||
|
||||
class Outer {
|
||||
inner class Inner<T>
|
||||
}
|
||||
|
||||
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<in @Ann2 Outer.Inner<@Ann3 String>>) {
|
||||
}
|
||||
|
||||
fun fooArrayOut(): @Ann Array<out @Ann2 Outer.Inner<@Ann3 String>>? {
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
fun <T> fooGenericIn(s: @Ann Bar<in @Ann2 T>) {
|
||||
}
|
||||
|
||||
fun <T> fooGenericOut(s: @Ann Bar<out @Ann2 T>) {
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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 <init>()
|
||||
}
|
||||
|
||||
public final class foo/Kotlin : java/lang/Object {
|
||||
public void <init>()
|
||||
|
||||
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 <init>(foo.Outer $outer)
|
||||
}
|
||||
|
||||
public final class foo/Outer : java/lang/Object {
|
||||
public void <init>()
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
final class foo/Kotlin$fooArray2$1 : kotlin/jvm/internal/Lambda, kotlin/jvm/functions/Function0 {
|
||||
final foo.Kotlin this$0
|
||||
|
||||
void <init>(foo.Kotlin p0)
|
||||
|
||||
public java.lang.Object invoke()
|
||||
|
||||
public final void invoke()
|
||||
}
|
||||
|
||||
public final class foo/Kotlin : java/lang/Object {
|
||||
public void <init>()
|
||||
|
||||
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 {
|
||||
|
||||
}
|
||||
@@ -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>) {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
public final class foo/Kotlin : java/lang/Object {
|
||||
public void <init>()
|
||||
|
||||
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()
|
||||
}
|
||||
@@ -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<T>
|
||||
|
||||
class Outer {
|
||||
class NestedStatic<T>
|
||||
}
|
||||
|
||||
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<in @Ann2 Outer.NestedStatic<@Ann3 String>>) {
|
||||
}
|
||||
|
||||
fun fooArrayOut(): @Ann Array<out @Ann2 Outer.NestedStatic<@Ann3 String>>? {
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
fun <T> fooGenericIn(s: @Ann Bar<in @Ann2 T>) {
|
||||
}
|
||||
|
||||
fun <T> fooGenericOut(s: @Ann Bar<out @Ann2 T>) {
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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 <init>()
|
||||
}
|
||||
|
||||
public final class foo/Kotlin : java/lang/Object {
|
||||
public void <init>()
|
||||
|
||||
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 <init>()
|
||||
}
|
||||
|
||||
public final class foo/Outer : java/lang/Object {
|
||||
public void <init>()
|
||||
}
|
||||
@@ -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()
|
||||
+57
@@ -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()
|
||||
+65
@@ -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()
|
||||
+76
@@ -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()
|
||||
+66
@@ -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()
|
||||
+60
@@ -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()
|
||||
+36
-6
@@ -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<TestFile>) {
|
||||
@@ -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<String>, showLocalVariables: Boolean): String {
|
||||
private fun renderClassNode(
|
||||
clazz: ClassNode,
|
||||
showBytecodeForTheseMethods: List<String>,
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+78
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+18
@@ -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")
|
||||
|
||||
+28
@@ -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")
|
||||
|
||||
+23
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+28
@@ -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")
|
||||
|
||||
+28
@@ -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")
|
||||
|
||||
Generated
+18
@@ -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")
|
||||
|
||||
+28
@@ -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")
|
||||
|
||||
Generated
+23
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Generated
+13
@@ -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")
|
||||
|
||||
+13
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user