From 87da4be9bb13b4f42487bc106ac8716b3b2f4941 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Sun, 15 Mar 2020 19:00:59 +0100 Subject: [PATCH] Move parametersMap.kt to 'cli-common' Also reformat and slightly refactor it. This allows to get rid of dependency of 'util' on 'kotlin-reflect-api'. --- .../jetbrains/kotlin/utils/parametersMap.kt | 122 +++++++++--------- compiler/util/build.gradle.kts | 1 - 2 files changed, 63 insertions(+), 60 deletions(-) rename compiler/{util => cli/cli-common}/src/org/jetbrains/kotlin/utils/parametersMap.kt (71%) diff --git a/compiler/util/src/org/jetbrains/kotlin/utils/parametersMap.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/utils/parametersMap.kt similarity index 71% rename from compiler/util/src/org/jetbrains/kotlin/utils/parametersMap.kt rename to compiler/cli/cli-common/src/org/jetbrains/kotlin/utils/parametersMap.kt index aa9f398af90..7f1d6bc9cea 100644 --- a/compiler/util/src/org/jetbrains/kotlin/utils/parametersMap.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/utils/parametersMap.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2020 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. */ @@ -10,23 +10,20 @@ import kotlin.reflect.full.isSubclassOf import kotlin.reflect.jvm.jvmErasure fun tryConstructClassFromStringArgs(clazz: Class<*>, args: List): Any? { - - try { - return clazz.getConstructor(Array::class.java).newInstance(args.toTypedArray()) - } - catch (e: NoSuchMethodException) { + return try { + clazz.getConstructor(Array::class.java).newInstance(args.toTypedArray()) + } catch (e: NoSuchMethodException) { for (ctor in clazz.kotlin.constructors) { val mapping = tryCreateCallableMappingFromStringArgs(ctor, args) if (mapping != null) { try { return ctor.callBy(mapping) - } - catch (e: Exception) { // TODO: find the exact exception type thrown then callBy fails + } catch (e: Exception) { // TODO: find the exact exception type thrown then callBy fails } } } + null } - return null } fun tryCreateCallableMapping(callable: KCallable<*>, args: List): Map? = @@ -60,11 +57,11 @@ fun tryCreateCallableMappingFromNamedArgs(callable: KCallable<*>, args: List(val name: String?, val value: T?) private interface ArgsConverter { - sealed class Result { object Failure : Result() class Success(val v: Any?) : Result() } + fun tryConvertSingle(parameter: KParameter, arg: NamedArgument): Result fun tryConvertVararg(parameter: KParameter, firstArg: NamedArgument, restArgsIt: Iterator>): Result fun tryConvertTail(parameter: KParameter, firstArg: NamedArgument, restArgsIt: Iterator>): Result @@ -72,7 +69,11 @@ private interface ArgsConverter { private enum class ArgsTraversalState { UNNAMED, NAMED, TAIL } -private fun tryCreateCallableMapping(callable: KCallable<*>, args: Iterator>, converter: ArgsConverter): Map? { +private fun tryCreateCallableMapping( + callable: KCallable<*>, + args: Iterator>, + converter: ArgsConverter +): Map? { val res = mutableMapOf() var state = ArgsTraversalState.UNNAMED val unboundParams = callable.parameters.toMutableList() @@ -98,28 +99,24 @@ private fun tryCreateCallableMapping(callable: KCallable<*>, args: Iterator< // if we do not allow to overload on nullability, drop this check return null // failed to match: null for a non-nullable value } - res.put(par, cvtRes.v) - } - else if (par.type.jvmErasure.java.isArray) { + res[par] = cvtRes.v + } else if (par.type.jvmErasure.java.isArray) { // try vararg val cvtVRes = converter.tryConvertVararg(par, arg, argIt) if (cvtVRes is ArgsConverter.Result.Success) { - res.put(par, cvtVRes.v) - } - else return null // failed to match: no suitable param for unnamed arg - } - else return null // failed to match: no suitable param for unnamed arg + res[par] = cvtVRes.v + } else return null // failed to match: no suitable param for unnamed arg + } else return null // failed to match: no suitable param for unnamed arg } ArgsTraversalState.NAMED -> { assert(arg.name != null) val parIdx = unboundParams.indexOfFirst { it.name == arg.name }.takeIf { it >= 0 } - ?: return null // failed to match: no matching named parameter found + ?: return null // failed to match: no matching named parameter found val par = unboundParams.removeAt(parIdx) val cvtRes = converter.tryConvertSingle(par, arg) if (cvtRes is ArgsConverter.Result.Success) { - res.put(par, cvtRes.v) - } - else return null // failed to match: cannot convert arg to param's type + res[par] = cvtRes.v + } else return null // failed to match: cannot convert arg to param's type } ArgsTraversalState.TAIL -> { assert(arg.name == null) @@ -127,9 +124,8 @@ private fun tryCreateCallableMapping(callable: KCallable<*>, args: Iterator< val cvtVRes = converter.tryConvertTail(par, arg, argIt) if (cvtVRes is ArgsConverter.Result.Success) { if (argIt.hasNext()) return null // failed to match: not all tail args are consumed - res.put(par, cvtVRes.v) - } - else return null // failed to match: no suitable param for tail arg(s) + res[par] = cvtVRes.v + } else return null // failed to match: no suitable param for tail arg(s) } } } @@ -140,12 +136,10 @@ private fun tryCreateCallableMapping(callable: KCallable<*>, args: Iterator< } private fun KType.allowsNulls(): Boolean = - isMarkedNullable || - classifier.let { it is KTypeParameter && it.upperBounds.any(KType::allowsNulls) } + isMarkedNullable || classifier.let { it is KTypeParameter && it.upperBounds.any(KType::allowsNulls) } private class StringArgsConverter : ArgsConverter { - override fun tryConvertSingle(parameter: KParameter, arg: NamedArgument): ArgsConverter.Result { val value = arg.value ?: return ArgsConverter.Result.Success(null) @@ -165,20 +159,23 @@ private class StringArgsConverter : ArgsConverter { return if (primitive != null) ArgsConverter.Result.Success(primitive) else ArgsConverter.Result.Failure } - override fun tryConvertVararg(parameter: KParameter, firstArg: NamedArgument, restArgsIt: Iterator>): ArgsConverter.Result { - + override fun tryConvertVararg( + parameter: KParameter, + firstArg: NamedArgument, + restArgsIt: Iterator> + ): ArgsConverter.Result { fun convertPrimitivesArray(type: KType, args: Sequence): Any? = - when (type.classifier) { - IntArray::class -> args.map { it?.toIntOrNull() } - LongArray::class -> args.map { it?.toLongOrNull() } - ShortArray::class -> args.map { it?.toShortOrNull() } - ByteArray::class -> args.map { it?.toByteOrNull() } - CharArray::class -> args.map { it?.singleOrNull() } - FloatArray::class -> args.map { it?.toFloatOrNull() } - DoubleArray::class -> args.map { it?.toDoubleOrNull() } - BooleanArray::class -> args.map { it?.toBoolean() } - else -> null - }?.toList()?.takeUnless { null in it }?.toTypedArray() + when (type.classifier) { + IntArray::class -> args.map { it?.toIntOrNull() } + LongArray::class -> args.map { it?.toLongOrNull() } + ShortArray::class -> args.map { it?.toShortOrNull() } + ByteArray::class -> args.map { it?.toByteOrNull() } + CharArray::class -> args.map { it?.singleOrNull() } + FloatArray::class -> args.map { it?.toFloatOrNull() } + DoubleArray::class -> args.map { it?.toDoubleOrNull() } + BooleanArray::class -> args.map { it?.toBoolean() } + else -> null + }?.toList()?.takeUnless { null in it }?.toTypedArray() val parameterType = parameter.type if (parameterType.jvmErasure.java.isArray) { @@ -195,8 +192,12 @@ private class StringArgsConverter : ArgsConverter { return ArgsConverter.Result.Failure } - override fun tryConvertTail(parameter: KParameter, firstArg: NamedArgument, restArgsIt: Iterator>): ArgsConverter.Result = - tryConvertVararg(parameter, firstArg, restArgsIt) + override fun tryConvertTail( + parameter: KParameter, + firstArg: NamedArgument, + restArgsIt: Iterator> + ): ArgsConverter.Result = + tryConvertVararg(parameter, firstArg, restArgsIt) } private class AnyArgsConverter : ArgsConverter { @@ -205,28 +206,27 @@ private class AnyArgsConverter : ArgsConverter { @Suppress("UNCHECKED_CAST") fun convertPrimitivesArray(type: KType?, arg: Any?): Any? = - when (type?.classifier) { - IntArray::class -> (arg as? Array)?.toIntArray() - LongArray::class -> (arg as? Array)?.toLongArray() - ShortArray::class -> (arg as? Array)?.toShortArray() - ByteArray::class -> (arg as? Array)?.toByteArray() - CharArray::class -> (arg as? Array)?.toCharArray() - FloatArray::class -> (arg as? Array)?.toFloatArray() - DoubleArray::class -> (arg as? Array)?.toDoubleArray() - BooleanArray::class -> (arg as? Array)?.toBooleanArray() - else -> null - } + when (type?.classifier) { + IntArray::class -> (arg as? Array)?.toIntArray() + LongArray::class -> (arg as? Array)?.toLongArray() + ShortArray::class -> (arg as? Array)?.toShortArray() + ByteArray::class -> (arg as? Array)?.toByteArray() + CharArray::class -> (arg as? Array)?.toCharArray() + FloatArray::class -> (arg as? Array)?.toFloatArray() + DoubleArray::class -> (arg as? Array)?.toDoubleArray() + BooleanArray::class -> (arg as? Array)?.toBooleanArray() + else -> null + } if (value::class.isSubclassOf(parameter.type.jvmErasure)) return ArgsConverter.Result.Success(value) return convertPrimitivesArray(parameter.type, value)?.let { ArgsConverter.Result.Success(it) } - ?: ArgsConverter.Result.Failure + ?: ArgsConverter.Result.Failure } override fun tryConvertVararg( parameter: KParameter, firstArg: NamedArgument, restArgsIt: Iterator> ): ArgsConverter.Result { - val parameterType = parameter.type if (parameterType.jvmErasure.java.isArray) { val argsSequence = sequenceOf(firstArg.value) + restArgsIt.asSequence().map { it.value } @@ -239,8 +239,12 @@ private class AnyArgsConverter : ArgsConverter { return ArgsConverter.Result.Failure } - override fun tryConvertTail(parameter: KParameter, firstArg: NamedArgument, restArgsIt: Iterator>): ArgsConverter.Result = - tryConvertSingle(parameter, firstArg) + override fun tryConvertTail( + parameter: KParameter, + firstArg: NamedArgument, + restArgsIt: Iterator> + ): ArgsConverter.Result = + tryConvertSingle(parameter, firstArg) } @Suppress("UNCHECKED_CAST") diff --git a/compiler/util/build.gradle.kts b/compiler/util/build.gradle.kts index c1652e0ef9b..0795c093dd8 100644 --- a/compiler/util/build.gradle.kts +++ b/compiler/util/build.gradle.kts @@ -7,7 +7,6 @@ dependencies { api(kotlinStdlib()) api(project(":compiler:compiler.version")) - compileOnly(project(":kotlin-reflect-api")) compileOnly(intellijCoreDep()) { includeJars("intellij-core") } compileOnly(intellijDep()) { includeIntellijCoreJarDependencies(project) } compileOnly(jpsStandalone()) { includeJars("jps-model") }