Sort parameters of Java annotation constructors by name for stability
This commit is contained in:
+27
@@ -0,0 +1,27 @@
|
|||||||
|
// WITH_REFLECT
|
||||||
|
// FILE: J.java
|
||||||
|
|
||||||
|
public @interface J {
|
||||||
|
short s();
|
||||||
|
long j();
|
||||||
|
boolean z();
|
||||||
|
int i();
|
||||||
|
float f();
|
||||||
|
char c();
|
||||||
|
double d();
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: K.kt
|
||||||
|
|
||||||
|
import kotlin.reflect.KParameter
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val ctor = J::class.constructors.single()
|
||||||
|
|
||||||
|
// We sort parameters by name for consistency
|
||||||
|
assertEquals(listOf("c", "d", "f", "i", "j", "s", "z"), ctor.parameters.map { it.name })
|
||||||
|
assert(ctor.parameters.all { it.kind == KParameter.Kind.VALUE })
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
@@ -13005,6 +13005,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("javaAnnotationConstructor.kt")
|
||||||
|
public void testJavaAnnotationConstructor() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/parameters/javaAnnotationConstructor.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("javaParametersHaveNoNames.kt")
|
@TestMetadata("javaParametersHaveNoNames.kt")
|
||||||
public void testJavaParametersHaveNoNames() throws Exception {
|
public void testJavaParametersHaveNoNames() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/parameters/javaParametersHaveNoNames.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/parameters/javaParametersHaveNoNames.kt");
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package kotlin.reflect.jvm.internal
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
|
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor
|
||||||
import java.lang.reflect.Type
|
import java.lang.reflect.Type
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.reflect.*
|
import kotlin.reflect.*
|
||||||
@@ -53,6 +54,13 @@ internal abstract class KCallableImpl<out R> : KCallable<R> {
|
|||||||
result.add(KParameterImpl(this, index++, KParameter.Kind.VALUE) { descriptor.valueParameters[i] })
|
result.add(KParameterImpl(this, index++, KParameter.Kind.VALUE) { descriptor.valueParameters[i] })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Constructor parameters of Java annotations are not ordered in any way, we order them by name here to be more stable.
|
||||||
|
// Note that positional call (via "call") is not allowed unless there's a single non-"value" parameter,
|
||||||
|
// so the order of parameters of Java annotation constructors here can be arbitrary
|
||||||
|
if (isAnnotationConstructor && descriptor is JavaCallableMemberDescriptor) {
|
||||||
|
result.sortBy { it.name }
|
||||||
|
}
|
||||||
|
|
||||||
result.trimToSize()
|
result.trimToSize()
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
@@ -86,6 +94,9 @@ internal abstract class KCallableImpl<out R> : KCallable<R> {
|
|||||||
override val isAbstract: Boolean
|
override val isAbstract: Boolean
|
||||||
get() = descriptor.modality == Modality.ABSTRACT
|
get() = descriptor.modality == Modality.ABSTRACT
|
||||||
|
|
||||||
|
private val isAnnotationConstructor: Boolean
|
||||||
|
get() = name == "<init>" && container.jClass.isAnnotation
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
override fun call(vararg args: Any?): R = reflectionCall {
|
override fun call(vararg args: Any?): R = reflectionCall {
|
||||||
return caller.call(args) as R
|
return caller.call(args) as R
|
||||||
|
|||||||
Reference in New Issue
Block a user