Clean up code of ir builtins map generator
This commit is contained in:
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.generators.evaluate
|
|||||||
import org.jetbrains.kotlin.backend.common.interpreter.builtins.compileTimeAnnotation
|
import org.jetbrains.kotlin.backend.common.interpreter.builtins.compileTimeAnnotation
|
||||||
import org.jetbrains.kotlin.backend.jvm.serialization.JvmIdSignatureDescriptor
|
import org.jetbrains.kotlin.backend.jvm.serialization.JvmIdSignatureDescriptor
|
||||||
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
|
||||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||||
import org.jetbrains.kotlin.config.ApiVersion
|
import org.jetbrains.kotlin.config.ApiVersion
|
||||||
import org.jetbrains.kotlin.config.LanguageVersion
|
import org.jetbrains.kotlin.config.LanguageVersion
|
||||||
@@ -25,7 +24,6 @@ import org.jetbrains.kotlin.ir.util.SymbolTable
|
|||||||
import org.jetbrains.kotlin.ir.util.TypeTranslator
|
import org.jetbrains.kotlin.ir.util.TypeTranslator
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
|
||||||
import org.jetbrains.kotlin.utils.Printer
|
import org.jetbrains.kotlin.utils.Printer
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
@@ -46,116 +44,25 @@ fun generateMap(): String {
|
|||||||
p.println("/** This file is generated by org.jetbrains.kotlin.backend.common.interpreter.builtins.GenerateBuiltInsMap.generateMap(). DO NOT MODIFY MANUALLY */")
|
p.println("/** This file is generated by org.jetbrains.kotlin.backend.common.interpreter.builtins.GenerateBuiltInsMap.generateMap(). DO NOT MODIFY MANUALLY */")
|
||||||
p.println()
|
p.println()
|
||||||
|
|
||||||
val unaryOperationsMap = mutableMapOf<CallableDescriptor, Pair<String, String>>()
|
val unaryOperationsMap = getOperationMap(1)
|
||||||
val binaryOperationsMap = mutableMapOf<CallableDescriptor, Pair<String, String>>()
|
val binaryOperationsMap = getOperationMap(2)
|
||||||
val ternaryOperationsMap = mutableMapOf<CallableDescriptor, Pair<String, String>>()
|
val ternaryOperationsMap = getOperationMap(3)
|
||||||
val builtIns = DefaultBuiltIns.Instance
|
|
||||||
|
|
||||||
//save common builtins
|
val binaryIrOperationsMap = getBinaryIrOperationMap()
|
||||||
val allPrimitiveTypes = PrimitiveType.values().map { builtIns.getBuiltInClassByFqName(it.typeFqName) }
|
|
||||||
val arrays = PrimitiveType.values().map { builtIns.getPrimitiveArrayClassDescriptor(it) } + builtIns.array
|
|
||||||
|
|
||||||
for (descriptor in allPrimitiveTypes + builtIns.string + arrays + builtIns.any) {
|
|
||||||
val typeParameters = descriptor.typeConstructor.parameters.map { it.name.asString() }
|
|
||||||
val typeParametersAsAny = if (typeParameters.isNotEmpty()) typeParameters.joinToString(prefix = "<", postfix = ">") { "Any?" } else ""
|
|
||||||
val descriptorType = descriptor.defaultType
|
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
val functions = descriptor.getMemberScope(listOf()).getContributedDescriptors()
|
|
||||||
.filter {
|
|
||||||
it is CallableDescriptor &&
|
|
||||||
(it as? FunctionDescriptor)?.kind != CallableMemberDescriptor.Kind.FAKE_OVERRIDE &&
|
|
||||||
(it.annotations.hasAnnotation(compileTimeAnnotation) || descriptor.annotations.hasAnnotation(compileTimeAnnotation))
|
|
||||||
} as List<CallableDescriptor>
|
|
||||||
|
|
||||||
for (function in functions) {
|
|
||||||
val operationArguments = (listOf(descriptorType) + function.valueParameters.map { it.type }).joinToString { "\"" + it + "\"" }
|
|
||||||
|
|
||||||
val functionTypeParameters = (listOf(descriptorType.constructor.toString() + typeParametersAsAny) +
|
|
||||||
function.valueParameters.map { if (typeParameters.contains(it.type.toString())) "Any?" else it.type.toString() })
|
|
||||||
.joinToString(prefix = "<", postfix = ">")
|
|
||||||
|
|
||||||
when (function.valueParameters.size + 1) { // +1 for receiver
|
|
||||||
1 -> unaryOperationsMap[function] = functionTypeParameters to operationArguments
|
|
||||||
2 -> binaryOperationsMap[function] = functionTypeParameters to operationArguments
|
|
||||||
3 -> ternaryOperationsMap[function] = functionTypeParameters to operationArguments
|
|
||||||
else -> throw IllegalStateException("Couldn't add following method from builtins to operations map: ${function.name} in class ${descriptor.name}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//save ir builtins
|
|
||||||
val binaryIrOperationsMap = mutableMapOf<CallableDescriptor, Pair<String, String>>()
|
|
||||||
val irBuiltIns = getIrBuiltIns()
|
|
||||||
val irNullCheck = irBuiltIns.checkNotNullSymbol.descriptor
|
|
||||||
val irFunSymbols =
|
|
||||||
(irBuiltIns.lessFunByOperandType.values +
|
|
||||||
irBuiltIns.lessOrEqualFunByOperandType.values +
|
|
||||||
irBuiltIns.greaterFunByOperandType.values +
|
|
||||||
irBuiltIns.greaterOrEqualFunByOperandType.values +
|
|
||||||
irBuiltIns.eqeqSymbol +
|
|
||||||
irBuiltIns.eqeqeqSymbol +
|
|
||||||
irBuiltIns.ieee754equalsFunByOperandType.values +
|
|
||||||
irBuiltIns.andandSymbol +
|
|
||||||
irBuiltIns.ororSymbol)
|
|
||||||
.map { it.descriptor }
|
|
||||||
.filter { it.annotations.hasAnnotation(compileTimeAnnotation) }
|
|
||||||
|
|
||||||
for (function in irFunSymbols) {
|
|
||||||
val parametersTypes = function.valueParameters.map { it.type }
|
|
||||||
val operationArguments = parametersTypes.joinToString { "\"" + it + "\"" }
|
|
||||||
val functionTypeParameters = parametersTypes.joinToString(prefix = "<", postfix = ">")
|
|
||||||
|
|
||||||
check(parametersTypes.size == 2) { "Couldn't add following method from ir builtins to operations map: ${function.name}" }
|
|
||||||
binaryIrOperationsMap[function] = functionTypeParameters to operationArguments
|
|
||||||
}
|
|
||||||
|
|
||||||
//save to file
|
//save to file
|
||||||
p.println("val unaryFunctions = mapOf<CompileTimeFunction, Function1<Any?, Any?>>(")
|
p.println("val unaryFunctions = mapOf<CompileTimeFunction, Function1<Any?, Any?>>(")
|
||||||
val unaryBody = unaryOperationsMap.entries.joinToString(",\n", postfix = ",\n") { (function, parameters) ->
|
p.println(generateUnaryBody(unaryOperationsMap))
|
||||||
val methodName = "${function.name}"
|
|
||||||
val parentheses = if (function is FunctionDescriptor) "()" else ""
|
|
||||||
val body =
|
|
||||||
if (methodName == "toString" && parameters.first == "<Any>") "a.defaultToString()"
|
|
||||||
else "a.$methodName$parentheses"
|
|
||||||
" unaryOperation${parameters.first}(\"$methodName\", ${parameters.second}) { a -> $body }"
|
|
||||||
} + " unaryOperation<Any?>(\"${irNullCheck.name}\", \"${irNullCheck.valueParameters.first().type}\") { a -> a!! },\n" +
|
|
||||||
" unaryOperation<ExceptionState>(\"<get-message>\", \"Throwable\") { a -> a.getMessage() },\n" +
|
|
||||||
" unaryOperation<ExceptionState>(\"<get-cause>\", \"Throwable\") { a -> a.getCause() }"
|
|
||||||
p.println(unaryBody)
|
|
||||||
p.println(")")
|
p.println(")")
|
||||||
p.println()
|
p.println()
|
||||||
|
|
||||||
p.println("val binaryFunctions = mapOf<CompileTimeFunction, Function2<Any?, Any?, Any?>>(")
|
p.println("val binaryFunctions = mapOf<CompileTimeFunction, Function2<Any?, Any?, Any?>>(")
|
||||||
val binaryBody = binaryOperationsMap.entries.joinToString(",\n", postfix = ",\n") { (function, parameters) ->
|
p.println(generateBinaryBody(binaryOperationsMap, binaryIrOperationsMap))
|
||||||
val methodName = "${function.name}"
|
|
||||||
" binaryOperation${parameters.first}(\"$methodName\", ${parameters.second}) { a, b -> a.$methodName(b) }"
|
|
||||||
} + binaryIrOperationsMap.entries.joinToString(",\n") { (function, parameters) ->
|
|
||||||
val methodName = "${function.name}"
|
|
||||||
val methodSymbol = when (methodName) {
|
|
||||||
IrBuiltIns.OperatorNames.LESS -> "<"
|
|
||||||
IrBuiltIns.OperatorNames.LESS_OR_EQUAL -> "<="
|
|
||||||
IrBuiltIns.OperatorNames.GREATER -> ">"
|
|
||||||
IrBuiltIns.OperatorNames.GREATER_OR_EQUAL -> ">="
|
|
||||||
IrBuiltIns.OperatorNames.EQEQ -> "=="
|
|
||||||
IrBuiltIns.OperatorNames.EQEQEQ -> "==="
|
|
||||||
IrBuiltIns.OperatorNames.IEEE754_EQUALS -> "=="
|
|
||||||
IrBuiltIns.OperatorNames.ANDAND -> "&&"
|
|
||||||
IrBuiltIns.OperatorNames.OROR -> "||"
|
|
||||||
else -> throw UnsupportedOperationException("Unknown ir operation \"$methodName\"")
|
|
||||||
}
|
|
||||||
" binaryOperation${parameters.first}(\"$methodName\", ${parameters.second}) { a, b -> a $methodSymbol b }"
|
|
||||||
}
|
|
||||||
p.println(binaryBody)
|
|
||||||
p.println(")")
|
p.println(")")
|
||||||
p.println()
|
p.println()
|
||||||
|
|
||||||
p.println("val ternaryFunctions = mapOf<CompileTimeFunction, Function3<Any?, Any?, Any?, Any?>>(")
|
p.println("val ternaryFunctions = mapOf<CompileTimeFunction, Function3<Any?, Any?, Any?, Any?>>(")
|
||||||
val ternaryBody = ternaryOperationsMap.entries.joinToString(",\n") { (function, parameters) ->
|
p.println(generateTernaryBody(ternaryOperationsMap))
|
||||||
val methodName = "${function.name}"
|
|
||||||
" ternaryOperation${parameters.first}(\"$methodName\", ${parameters.second}) { a, b, c -> a.$methodName(b, c) }"
|
|
||||||
}
|
|
||||||
p.println(ternaryBody)
|
|
||||||
p.println(")")
|
p.println(")")
|
||||||
p.println()
|
p.println()
|
||||||
|
|
||||||
@@ -174,6 +81,115 @@ fun generateMap(): String {
|
|||||||
return sb.toString()
|
return sb.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getOperationMap(argumentsCount: Int): MutableMap<CallableDescriptor, Pair<String, String>> {
|
||||||
|
val builtIns = DefaultBuiltIns.Instance
|
||||||
|
val operationMap = mutableMapOf<CallableDescriptor, Pair<String, String>>()
|
||||||
|
val allPrimitiveTypes = PrimitiveType.values().map { builtIns.getBuiltInClassByFqName(it.typeFqName) }
|
||||||
|
val arrays = PrimitiveType.values().map { builtIns.getPrimitiveArrayClassDescriptor(it) } + builtIns.array
|
||||||
|
|
||||||
|
fun CallableDescriptor.isCompileTime(classDescriptor: ClassDescriptor): Boolean {
|
||||||
|
return (this as? FunctionDescriptor)?.kind != CallableMemberDescriptor.Kind.FAKE_OVERRIDE &&
|
||||||
|
(this.annotations.hasAnnotation(compileTimeAnnotation) || classDescriptor.annotations.hasAnnotation(compileTimeAnnotation))
|
||||||
|
}
|
||||||
|
|
||||||
|
for (classDescriptor in allPrimitiveTypes + builtIns.string + arrays + builtIns.any) {
|
||||||
|
val classTypeParameters = classDescriptor.typeConstructor.parameters.map { it.name.asString() }
|
||||||
|
val typeParametersReplacedToAny =
|
||||||
|
if (classTypeParameters.isNotEmpty()) classTypeParameters.joinToString(prefix = "<", postfix = ">") { "Any?" } else ""
|
||||||
|
val classType = classDescriptor.defaultType
|
||||||
|
|
||||||
|
val compileTimeFunctions = classDescriptor.getMemberScope(listOf()).getContributedDescriptors()
|
||||||
|
.filterIsInstance<CallableDescriptor>()
|
||||||
|
.filter { it.isCompileTime(classDescriptor) }
|
||||||
|
|
||||||
|
for (function in compileTimeFunctions) {
|
||||||
|
val operationArguments = (listOf(classType) + function.valueParameters.map { it.type }).joinToString { "\"" + it + "\"" }
|
||||||
|
|
||||||
|
val typeParametersOfFun = listOf(classType.constructor.toString() + typeParametersReplacedToAny) +
|
||||||
|
function.valueParameters.map { if (classTypeParameters.contains(it.type.toString())) "Any?" else it.type.toString() }
|
||||||
|
|
||||||
|
if (function.valueParameters.size + 1 == argumentsCount) { // +1 for receiver
|
||||||
|
operationMap[function] = typeParametersOfFun.joinToString(prefix = "<", postfix = ">") to operationArguments
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return operationMap
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getBinaryIrOperationMap(): MutableMap<CallableDescriptor, Pair<String, String>> {
|
||||||
|
val irBuiltIns = getIrBuiltIns()
|
||||||
|
val operationMap = mutableMapOf<CallableDescriptor, Pair<String, String>>()
|
||||||
|
val irFunSymbols =
|
||||||
|
(irBuiltIns.lessFunByOperandType.values + irBuiltIns.lessOrEqualFunByOperandType.values +
|
||||||
|
irBuiltIns.greaterFunByOperandType.values + irBuiltIns.greaterOrEqualFunByOperandType.values +
|
||||||
|
irBuiltIns.eqeqSymbol + irBuiltIns.eqeqeqSymbol + irBuiltIns.ieee754equalsFunByOperandType.values +
|
||||||
|
irBuiltIns.andandSymbol + irBuiltIns.ororSymbol)
|
||||||
|
.map { it.descriptor }
|
||||||
|
.filter { it.annotations.hasAnnotation(compileTimeAnnotation) }
|
||||||
|
|
||||||
|
for (function in irFunSymbols) {
|
||||||
|
val parametersTypes = function.valueParameters.map { it.type }
|
||||||
|
val operationArguments = parametersTypes.joinToString { "\"" + it + "\"" }
|
||||||
|
val functionTypeParameters = parametersTypes.joinToString(prefix = "<", postfix = ">")
|
||||||
|
|
||||||
|
check(parametersTypes.size == 2) { "Couldn't add following method from ir builtins to operations map: ${function.name}" }
|
||||||
|
operationMap[function] = functionTypeParameters to operationArguments
|
||||||
|
}
|
||||||
|
|
||||||
|
return operationMap
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun generateUnaryBody(unaryOperationsMap: Map<CallableDescriptor, Pair<String, String>>): String {
|
||||||
|
val irNullCheck = getIrBuiltIns().checkNotNullSymbol.descriptor
|
||||||
|
return unaryOperationsMap.entries.joinToString(separator = ",\n", postfix = ",\n") { (function, parameters) ->
|
||||||
|
val methodName = "${function.name}"
|
||||||
|
val parentheses = if (function is FunctionDescriptor) "()" else ""
|
||||||
|
val body =
|
||||||
|
if (methodName == "toString" && parameters.first == "<Any>") "a.defaultToString()"
|
||||||
|
else "a.$methodName$parentheses"
|
||||||
|
" unaryOperation${parameters.first}(\"$methodName\", ${parameters.second}) { a -> $body }"
|
||||||
|
} +
|
||||||
|
" unaryOperation<Any?>(\"${irNullCheck.name}\", \"${irNullCheck.valueParameters.first().type}\") { a -> a!! },\n" +
|
||||||
|
" unaryOperation<ExceptionState>(\"<get-message>\", \"Throwable\") { a -> a.getMessage() },\n" +
|
||||||
|
" unaryOperation<ExceptionState>(\"<get-cause>\", \"Throwable\") { a -> a.getCause() }"
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun generateBinaryBody(
|
||||||
|
binaryOperationsMap: Map<CallableDescriptor, Pair<String, String>>, binaryIrOperationsMap: Map<CallableDescriptor, Pair<String, String>>
|
||||||
|
): String {
|
||||||
|
return binaryOperationsMap.entries.joinToString(separator = ",\n", postfix = ",\n") { (function, parameters) ->
|
||||||
|
val methodName = "${function.name}"
|
||||||
|
" binaryOperation${parameters.first}(\"$methodName\", ${parameters.second}) { a, b -> a.$methodName(b) }"
|
||||||
|
} + binaryIrOperationsMap.entries.joinToString(separator = ",\n") { (function, parameters) ->
|
||||||
|
val methodName = "${function.name}"
|
||||||
|
val methodSymbol = getIrMethodSymbolByName(methodName)
|
||||||
|
" binaryOperation${parameters.first}(\"$methodName\", ${parameters.second}) { a, b -> a $methodSymbol b }"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun generateTernaryBody(ternaryOperationsMap: Map<CallableDescriptor, Pair<String, String>>): String {
|
||||||
|
return ternaryOperationsMap.entries.joinToString(separator = ",\n") { (function, parameters) ->
|
||||||
|
val methodName = "${function.name}"
|
||||||
|
" ternaryOperation${parameters.first}(\"$methodName\", ${parameters.second}) { a, b, c -> a.$methodName(b, c) }"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getIrMethodSymbolByName(methodName: String): String {
|
||||||
|
return when (methodName) {
|
||||||
|
IrBuiltIns.OperatorNames.LESS -> "<"
|
||||||
|
IrBuiltIns.OperatorNames.LESS_OR_EQUAL -> "<="
|
||||||
|
IrBuiltIns.OperatorNames.GREATER -> ">"
|
||||||
|
IrBuiltIns.OperatorNames.GREATER_OR_EQUAL -> ">="
|
||||||
|
IrBuiltIns.OperatorNames.EQEQ -> "=="
|
||||||
|
IrBuiltIns.OperatorNames.EQEQEQ -> "==="
|
||||||
|
IrBuiltIns.OperatorNames.IEEE754_EQUALS -> "=="
|
||||||
|
IrBuiltIns.OperatorNames.ANDAND -> "&&"
|
||||||
|
IrBuiltIns.OperatorNames.OROR -> "||"
|
||||||
|
else -> throw UnsupportedOperationException("Unknown ir operation \"$methodName\"")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun getIrBuiltIns(): IrBuiltIns {
|
private fun getIrBuiltIns(): IrBuiltIns {
|
||||||
val builtIns = DefaultBuiltIns.Instance
|
val builtIns = DefaultBuiltIns.Instance
|
||||||
val languageSettings = LanguageVersionSettingsImpl(LanguageVersion.KOTLIN_1_3, ApiVersion.KOTLIN_1_3)
|
val languageSettings = LanguageVersionSettingsImpl(LanguageVersion.KOTLIN_1_3, ApiVersion.KOTLIN_1_3)
|
||||||
|
|||||||
Reference in New Issue
Block a user