CLI: Change kotlin reflection to java reflection
The command line argument parser is using between 0.25s and 0.5s (depending on platform) on finding annotated properties. This fix replaces the slow kotlin reflection with java reflection, which is an order of magnitude faster. #KT-58183 Fixed
This commit is contained in:
committed by
Space Team
parent
b28b0e70b6
commit
111bb461a9
@@ -12,8 +12,8 @@ import org.jetbrains.kotlin.cli.common.arguments.CommonToolArguments
|
||||
import org.jetbrains.kotlin.cli.common.arguments.isAdvanced
|
||||
import org.jetbrains.kotlin.cli.common.arguments.resolvedDelimiter
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.full.findAnnotation
|
||||
import kotlin.reflect.full.memberProperties
|
||||
import kotlin.reflect.jvm.javaField
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
@JvmOverloads
|
||||
@@ -33,7 +33,7 @@ internal fun <T : CommonToolArguments> toArgumentStrings(
|
||||
): List<String> = ArrayList<String>().apply {
|
||||
val defaultArguments = type.newArgumentsInstance()
|
||||
type.memberProperties.forEach { property ->
|
||||
val argumentAnnotation = property.findAnnotation<Argument>() ?: return@forEach
|
||||
val argumentAnnotation = property.javaField?.getAnnotation(Argument::class.java) ?: return@forEach
|
||||
val rawPropertyValue = property.get(thisArguments)
|
||||
val rawDefaultValue = property.get(defaultArguments)
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.config.JvmTarget
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.KProperty1
|
||||
import kotlin.reflect.full.findAnnotation
|
||||
import kotlin.reflect.jvm.javaField
|
||||
|
||||
//used by IJ facet import
|
||||
@SuppressWarnings("unused")
|
||||
@@ -24,7 +25,8 @@ sealed class ExplicitDefaultSubstitutor {
|
||||
abstract fun isSubstitutable(args: List<String>): Boolean
|
||||
|
||||
protected val argument: Argument by lazy {
|
||||
substitutedProperty.findAnnotation() ?: error("Property \"${substitutedProperty.name}\" has no Argument annotation")
|
||||
substitutedProperty.javaField?.getAnnotation(Argument::class.java)
|
||||
?: error("Property \"${substitutedProperty.name}\" has no Argument annotation")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -14,10 +14,10 @@ import org.junit.jupiter.params.provider.MethodSource
|
||||
import java.util.Base64.getEncoder
|
||||
import kotlin.random.Random
|
||||
import kotlin.reflect.*
|
||||
import kotlin.reflect.full.findAnnotation
|
||||
import kotlin.reflect.full.isSubtypeOf
|
||||
import kotlin.reflect.full.memberProperties
|
||||
import kotlin.reflect.full.withNullability
|
||||
import kotlin.reflect.jvm.javaField
|
||||
import kotlin.test.assertContentEquals
|
||||
import kotlin.test.fail
|
||||
|
||||
@@ -72,7 +72,7 @@ class CompilerArgumentParsingTest {
|
||||
private fun assertEqualArguments(expected: CommonToolArguments, actual: CommonToolArguments) {
|
||||
if (expected::class != actual::class) fail("Expected class '${expected::class}', found: '${actual::class}'")
|
||||
expected::class.memberProperties
|
||||
.filter { it.findAnnotation<Argument>() != null }
|
||||
.filter { it.javaField?.getAnnotation(Argument::class.java) != null }
|
||||
.ifEmpty { fail("No members with ${Argument::class} annotation") }
|
||||
.map { property ->
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
|
||||
+2
-2
@@ -11,8 +11,8 @@ import org.junit.jupiter.params.ParameterizedTest
|
||||
import org.junit.jupiter.params.provider.MethodSource
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.KVisibility
|
||||
import kotlin.reflect.full.findAnnotation
|
||||
import kotlin.reflect.full.memberProperties
|
||||
import kotlin.reflect.jvm.javaField
|
||||
import kotlin.test.fail
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ class CompilerArgumentsImplementationTest {
|
||||
@MethodSource("implementations")
|
||||
fun `test - all properties with Argument annotation - are public`(implementation: KClass<out CommonToolArguments>) {
|
||||
implementation.memberProperties.forEach { property ->
|
||||
if (property.findAnnotation<Argument>() != null) {
|
||||
if (property.javaField?.getAnnotation(Argument::class.java) != null) {
|
||||
if (property.visibility != KVisibility.PUBLIC) {
|
||||
fail(
|
||||
"Property '${property.name}: ${property.returnType}' " +
|
||||
|
||||
Reference in New Issue
Block a user