Support field type annotations
#KT-35843 Fixed
This commit is contained in:
@@ -88,17 +88,23 @@ public abstract class AnnotationCodegen {
|
|||||||
private final InnerClassConsumer innerClassConsumer;
|
private final InnerClassConsumer innerClassConsumer;
|
||||||
private final KotlinTypeMapper typeMapper;
|
private final KotlinTypeMapper typeMapper;
|
||||||
private final ModuleDescriptor module;
|
private final ModuleDescriptor module;
|
||||||
|
private final GenerationState state;
|
||||||
|
|
||||||
private AnnotationCodegen(@NotNull InnerClassConsumer innerClassConsumer, @NotNull GenerationState state) {
|
private AnnotationCodegen(@NotNull InnerClassConsumer innerClassConsumer, @NotNull GenerationState state) {
|
||||||
this.innerClassConsumer = innerClassConsumer;
|
this.innerClassConsumer = innerClassConsumer;
|
||||||
this.typeMapper = state.getTypeMapper();
|
this.typeMapper = state.getTypeMapper();
|
||||||
this.module = state.getModule();
|
this.module = state.getModule();
|
||||||
|
this.state = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param returnType can be null if not applicable (e.g. {@code annotated} is a class)
|
* @param returnType can be null if not applicable (e.g. {@code annotated} is a class)
|
||||||
*/
|
*/
|
||||||
public void genAnnotations(@Nullable Annotated annotated, @Nullable Type returnType) {
|
public void genAnnotations(
|
||||||
|
@Nullable Annotated annotated,
|
||||||
|
@Nullable Type returnType,
|
||||||
|
@Nullable KotlinType typeForTypeAnnotations
|
||||||
|
) {
|
||||||
if (annotated == null) return;
|
if (annotated == null) return;
|
||||||
|
|
||||||
Set<String> annotationDescriptorsAlreadyPresent = new HashSet<>();
|
Set<String> annotationDescriptorsAlreadyPresent = new HashSet<>();
|
||||||
@@ -126,13 +132,14 @@ public abstract class AnnotationCodegen {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String descriptor = genAnnotation(annotation);
|
String descriptor = genAnnotation(annotation, null, false);
|
||||||
if (descriptor != null) {
|
if (descriptor != null) {
|
||||||
annotationDescriptorsAlreadyPresent.add(descriptor);
|
annotationDescriptorsAlreadyPresent.add(descriptor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
generateAdditionalAnnotations(annotated, returnType, annotationDescriptorsAlreadyPresent);
|
generateAdditionalAnnotations(annotated, returnType, annotationDescriptorsAlreadyPresent);
|
||||||
|
generateTypeAnnotations(typeForTypeAnnotations);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateAdditionalAnnotations(
|
private void generateAdditionalAnnotations(
|
||||||
@@ -322,7 +329,11 @@ public abstract class AnnotationCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private String genAnnotation(@NotNull AnnotationDescriptor annotationDescriptor) {
|
private String genAnnotation(
|
||||||
|
@NotNull AnnotationDescriptor annotationDescriptor,
|
||||||
|
@Nullable TypePath path,
|
||||||
|
boolean isTypeAnnotation
|
||||||
|
) {
|
||||||
ClassDescriptor classDescriptor = getAnnotationClass(annotationDescriptor);
|
ClassDescriptor classDescriptor = getAnnotationClass(annotationDescriptor);
|
||||||
assert classDescriptor != null : "Annotation descriptor has no class: " + annotationDescriptor;
|
assert classDescriptor != null : "Annotation descriptor has no class: " + annotationDescriptor;
|
||||||
RetentionPolicy rp = getRetentionPolicy(classDescriptor);
|
RetentionPolicy rp = getRetentionPolicy(classDescriptor);
|
||||||
@@ -340,7 +351,9 @@ public abstract class AnnotationCodegen {
|
|||||||
innerClassConsumer.addInnerClassInfoFromAnnotation(classDescriptor);
|
innerClassConsumer.addInnerClassInfoFromAnnotation(classDescriptor);
|
||||||
|
|
||||||
String asmTypeDescriptor = typeMapper.mapType(annotationDescriptor.getType()).getDescriptor();
|
String asmTypeDescriptor = typeMapper.mapType(annotationDescriptor.getType()).getDescriptor();
|
||||||
AnnotationVisitor annotationVisitor = visitAnnotation(asmTypeDescriptor, rp == RetentionPolicy.RUNTIME);
|
AnnotationVisitor annotationVisitor = isTypeAnnotation
|
||||||
|
? visitTypeAnnotation(asmTypeDescriptor, path, rp == RetentionPolicy.RUNTIME)
|
||||||
|
: visitAnnotation(asmTypeDescriptor, rp == RetentionPolicy.RUNTIME);
|
||||||
|
|
||||||
genAnnotationArguments(annotationDescriptor, annotationVisitor);
|
genAnnotationArguments(annotationDescriptor, annotationVisitor);
|
||||||
annotationVisitor.visitEnd();
|
annotationVisitor.visitEnd();
|
||||||
@@ -553,6 +566,11 @@ public abstract class AnnotationCodegen {
|
|||||||
@NotNull
|
@NotNull
|
||||||
abstract AnnotationVisitor visitAnnotation(String descr, boolean visible);
|
abstract AnnotationVisitor visitAnnotation(String descr, boolean visible);
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
AnnotationVisitor visitTypeAnnotation(String descr, TypePath path, boolean visible) {
|
||||||
|
throw new RuntimeException("Not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
public static AnnotationCodegen forClass(
|
public static AnnotationCodegen forClass(
|
||||||
@NotNull ClassVisitor cv,
|
@NotNull ClassVisitor cv,
|
||||||
@NotNull InnerClassConsumer innerClassConsumer,
|
@NotNull InnerClassConsumer innerClassConsumer,
|
||||||
@@ -578,6 +596,12 @@ public abstract class AnnotationCodegen {
|
|||||||
AnnotationVisitor visitAnnotation(String descr, boolean visible) {
|
AnnotationVisitor visitAnnotation(String descr, boolean visible) {
|
||||||
return safe(mv.visitAnnotation(descr, visible));
|
return safe(mv.visitAnnotation(descr, visible));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
AnnotationVisitor visitTypeAnnotation(String descr, TypePath path, boolean visible) {
|
||||||
|
return safe(mv.visitTypeAnnotation(TypeReference.newTypeReference(TypeReference.METHOD_RETURN).getValue(), path, descr, visible));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -592,6 +616,12 @@ public abstract class AnnotationCodegen {
|
|||||||
AnnotationVisitor visitAnnotation(String descr, boolean visible) {
|
AnnotationVisitor visitAnnotation(String descr, boolean visible) {
|
||||||
return safe(fv.visitAnnotation(descr, visible));
|
return safe(fv.visitAnnotation(descr, visible));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
AnnotationVisitor visitTypeAnnotation(String descr, TypePath path, boolean visible) {
|
||||||
|
return safe(fv.visitTypeAnnotation(TypeReference.newTypeReference(TypeReference.FIELD).getValue(), path, descr, visible));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -607,6 +637,12 @@ public abstract class AnnotationCodegen {
|
|||||||
AnnotationVisitor visitAnnotation(String descr, boolean visible) {
|
AnnotationVisitor visitAnnotation(String descr, boolean visible) {
|
||||||
return safe(mv.visitParameterAnnotation(parameter, descr, visible));
|
return safe(mv.visitParameterAnnotation(parameter, descr, visible));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
AnnotationVisitor visitTypeAnnotation(String descr, TypePath path, boolean visible) {
|
||||||
|
return safe(mv.visitTypeAnnotation(TypeReference.newFormalParameterReference(parameter).getValue(), path, descr, visible));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -629,13 +665,7 @@ public abstract class AnnotationCodegen {
|
|||||||
return av == null ? NO_ANNOTATION_VISITOR : av;
|
return av == null ? NO_ANNOTATION_VISITOR : av;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void writeTypeAnnotations(
|
private void generateTypeAnnotations(@Nullable KotlinType type) {
|
||||||
@NotNull MethodVisitor mv,
|
|
||||||
@NotNull GenerationState state,
|
|
||||||
int parameterIndex,
|
|
||||||
@Nullable KotlinType type,
|
|
||||||
@NotNull InnerClassConsumer innerClassConsumer
|
|
||||||
) {
|
|
||||||
if (type == null ||
|
if (type == null ||
|
||||||
state.getTarget() == JvmTarget.JVM_1_6 ||
|
state.getTarget() == JvmTarget.JVM_1_6 ||
|
||||||
!state.getConfiguration().getBoolean(JVMConfigurationKeys.EMIT_JVM_TYPE_ANNOTATIONS)) {
|
!state.getConfiguration().getBoolean(JVMConfigurationKeys.EMIT_JVM_TYPE_ANNOTATIONS)) {
|
||||||
@@ -646,18 +676,7 @@ public abstract class AnnotationCodegen {
|
|||||||
new TypeAnnotationCollector().collectTypeAnnotations(type, TypeReference.METHOD_FORMAL_PARAMETER);
|
new TypeAnnotationCollector().collectTypeAnnotations(type, TypeReference.METHOD_FORMAL_PARAMETER);
|
||||||
for (TypePathInfo info : infos) {
|
for (TypePathInfo info : infos) {
|
||||||
for (AnnotationDescriptor annotationDescriptor : info.getAnnotations()) {
|
for (AnnotationDescriptor annotationDescriptor : info.getAnnotations()) {
|
||||||
TypeReference typeReference = parameterIndex != -1 ?
|
genAnnotation(annotationDescriptor, info.getPath(), true);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-1
@@ -150,7 +150,11 @@ class DefaultParameterValueSubstitutor(val state: GenerationState) {
|
|||||||
FunctionCodegen.getThrownExceptions(functionDescriptor, typeMapper)
|
FunctionCodegen.getThrownExceptions(functionDescriptor, typeMapper)
|
||||||
)
|
)
|
||||||
|
|
||||||
AnnotationCodegen.forMethod(mv, memberCodegen, state).genAnnotations(functionDescriptor, signature.returnType)
|
AnnotationCodegen.forMethod(mv, memberCodegen, state).genAnnotations(
|
||||||
|
functionDescriptor,
|
||||||
|
signature.returnType,
|
||||||
|
functionDescriptor.returnType
|
||||||
|
)
|
||||||
|
|
||||||
if (state.classBuilderMode == ClassBuilderMode.KAPT3) {
|
if (state.classBuilderMode == ClassBuilderMode.KAPT3) {
|
||||||
mv.visitAnnotation(ANNOTATION_TYPE_DESCRIPTOR_FOR_JVM_OVERLOADS_GENERATED_METHODS, false)
|
mv.visitAnnotation(ANNOTATION_TYPE_DESCRIPTOR_FOR_JVM_OVERLOADS_GENERATED_METHODS, false)
|
||||||
|
|||||||
@@ -303,7 +303,9 @@ public class FunctionCodegen {
|
|||||||
annotationsOwner = functionDescriptor;
|
annotationsOwner = functionDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
AnnotationCodegen.forMethod(mv, memberCodegen, state).genAnnotations(annotationsOwner, asmMethod.getReturnType());
|
AnnotationCodegen.forMethod(mv, memberCodegen, state)
|
||||||
|
.genAnnotations(annotationsOwner, asmMethod.getReturnType(), functionDescriptor.getReturnType());
|
||||||
|
|
||||||
generateParameterAnnotations(annotationsOwner, mv, jvmSignature, memberCodegen, state);
|
generateParameterAnnotations(annotationsOwner, mv, jvmSignature, memberCodegen, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -544,13 +546,9 @@ public class FunctionCodegen {
|
|||||||
//noinspection ConstantConditions
|
//noinspection ConstantConditions
|
||||||
int parameterIndex = i - syntheticParameterCount;
|
int parameterIndex = i - syntheticParameterCount;
|
||||||
AnnotationCodegen.forParameter(parameterIndex, mv, innerClassConsumer, state)
|
AnnotationCodegen.forParameter(parameterIndex, mv, innerClassConsumer, state)
|
||||||
.genAnnotations(annotated, parameterSignature.getAsmType());
|
.genAnnotations(annotated, parameterSignature.getAsmType(), annotated.getReturnType());
|
||||||
|
|
||||||
AnnotationCodegen.writeTypeAnnotations(mv, state, parameterIndex, annotated.getType(), innerClassConsumer);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AnnotationCodegen.writeTypeAnnotations(mv, state, -1, functionDescriptor.getReturnType(), innerClassConsumer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|||||||
@@ -232,7 +232,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
|
|
||||||
writeEnclosingMethod();
|
writeEnclosingMethod();
|
||||||
|
|
||||||
AnnotationCodegen.forClass(v.getVisitor(), this, state).genAnnotations(descriptor, null);
|
AnnotationCodegen.forClass(v.getVisitor(), this, state).genAnnotations(descriptor, null, null);
|
||||||
|
|
||||||
generateEnumEntries();
|
generateEnumEntries();
|
||||||
}
|
}
|
||||||
@@ -905,7 +905,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
type.getDescriptor(), typeMapper.mapFieldSignature(property.getType(), property),
|
type.getDescriptor(), typeMapper.mapFieldSignature(property.getType(), property),
|
||||||
info.defaultValue);
|
info.defaultValue);
|
||||||
|
|
||||||
AnnotationCodegen.forField(fv, this, state).genAnnotations(property, type);
|
AnnotationCodegen.forField(fv, this, state).genAnnotations(property, type, null);
|
||||||
|
|
||||||
//This field are always static and final so if it has constant initializer don't do anything in clinit,
|
//This field are always static and final so if it has constant initializer don't do anything in clinit,
|
||||||
//field would be initialized via default value in v.newField(...) - see JVM SPEC Ch.4
|
//field would be initialized via default value in v.newField(...) - see JVM SPEC Ch.4
|
||||||
@@ -1087,7 +1087,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
int isDeprecated = KotlinBuiltIns.isDeprecated(descriptor) ? ACC_DEPRECATED : 0;
|
int isDeprecated = KotlinBuiltIns.isDeprecated(descriptor) ? ACC_DEPRECATED : 0;
|
||||||
FieldVisitor fv = v.newField(JvmDeclarationOriginKt.OtherOrigin(enumEntry, descriptor), ACC_PUBLIC | ACC_ENUM | ACC_STATIC | ACC_FINAL | isDeprecated,
|
FieldVisitor fv = v.newField(JvmDeclarationOriginKt.OtherOrigin(enumEntry, descriptor), ACC_PUBLIC | ACC_ENUM | ACC_STATIC | ACC_FINAL | isDeprecated,
|
||||||
descriptor.getName().asString(), classAsmType.getDescriptor(), null, null);
|
descriptor.getName().asString(), classAsmType.getDescriptor(), null, null);
|
||||||
AnnotationCodegen.forField(fv, this, state).genAnnotations(descriptor, null);
|
AnnotationCodegen.forField(fv, this, state).genAnnotations(descriptor, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
initializeEnumConstants(enumEntries);
|
initializeEnumConstants(enumEntries);
|
||||||
|
|||||||
@@ -261,7 +261,7 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
|
|||||||
int flags = ACC_DEPRECATED | ACC_STATIC | ACC_SYNTHETIC | AsmUtil.getVisibilityAccessFlag(descriptor);
|
int flags = ACC_DEPRECATED | ACC_STATIC | ACC_SYNTHETIC | AsmUtil.getVisibilityAccessFlag(descriptor);
|
||||||
MethodVisitor mv = v.newMethod(JvmDeclarationOriginKt.OtherOrigin(descriptor), flags, syntheticMethod.getName(),
|
MethodVisitor mv = v.newMethod(JvmDeclarationOriginKt.OtherOrigin(descriptor), flags, syntheticMethod.getName(),
|
||||||
syntheticMethod.getDescriptor(), null, null);
|
syntheticMethod.getDescriptor(), null, null);
|
||||||
AnnotationCodegen.forMethod(mv, this, state).genAnnotations(new AnnotatedImpl(annotations), Type.VOID_TYPE);
|
AnnotationCodegen.forMethod(mv, this, state).genAnnotations(new AnnotatedImpl(annotations), Type.VOID_TYPE, null);
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
mv.visitInsn(Opcodes.RETURN);
|
mv.visitInsn(Opcodes.RETURN);
|
||||||
mv.visitEnd();
|
mv.visitEnd();
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ public class PackagePartCodegen extends MemberCodegen<KtFile> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Annotated annotatedFile = new AnnotatedImpl(Annotations.Companion.create(fileAnnotationDescriptors));
|
Annotated annotatedFile = new AnnotatedImpl(Annotations.Companion.create(fileAnnotationDescriptors));
|
||||||
AnnotationCodegen.forClass(v.getVisitor(), this, state).genAnnotations(annotatedFile, null);
|
AnnotationCodegen.forClass(v.getVisitor(), this, state).genAnnotations(annotatedFile, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -270,7 +270,7 @@ public class PropertyCodegen {
|
|||||||
PropertyGetterDescriptor getter = descriptor.getGetter();
|
PropertyGetterDescriptor getter = descriptor.getGetter();
|
||||||
assert getter != null : "Annotation property should have a getter: " + descriptor;
|
assert getter != null : "Annotation property should have a getter: " + descriptor;
|
||||||
v.getSerializationBindings().put(METHOD_FOR_FUNCTION, getter, asmMethod);
|
v.getSerializationBindings().put(METHOD_FOR_FUNCTION, getter, asmMethod);
|
||||||
AnnotationCodegen.forMethod(mv, memberCodegen, state).genAnnotations(getter, asmMethod.getReturnType());
|
AnnotationCodegen.forMethod(mv, memberCodegen, state).genAnnotations(getter, asmMethod.getReturnType(), null);
|
||||||
|
|
||||||
KtExpression defaultValue = loadAnnotationArgumentDefaultValue(parameter, descriptor, expectedAnnotationConstructor);
|
KtExpression defaultValue = loadAnnotationArgumentDefaultValue(parameter, descriptor, expectedAnnotationConstructor);
|
||||||
if (defaultValue != null) {
|
if (defaultValue != null) {
|
||||||
@@ -417,7 +417,8 @@ public class PropertyCodegen {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (annotatedField != null) {
|
if (annotatedField != null) {
|
||||||
AnnotationCodegen.forField(fv, memberCodegen, state).genAnnotations(annotatedField, type);
|
AnnotationCodegen.forField(fv, memberCodegen, state)
|
||||||
|
.genAnnotations(annotatedField, type, propertyDescriptor.getType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ class ScriptCodegen private constructor(
|
|||||||
typeMapper.mapSupertype(it.defaultType, null).internalName
|
typeMapper.mapSupertype(it.defaultType, null).internalName
|
||||||
}.toTypedArray()
|
}.toTypedArray()
|
||||||
)
|
)
|
||||||
AnnotationCodegen.forClass(v.visitor, this, state).genAnnotations(scriptDescriptor, null)
|
AnnotationCodegen.forClass(v.visitor, this, state).genAnnotations(scriptDescriptor, null, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun generateBody() {
|
override fun generateBody() {
|
||||||
@@ -99,7 +99,8 @@ class ScriptCodegen private constructor(
|
|||||||
OtherOrigin(scriptDeclaration, scriptDescriptor.unsubstitutedPrimaryConstructor),
|
OtherOrigin(scriptDeclaration, scriptDescriptor.unsubstitutedPrimaryConstructor),
|
||||||
ACC_PUBLIC, jvmSignature.asmMethod.name, jvmSignature.asmMethod.descriptor, null, null)
|
ACC_PUBLIC, jvmSignature.asmMethod.name, jvmSignature.asmMethod.descriptor, null, null)
|
||||||
|
|
||||||
AnnotationCodegen.forMethod(mv, this, state).genAnnotations(scriptDescriptor.unsubstitutedPrimaryConstructor, asmMethod.returnType)
|
AnnotationCodegen.forMethod(mv, this, state)
|
||||||
|
.genAnnotations(scriptDescriptor.unsubstitutedPrimaryConstructor, asmMethod.returnType, null)
|
||||||
|
|
||||||
if (state.classBuilderMode.generateBodies) {
|
if (state.classBuilderMode.generateBodies) {
|
||||||
mv.visitCode()
|
mv.visitCode()
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ public final class foo/Kotlin : java/lang/Object {
|
|||||||
public void <init>()
|
public void <init>()
|
||||||
|
|
||||||
public final java.lang.Object foo(java.lang.String s, int x)
|
public final java.lang.Object foo(java.lang.String s, int x)
|
||||||
|
@Lfoo/TypeAnn;([name="return"]) : METHOD_RETURN, null
|
||||||
@Lfoo/TypeAnn;([name="1"]) : METHOD_FORMAL_PARAMETER 0, null
|
@Lfoo/TypeAnn;([name="1"]) : METHOD_FORMAL_PARAMETER 0, null
|
||||||
@Lfoo/TypeAnn;([name="2"]) : METHOD_FORMAL_PARAMETER 1, 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 static java.lang.Object foo$default(foo.Kotlin p0, java.lang.String p1, int p2, int p3, java.lang.Object p4)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,13 +2,13 @@ public final class foo/FooClass : java/lang/Object {
|
|||||||
public void <init>()
|
public void <init>()
|
||||||
|
|
||||||
public final java.lang.Object foo(java.lang.String s, int x)
|
public final java.lang.Object foo(java.lang.String s, int x)
|
||||||
|
@Lfoo/TypeAnn;([name="return"]) : METHOD_RETURN, null
|
||||||
@Lfoo/TypeAnn;([name="1"]) : METHOD_FORMAL_PARAMETER 0, null
|
@Lfoo/TypeAnn;([name="1"]) : METHOD_FORMAL_PARAMETER 0, null
|
||||||
@Lfoo/TypeAnn;([name="2"]) : METHOD_FORMAL_PARAMETER 1, 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)
|
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
|
@Lfoo/TypeAnn;([name="return"]) : METHOD_RETURN, null
|
||||||
|
@Lfoo/TypeAnn;([name="1"]) : METHOD_FORMAL_PARAMETER 0, null
|
||||||
|
|
||||||
public final java.lang.Object foo()
|
public final java.lang.Object foo()
|
||||||
@Lfoo/TypeAnn;([name="return"]) : METHOD_RETURN, null
|
@Lfoo/TypeAnn;([name="return"]) : METHOD_RETURN, null
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ public final class foo/Foo : java/lang/Object {
|
|||||||
private void <init>()
|
private void <init>()
|
||||||
|
|
||||||
public final static java.lang.Object foo(java.lang.String s, int x)
|
public final static java.lang.Object foo(java.lang.String s, int x)
|
||||||
|
@Lfoo/TypeAnn;([name="return"]) : METHOD_RETURN, null
|
||||||
@Lfoo/TypeAnn;([name="1"]) : METHOD_FORMAL_PARAMETER 0, null
|
@Lfoo/TypeAnn;([name="1"]) : METHOD_FORMAL_PARAMETER 0, null
|
||||||
@Lfoo/TypeAnn;([name="2"]) : METHOD_FORMAL_PARAMETER 1, 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 {
|
public final class foo/FooClass$Companion : java/lang/Object {
|
||||||
@@ -17,9 +17,9 @@ public final class foo/FooClass$Companion : java/lang/Object {
|
|||||||
public void <init>(kotlin.jvm.internal.DefaultConstructorMarker $constructor_marker)
|
public void <init>(kotlin.jvm.internal.DefaultConstructorMarker $constructor_marker)
|
||||||
|
|
||||||
public final java.lang.Object foo(java.lang.String s, int x)
|
public final java.lang.Object foo(java.lang.String s, int x)
|
||||||
|
@Lfoo/TypeAnn;([name="return"]) : METHOD_RETURN, null
|
||||||
@Lfoo/TypeAnn;([name="1"]) : METHOD_FORMAL_PARAMETER 0, null
|
@Lfoo/TypeAnn;([name="1"]) : METHOD_FORMAL_PARAMETER 0, null
|
||||||
@Lfoo/TypeAnn;([name="2"]) : METHOD_FORMAL_PARAMETER 1, 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 class foo/FooClass : java/lang/Object {
|
||||||
@@ -30,9 +30,9 @@ public final class foo/FooClass : java/lang/Object {
|
|||||||
public void <init>()
|
public void <init>()
|
||||||
|
|
||||||
public final static java.lang.Object foo(java.lang.String s, int x)
|
public final static java.lang.Object foo(java.lang.String s, int x)
|
||||||
|
@Lfoo/TypeAnn;([name="return"]) : METHOD_RETURN, null
|
||||||
@Lfoo/TypeAnn;([name="1"]) : METHOD_FORMAL_PARAMETER 0, null
|
@Lfoo/TypeAnn;([name="1"]) : METHOD_FORMAL_PARAMETER 0, null
|
||||||
@Lfoo/TypeAnn;([name="2"]) : METHOD_FORMAL_PARAMETER 1, 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 interface foo/TypeAnn : java/lang/Object, java/lang/annotation/Annotation {
|
||||||
|
|||||||
@@ -37,7 +37,16 @@ class Kotlin {
|
|||||||
|
|
||||||
lateinit var lateinitProp: @TypeAnn("1") @TypeAnnBinary @TypeAnnSource String
|
lateinit var lateinitProp: @TypeAnn("1") @TypeAnnBinary @TypeAnnSource String
|
||||||
|
|
||||||
|
val annotatedGetter: Int
|
||||||
|
get(): @TypeAnn("1") @TypeAnnBinary @TypeAnnSource Int = 123
|
||||||
|
|
||||||
|
val unannotatedGetter: @TypeAnn("1") @TypeAnnBinary @TypeAnnSource Int
|
||||||
|
get(): Int = 123
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
var companionVarProperty: @TypeAnn("1") @TypeAnnBinary @TypeAnnSource String = "123"
|
var companionVarProperty: @TypeAnn("1") @TypeAnnBinary @TypeAnnSource String = "123"
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
var jvmStatic: @TypeAnn("1") @TypeAnnBinary @TypeAnnSource String = "123"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,121 @@
|
|||||||
|
public final class foo/Kotlin$Companion : java/lang/Object {
|
||||||
|
private void <init>()
|
||||||
|
|
||||||
|
public void <init>(kotlin.jvm.internal.DefaultConstructorMarker $constructor_marker)
|
||||||
|
|
||||||
|
public final java.lang.String getCompanionVarProperty()
|
||||||
|
@Lfoo/TypeAnn;([name="1"]) : METHOD_RETURN, null
|
||||||
|
@Lfoo/TypeAnnBinary;([]) : METHOD_RETURN, null // invisible
|
||||||
|
|
||||||
|
public final java.lang.String getJvmStatic()
|
||||||
|
@Lfoo/TypeAnn;([name="1"]) : METHOD_RETURN, null
|
||||||
|
@Lfoo/TypeAnnBinary;([]) : METHOD_RETURN, null // invisible
|
||||||
|
|
||||||
|
public static void jvmStatic$annotations()
|
||||||
|
|
||||||
|
public final void setCompanionVarProperty(java.lang.String <set-?>)
|
||||||
|
@Lfoo/TypeAnn;([name="1"]) : METHOD_FORMAL_PARAMETER 0, null
|
||||||
|
@Lfoo/TypeAnnBinary;([]) : METHOD_FORMAL_PARAMETER 0, null // invisible
|
||||||
|
|
||||||
|
public final void setJvmStatic(java.lang.String <set-?>)
|
||||||
|
@Lfoo/TypeAnn;([name="1"]) : METHOD_FORMAL_PARAMETER 0, null
|
||||||
|
@Lfoo/TypeAnnBinary;([]) : METHOD_FORMAL_PARAMETER 0, null // invisible
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class foo/Kotlin : java/lang/Object {
|
||||||
|
public final static foo.Kotlin$Companion Companion
|
||||||
|
|
||||||
|
private static java.lang.String companionVarProperty
|
||||||
|
@Lfoo/TypeAnn;([name="1"]) : FIELD, null
|
||||||
|
@Lfoo/TypeAnnBinary;([]) : FIELD, null // invisible
|
||||||
|
|
||||||
|
private java.lang.String customSetter
|
||||||
|
@Lfoo/TypeAnn;([name="1"]) : FIELD, null
|
||||||
|
@Lfoo/TypeAnnBinary;([]) : FIELD, null // invisible
|
||||||
|
|
||||||
|
public java.lang.String jvmField
|
||||||
|
@Lfoo/TypeAnn;([name="1"]) : FIELD, null
|
||||||
|
@Lfoo/TypeAnnBinary;([]) : FIELD, null // invisible
|
||||||
|
|
||||||
|
private static java.lang.String jvmStatic
|
||||||
|
@Lfoo/TypeAnn;([name="1"]) : FIELD, null
|
||||||
|
@Lfoo/TypeAnnBinary;([]) : FIELD, null // invisible
|
||||||
|
|
||||||
|
public java.lang.String lateinitProp
|
||||||
|
@Lfoo/TypeAnn;([name="1"]) : FIELD, null
|
||||||
|
@Lfoo/TypeAnnBinary;([]) : FIELD, null // invisible
|
||||||
|
|
||||||
|
private final java.lang.String valProp
|
||||||
|
@Lfoo/TypeAnn;([name="1"]) : FIELD, null
|
||||||
|
@Lfoo/TypeAnnBinary;([]) : FIELD, null // invisible
|
||||||
|
|
||||||
|
private java.lang.String varProp
|
||||||
|
@Lfoo/TypeAnn;([name="1"]) : FIELD, null
|
||||||
|
@Lfoo/TypeAnnBinary;([]) : FIELD, null // invisible
|
||||||
|
|
||||||
|
static void <clinit>()
|
||||||
|
|
||||||
|
public void <init>()
|
||||||
|
|
||||||
|
public final static java.lang.String access$getCompanionVarProperty$cp()
|
||||||
|
@Lfoo/TypeAnn;([name="1"]) : METHOD_RETURN, null
|
||||||
|
@Lfoo/TypeAnnBinary;([]) : METHOD_RETURN, null // invisible
|
||||||
|
|
||||||
|
public final static java.lang.String access$getJvmStatic$cp()
|
||||||
|
|
||||||
|
public final static void access$setCompanionVarProperty$cp(java.lang.String <set-?>)
|
||||||
|
|
||||||
|
public final static void access$setJvmStatic$cp(java.lang.String <set-?>)
|
||||||
|
|
||||||
|
public final int getAnnotatedGetter()
|
||||||
|
@Lfoo/TypeAnn;([name="1"]) : METHOD_RETURN, null
|
||||||
|
@Lfoo/TypeAnnBinary;([]) : METHOD_RETURN, null // invisible
|
||||||
|
|
||||||
|
public final java.lang.String getCustomSetter()
|
||||||
|
@Lfoo/TypeAnn;([name="1"]) : METHOD_RETURN, null
|
||||||
|
@Lfoo/TypeAnnBinary;([]) : METHOD_RETURN, null // invisible
|
||||||
|
|
||||||
|
public final static java.lang.String getJvmStatic()
|
||||||
|
@Lfoo/TypeAnn;([name="1"]) : METHOD_RETURN, null
|
||||||
|
@Lfoo/TypeAnnBinary;([]) : METHOD_RETURN, null // invisible
|
||||||
|
|
||||||
|
public final java.lang.String getLateinitProp()
|
||||||
|
@Lfoo/TypeAnn;([name="1"]) : METHOD_RETURN, null
|
||||||
|
@Lfoo/TypeAnnBinary;([]) : METHOD_RETURN, null // invisible
|
||||||
|
|
||||||
|
public final int getUnannotatedGetter()
|
||||||
|
|
||||||
|
public final java.lang.String getValProp()
|
||||||
|
@Lfoo/TypeAnn;([name="1"]) : METHOD_RETURN, null
|
||||||
|
@Lfoo/TypeAnnBinary;([]) : METHOD_RETURN, null // invisible
|
||||||
|
|
||||||
|
public final java.lang.String getVarProp()
|
||||||
|
@Lfoo/TypeAnn;([name="1"]) : METHOD_RETURN, null
|
||||||
|
@Lfoo/TypeAnnBinary;([]) : METHOD_RETURN, null // invisible
|
||||||
|
|
||||||
|
public final void setCustomSetter(java.lang.String field)
|
||||||
|
|
||||||
|
public final static void setJvmStatic(java.lang.String <set-?>)
|
||||||
|
@Lfoo/TypeAnn;([name="1"]) : METHOD_FORMAL_PARAMETER 0, null
|
||||||
|
@Lfoo/TypeAnnBinary;([]) : METHOD_FORMAL_PARAMETER 0, null // invisible
|
||||||
|
|
||||||
|
public final void setLateinitProp(java.lang.String <set-?>)
|
||||||
|
@Lfoo/TypeAnn;([name="1"]) : METHOD_FORMAL_PARAMETER 0, null
|
||||||
|
@Lfoo/TypeAnnBinary;([]) : METHOD_FORMAL_PARAMETER 0, null // invisible
|
||||||
|
|
||||||
|
public final void setVarProp(java.lang.String <set-?>)
|
||||||
|
@Lfoo/TypeAnn;([name="1"]) : METHOD_FORMAL_PARAMETER 0, null
|
||||||
|
@Lfoo/TypeAnnBinary;([]) : METHOD_FORMAL_PARAMETER 0, 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 {
|
||||||
|
|
||||||
|
}
|
||||||
+17
-2
@@ -14,6 +14,7 @@ import org.jetbrains.org.objectweb.asm.Type
|
|||||||
import org.jetbrains.org.objectweb.asm.tree.*
|
import org.jetbrains.org.objectweb.asm.tree.*
|
||||||
import org.jetbrains.org.objectweb.asm.util.Printer
|
import org.jetbrains.org.objectweb.asm.util.Printer
|
||||||
import org.jetbrains.org.objectweb.asm.util.Textifier
|
import org.jetbrains.org.objectweb.asm.util.Textifier
|
||||||
|
import org.jetbrains.org.objectweb.asm.util.TraceFieldVisitor
|
||||||
import org.jetbrains.org.objectweb.asm.util.TraceMethodVisitor
|
import org.jetbrains.org.objectweb.asm.util.TraceMethodVisitor
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
@@ -75,7 +76,7 @@ abstract class AbstractAsmLikeInstructionListingTest : CodegenTestCase() {
|
|||||||
|
|
||||||
appendln(" {")
|
appendln(" {")
|
||||||
|
|
||||||
fields.joinTo(this, LINE_SEPARATOR.repeat(2)) { renderField(it).withMargin() }
|
fields.joinTo(this, LINE_SEPARATOR.repeat(2)) { renderField(it, showTypeAnnotations).withMargin() }
|
||||||
|
|
||||||
if (fields.isNotEmpty()) {
|
if (fields.isNotEmpty()) {
|
||||||
appendln().appendln()
|
appendln().appendln()
|
||||||
@@ -90,11 +91,25 @@ abstract class AbstractAsmLikeInstructionListingTest : CodegenTestCase() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun renderField(field: FieldNode) = buildString {
|
private fun renderField(field: FieldNode, showTypeAnnotations: Boolean) = buildString {
|
||||||
renderVisibilityModifiers(field.access)
|
renderVisibilityModifiers(field.access)
|
||||||
renderModalityModifiers(field.access)
|
renderModalityModifiers(field.access)
|
||||||
append(Type.getType(field.desc).className).append(' ')
|
append(Type.getType(field.desc).className).append(' ')
|
||||||
append(field.name)
|
append(field.name)
|
||||||
|
|
||||||
|
if (showTypeAnnotations) {
|
||||||
|
val textifier = Textifier()
|
||||||
|
val visitor = TraceFieldVisitor(textifier)
|
||||||
|
field.visibleTypeAnnotations?.forEach {
|
||||||
|
it.accept(visitor.visitTypeAnnotation(it.typeRef, it.typePath, it.desc, true))
|
||||||
|
}
|
||||||
|
field.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()}")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun renderMethod(
|
private fun renderMethod(
|
||||||
|
|||||||
+5
@@ -174,6 +174,11 @@ public class AsmLikeInstructionListingTestGenerated extends AbstractAsmLikeInstr
|
|||||||
runTest("compiler/testData/codegen/asmLike/typeAnnotations/notYetSupported.kt");
|
runTest("compiler/testData/codegen/asmLike/typeAnnotations/notYetSupported.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("property.kt")
|
||||||
|
public void testProperty() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/asmLike/typeAnnotations/property.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("simple.kt")
|
@TestMetadata("simple.kt")
|
||||||
public void testSimple() throws Exception {
|
public void testSimple() throws Exception {
|
||||||
runTest("compiler/testData/codegen/asmLike/typeAnnotations/simple.kt");
|
runTest("compiler/testData/codegen/asmLike/typeAnnotations/simple.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user