Allow receiver to be generic type constrained by SELF. Receiver itself now can be referenced with RECEIVER.
This commit is contained in:
@@ -257,14 +257,15 @@ class GenericFunction(val signature: String, val keyword: String = "fun") {
|
|||||||
fun build(builder: Appendable, f: Family, primitive: PrimitiveType?) {
|
fun build(builder: Appendable, f: Family, primitive: PrimitiveType?) {
|
||||||
val returnType = returns[f] ?: throw RuntimeException("No return type specified for $signature")
|
val returnType = returns[f] ?: throw RuntimeException("No return type specified for $signature")
|
||||||
|
|
||||||
fun renderType(expression: String, receiver: String): String {
|
fun renderType(expression: String, receiver: String, self: String): String {
|
||||||
val t = StringTokenizer(expression, " \t\n,:()<>?.", true)
|
val t = StringTokenizer(expression, " \t\n,:()<>?.", true)
|
||||||
val answer = StringBuilder()
|
val answer = StringBuilder()
|
||||||
|
|
||||||
while (t.hasMoreTokens()) {
|
while (t.hasMoreTokens()) {
|
||||||
val token = t.nextToken()
|
val token = t.nextToken()
|
||||||
answer.append(when (token) {
|
answer.append(when (token) {
|
||||||
"SELF" -> receiver
|
"RECEIVER" -> receiver
|
||||||
|
"SELF" -> self
|
||||||
"PRIMITIVE" -> primitive?.name ?: token
|
"PRIMITIVE" -> primitive?.name ?: token
|
||||||
"SUM" -> {
|
"SUM" -> {
|
||||||
when (primitive) {
|
when (primitive) {
|
||||||
@@ -293,7 +294,7 @@ class GenericFunction(val signature: String, val keyword: String = "fun") {
|
|||||||
"TCollection" -> {
|
"TCollection" -> {
|
||||||
when (f) {
|
when (f) {
|
||||||
CharSequences, Strings -> "Appendable"
|
CharSequences, Strings -> "Appendable"
|
||||||
else -> renderType("MutableCollection<in T>", receiver)
|
else -> renderType("MutableCollection<in T>", receiver, self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"T" -> {
|
"T" -> {
|
||||||
@@ -324,7 +325,7 @@ class GenericFunction(val signature: String, val keyword: String = "fun") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val isAsteriskOrT = if (receiverAsterisk[f] == true) "*" else "T"
|
val isAsteriskOrT = if (receiverAsterisk[f] == true) "*" else "T"
|
||||||
val receiver = (customReceiver[f] ?: when (f) {
|
val self = (when (f) {
|
||||||
Iterables -> "Iterable<$isAsteriskOrT>"
|
Iterables -> "Iterable<$isAsteriskOrT>"
|
||||||
Collections -> "Collection<$isAsteriskOrT>"
|
Collections -> "Collection<$isAsteriskOrT>"
|
||||||
Lists -> "List<$isAsteriskOrT>"
|
Lists -> "List<$isAsteriskOrT>"
|
||||||
@@ -341,12 +342,14 @@ class GenericFunction(val signature: String, val keyword: String = "fun") {
|
|||||||
ProgressionsOfPrimitives -> primitive?.let { it.name + "Progression" } ?: throw IllegalArgumentException("Primitive progression 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")
|
Primitives -> primitive?.let { it.name } ?: throw IllegalArgumentException("Primitive should specify primitive type")
|
||||||
Generic -> "T"
|
Generic -> "T"
|
||||||
}).let { renderType(it, it) }
|
})
|
||||||
|
|
||||||
fun String.renderType(): String = renderType(this, receiver)
|
val receiver = (customReceiver[f] ?: self).let { renderType(it, it, self) }
|
||||||
|
|
||||||
|
fun String.renderType(): String = renderType(this, receiver, self)
|
||||||
|
|
||||||
fun effectiveTypeParams(): List<TypeParameter> {
|
fun effectiveTypeParams(): List<TypeParameter> {
|
||||||
val parameters = typeParams.mapTo(mutableListOf()) { parseTypeParameter(it) }
|
val parameters = typeParams.mapTo(mutableListOf()) { parseTypeParameter(it.renderType()) }
|
||||||
|
|
||||||
if (f == Generic) {
|
if (f == Generic) {
|
||||||
if (parameters.none { it.name == "T" })
|
if (parameters.none { it.name == "T" })
|
||||||
@@ -364,9 +367,9 @@ class GenericFunction(val signature: String, val keyword: String = "fun") {
|
|||||||
|
|
||||||
return parameters
|
return parameters
|
||||||
} else {
|
} else {
|
||||||
// remove T as parameter
|
// substituted T is no longer a parameter
|
||||||
// TODO: Substitute primitive or String instead of T in other parameters from effective types not from original typeParams
|
val renderedT = "T".renderType()
|
||||||
return parameters.filterNot { it.name == "T" }
|
return parameters.filterNot { it.name == renderedT }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -418,7 +421,7 @@ class GenericFunction(val signature: String, val keyword: String = "fun") {
|
|||||||
|
|
||||||
val types = effectiveTypeParams()
|
val types = effectiveTypeParams()
|
||||||
if (!types.isEmpty()) {
|
if (!types.isEmpty()) {
|
||||||
builder.append(types.joinToString(separator = ", ", prefix = "<", postfix = "> ", transform = { it.original }).renderType())
|
builder.append(types.joinToString(separator = ", ", prefix = "<", postfix = "> ", transform = { it.original }))
|
||||||
}
|
}
|
||||||
|
|
||||||
val receiverType = (if (toNullableT) receiver.replace("T>", "T?>") else receiver).renderType()
|
val receiverType = (if (toNullableT) receiver.replace("T>", "T?>") else receiver).renderType()
|
||||||
|
|||||||
Reference in New Issue
Block a user