Support JvmName on annotation constructor parameters
#KT-25372 Fixed
This commit is contained in:
committed by
Ilya Gorbunov
parent
dc1f4c7d5b
commit
b55fc818d1
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.config.JvmTarget;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.*;
|
||||
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor;
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
@@ -346,11 +347,22 @@ public abstract class AnnotationCodegen {
|
||||
}
|
||||
|
||||
private void genAnnotationArguments(AnnotationDescriptor annotationDescriptor, AnnotationVisitor annotationVisitor) {
|
||||
ClassDescriptor annotationClass = DescriptorUtilsKt.getAnnotationClass(annotationDescriptor);
|
||||
for (Map.Entry<Name, ConstantValue<?>> entry : annotationDescriptor.getAllValueArguments().entrySet()) {
|
||||
genCompileTimeValue(entry.getKey().asString(), entry.getValue(), annotationVisitor);
|
||||
genCompileTimeValue(getAnnotationArgumentJvmName(annotationClass, entry.getKey()), entry.getValue(), annotationVisitor);
|
||||
}
|
||||
}
|
||||
|
||||
private String getAnnotationArgumentJvmName(@Nullable ClassDescriptor annotationClass, @NotNull Name parameterName) {
|
||||
if (annotationClass == null) return parameterName.asString();
|
||||
|
||||
Collection<PropertyDescriptor> variables =
|
||||
annotationClass.getUnsubstitutedMemberScope().getContributedVariables(parameterName, NoLookupLocation.FROM_BACKEND);
|
||||
if (variables.size() != 1) return parameterName.asString();
|
||||
|
||||
return typeMapper.mapAnnotationParameterName(variables.iterator().next());
|
||||
}
|
||||
|
||||
private void genCompileTimeValue(
|
||||
@Nullable String name,
|
||||
@NotNull ConstantValue<?> value,
|
||||
|
||||
@@ -55,8 +55,7 @@ import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isConstOrHasJvmFieldAn
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvmInterface;
|
||||
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.DELEGATED_PROPERTIES;
|
||||
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.DELEGATED_PROPERTY_METADATA_OWNER;
|
||||
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.FIELD_FOR_PROPERTY;
|
||||
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.SYNTHETIC_METHOD_FOR_PROPERTY;
|
||||
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.*;
|
||||
import static org.jetbrains.kotlin.diagnostics.Errors.EXPECTED_FUNCTION_SOURCE_WITH_DEFAULT_ARGUMENTS_NOT_FOUND;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isCompanionObject;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isInterface;
|
||||
@@ -278,6 +277,7 @@ public class PropertyCodegen {
|
||||
|
||||
PropertyGetterDescriptor getter = descriptor.getGetter();
|
||||
assert getter != null : "Annotation property should have a getter: " + descriptor;
|
||||
v.getSerializationBindings().put(METHOD_FOR_FUNCTION, getter, asmMethod);
|
||||
FunctionCodegen.generateMethodAnnotations(getter, asmMethod, mv, memberCodegen, typeMapper);
|
||||
|
||||
KtExpression defaultValue = loadAnnotationArgumentDefaultValue(parameter, descriptor, expectedAnnotationConstructor);
|
||||
|
||||
@@ -489,7 +489,13 @@ public class KotlinTypeMapper {
|
||||
sw.writeReturnType();
|
||||
mapType(descriptor.getType(), sw, TypeMappingMode.VALUE_FOR_ANNOTATION);
|
||||
sw.writeReturnTypeEnd();
|
||||
return sw.makeJvmMethodSignature(descriptor.getName().asString());
|
||||
return sw.makeJvmMethodSignature(mapAnnotationParameterName(descriptor));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String mapAnnotationParameterName(@NotNull PropertyDescriptor descriptor) {
|
||||
PropertyGetterDescriptor getter = descriptor.getGetter();
|
||||
return getter != null ? mapFunctionName(getter, OwnerKind.IMPLEMENTATION) : descriptor.getName().asString();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// WITH_REFLECT
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
annotation class Anno(@get:JvmName("uglyJvmName") val value: String)
|
||||
|
||||
@Anno(value = "OK")
|
||||
class Foo
|
||||
|
||||
|
||||
annotation class Meta(val anno: Anno)
|
||||
|
||||
@Meta(Anno(value = "OK"))
|
||||
fun bar() {}
|
||||
|
||||
|
||||
fun box(): String {
|
||||
val f = Foo::class.annotations.single()
|
||||
assertEquals("@Anno(uglyJvmName=OK)", f.toString())
|
||||
assertEquals("OK", (f as Anno).value)
|
||||
|
||||
val b = ::bar.annotations.single()
|
||||
assertEquals("@Meta(anno=@Anno(uglyJvmName=OK))", b.toString())
|
||||
assertEquals("OK", (b as Meta).anno.value)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -19,13 +19,22 @@ class A {
|
||||
@JvmName("OK") get
|
||||
}
|
||||
|
||||
annotation class Anno(@get:JvmName("uglyJvmName") val value: String)
|
||||
|
||||
// FILE: B.kt
|
||||
|
||||
import lib.*
|
||||
|
||||
@Anno("OK")
|
||||
fun annotated() {}
|
||||
|
||||
fun box(): String {
|
||||
foo()
|
||||
v = 1
|
||||
consumeInt(v)
|
||||
|
||||
val annoValue = (::annotated.annotations.single() as Anno).value
|
||||
if (annoValue != "OK") return "Fail annotation value: $annoValue"
|
||||
|
||||
return A().OK
|
||||
}
|
||||
|
||||
+5
@@ -12648,6 +12648,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/jvmName"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||
}
|
||||
|
||||
@TestMetadata("annotationProperties.kt")
|
||||
public void testAnnotationProperties() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/jvmName/annotationProperties.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("callableReference.kt")
|
||||
public void testCallableReference() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/jvmName/callableReference.kt");
|
||||
|
||||
+5
@@ -12648,6 +12648,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/jvmName"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||
}
|
||||
|
||||
@TestMetadata("annotationProperties.kt")
|
||||
public void testAnnotationProperties() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/jvmName/annotationProperties.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("callableReference.kt")
|
||||
public void testCallableReference() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/jvmName/callableReference.kt");
|
||||
|
||||
+5
@@ -12648,6 +12648,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/jvmName"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@TestMetadata("annotationProperties.kt")
|
||||
public void testAnnotationProperties() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/jvmName/annotationProperties.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("callableReference.kt")
|
||||
public void testCallableReference() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/jvmName/callableReference.kt");
|
||||
|
||||
Reference in New Issue
Block a user