diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/dsl/MemberBuilder.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/dsl/MemberBuilder.kt index 209d63a2890..93bcc3465a3 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/dsl/MemberBuilder.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/dsl/MemberBuilder.kt @@ -57,6 +57,7 @@ class MemberBuilder( var infix: Boolean = false; private set var operator: Boolean = false; private set val typeParams = mutableListOf() + var primaryTypeParameter: String? = null; private set var customReceiver: String? = null; private set var receiverAsterisk: Boolean = false // TODO: rename to genericStarProjection var toNullableT: Boolean = false @@ -97,8 +98,12 @@ class MemberBuilder( @Deprecated("Use specialFor", ReplaceWith("specialFor(*fs) { returns(run(valueBuilder)) }")) fun returns(vararg fs: Family, valueBuilder: () -> String) = specialFor(*fs) { returns(run(valueBuilder)) } - fun typeParam(typeParameterName: String) { + fun typeParam(typeParameterName: String, primary: Boolean = false) { typeParams += typeParameterName + if (primary) { + check(primaryTypeParameter == null) + primaryTypeParameter = typeParameterName + } } fun annotation(annotation: String) { @@ -171,7 +176,7 @@ class MemberBuilder( } val returnType = returns ?: throw RuntimeException("No return type specified for $signature") - + val primaryTypeParameter = this.primaryTypeParameter ?: "T" fun renderType(expression: String, receiver: String, self: String): String { val t = StringTokenizer(expression, " \t\n,:()<>?.", true) @@ -210,12 +215,12 @@ class MemberBuilder( "TCollection" -> { when (family) { CharSequences, Strings -> "Appendable" - else -> renderType("MutableCollection", receiver, self) + else -> renderType("MutableCollection", receiver, self) } } - "T" -> { + primaryTypeParameter -> { when (family) { - Generic -> "T" + Generic -> primaryTypeParameter CharSequences, Strings -> "Char" Maps -> "Map.Entry" else -> primitive?.name ?: token @@ -223,13 +228,13 @@ class MemberBuilder( } "TRange" -> { when (family) { - Generic -> "Range" + Generic -> "Range<$primaryTypeParameter>" else -> primitive!!.name + "Range" } } "TProgression" -> { when (family) { - Generic -> "Progression" + Generic -> "Progression" else -> primitive!!.name + "Progression" } } @@ -240,7 +245,7 @@ class MemberBuilder( return answer.toString() } - val isAsteriskOrT = if (receiverAsterisk) "*" else "T" + val isAsteriskOrT = if (receiverAsterisk) "*" else primaryTypeParameter val self = (when (family) { Iterables -> "Iterable<$isAsteriskOrT>" Collections -> "Collection<$isAsteriskOrT>" @@ -248,8 +253,8 @@ class MemberBuilder( Maps -> "Map" Sets -> "Set<$isAsteriskOrT>" Sequences -> "Sequence<$isAsteriskOrT>" - InvariantArraysOfObjects -> "Array" - ArraysOfObjects -> "Array<${isAsteriskOrT.replace("T", "out T")}>" + InvariantArraysOfObjects -> "Array<$primaryTypeParameter>" + ArraysOfObjects -> "Array<${isAsteriskOrT.replace(primaryTypeParameter, "out $primaryTypeParameter")}>" Strings -> "String" CharSequences -> "CharSequence" Ranges -> "ClosedRange<$isAsteriskOrT>" @@ -257,7 +262,7 @@ class MemberBuilder( RangesOfPrimitives -> primitive?.let { it.name + "Range" } ?: throw IllegalArgumentException("Primitive range should specify primitive type") ProgressionsOfPrimitives -> primitive?.let { it.name + "Progression" } ?: throw IllegalArgumentException("Primitive progression should specify primitive type") Primitives -> primitive?.let { it.name } ?: throw IllegalArgumentException("Primitive should specify primitive type") - Generic -> "T" + Generic -> primaryTypeParameter }) val receiver = (customReceiver ?: self).let { renderType(it, it, self) } @@ -268,8 +273,8 @@ class MemberBuilder( val parameters = typeParams.mapTo(mutableListOf()) { parseTypeParameter(it.renderType()) } if (family == Generic) { - if (parameters.none { it.name == "T" }) - parameters.add(TypeParameter("T")) + if (parameters.none { it.name == primaryTypeParameter }) + parameters.add(TypeParameter(primaryTypeParameter)) return parameters } else if (primitive == null && family != Strings && family != CharSequences) { val mentionedTypes = parseTypeRef(receiver).mentionedTypes() + parameters.flatMap { it.mentionedTypeRefs() } @@ -283,7 +288,7 @@ class MemberBuilder( return parameters } else { // substituted T is no longer a parameter - val renderedT = "T".renderType() + val renderedT = primaryTypeParameter.renderType() return parameters.filterNot { it.name == renderedT } } } @@ -318,7 +323,7 @@ class MemberBuilder( if (!f.isPrimitiveSpecialization && primitive != null) { platformName - ?.replace("", primitive!!.name) + ?.replace("<$primaryTypeParameter>", primitive!!.name) ?.let { platformName -> builder.append("@kotlin.jvm.JvmName(\"${platformName}\")\n") } }