FIR: generate operations map for CompileTimeConstantEvaluator
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.generators.evaluate
|
||||
|
||||
import org.jetbrains.kotlin.generators.util.GeneratorsFileUtil
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
import java.io.File
|
||||
|
||||
val FIR_DEST_FILE: File = File("compiler/fir/evaluate/src/org/jetbrains/kotlin/fir/evaluate/FirOperationsMapGenerated.kt")
|
||||
private val EXCLUDED_FUNCTIONS: List<String> = listOf(
|
||||
"not", "toChar", "toString",
|
||||
"and", "or", "xor", "shl", "shr", "ushr",
|
||||
"compareTo", "equals",
|
||||
"rangeTo", "subSequence"
|
||||
)
|
||||
private val EXCLUDED_TYPES: List<String> = listOf("Boolean", "Char", "String")
|
||||
|
||||
fun main() {
|
||||
GeneratorsFileUtil.writeFileIfContentChanged(FIR_DEST_FILE, generateFirMap())
|
||||
}
|
||||
|
||||
fun generateFirMap(): String {
|
||||
val sb = StringBuilder()
|
||||
val p = Printer(sb)
|
||||
p.println(File("license/COPYRIGHT.txt").readText())
|
||||
|
||||
p.println(
|
||||
"""
|
||||
|package org.jetbrains.kotlin.fir.evaluate
|
||||
|
|
||||
|import org.jetbrains.kotlin.fir.expressions.FirConstKind
|
||||
|
|
||||
|/** This file is generated by org.jetbrains.kotlin.generators.evaluate:generateFirMap(). DO NOT MODIFY MANUALLY */
|
||||
|
|
||||
|internal data class UnaryOperationKey<out T>(val opr: FirConstKind<out T>, val opName: String)
|
||||
|internal data class BinaryOperationKey<out T, out U>(val opr1: FirConstKind<out T>, val opr2: FirConstKind<out U>, val opName: String)
|
||||
|
|
||||
|@Suppress("UNCHECKED_CAST")
|
||||
|private fun <T> unaryOperation(
|
||||
| t: FirConstKind<T>,
|
||||
| opName: String,
|
||||
| operation: Function1<T, Number>
|
||||
|) = UnaryOperationKey(t, opName) to operation as Function1<Number, Number>
|
||||
|
|
||||
|@Suppress("UNCHECKED_CAST")
|
||||
|private fun <T, U> binaryOperation(
|
||||
| t: FirConstKind<T>,
|
||||
| u: FirConstKind<U>,
|
||||
| opName: String,
|
||||
| operation: Function2<T, U, Number>
|
||||
|) = BinaryOperationKey(t, u, opName) to operation as Function2<Number, Number, Number>
|
||||
""".trimMargin()
|
||||
)
|
||||
p.println()
|
||||
|
||||
val unaryOperationsMap = arrayListOf<Triple<String, List<KotlinType>, Boolean>>()
|
||||
val binaryOperationsMap = arrayListOf<Pair<String, List<KotlinType>>>()
|
||||
populateOperationsMap(unaryOperationsMap, binaryOperationsMap, EXCLUDED_FUNCTIONS)
|
||||
|
||||
p.println("internal val unaryOperations: HashMap<UnaryOperationKey<*>, Function1<Number, Number>> = hashMapOf(")
|
||||
p.pushIndent()
|
||||
p.renderUnaryOperations(unaryOperationsMap)
|
||||
p.popIndent()
|
||||
p.println(")")
|
||||
p.println()
|
||||
|
||||
p.println("internal val binaryOperations: HashMap<BinaryOperationKey<*, *>, Function2<Number, Number, Number>> = hashMapOf(")
|
||||
p.pushIndent()
|
||||
p.renderBinaryOperations(binaryOperationsMap)
|
||||
p.popIndent()
|
||||
p.println(")")
|
||||
|
||||
return sb.toString()
|
||||
}
|
||||
|
||||
private fun Printer.renderUnaryOperations(unaryOperationsMap: List<Triple<String, List<KotlinType>, Boolean>>) {
|
||||
val unaryOperationsMapIterator = unaryOperationsMap.iterator()
|
||||
while (unaryOperationsMapIterator.hasNext()) {
|
||||
val (funcName, parameters, isFunction) = unaryOperationsMapIterator.next()
|
||||
if (parameters.first().constructor.declarationDescriptor!!.name.asString() in EXCLUDED_TYPES) {
|
||||
continue
|
||||
}
|
||||
val parenthesesOrBlank = if (isFunction) "()" else ""
|
||||
this.println(
|
||||
"unaryOperation(",
|
||||
parameters.joinToString(", ") { it.asString() },
|
||||
", ",
|
||||
"\"$funcName\"",
|
||||
", { a -> a.$funcName$parenthesesOrBlank })",
|
||||
if (unaryOperationsMapIterator.hasNext()) "," else ""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun Printer.renderBinaryOperations(binaryOperationsMap: List<Pair<String, List<KotlinType>>>) {
|
||||
val binaryOperationsMapIterator = binaryOperationsMap.iterator()
|
||||
while (binaryOperationsMapIterator.hasNext()) {
|
||||
val (funcName, parameters) = binaryOperationsMapIterator.next()
|
||||
if (parameters.first().constructor.declarationDescriptor!!.name.asString() in EXCLUDED_TYPES) {
|
||||
continue
|
||||
}
|
||||
this.println(
|
||||
"binaryOperation(",
|
||||
parameters.joinToString(", ") { it.asString() },
|
||||
", ",
|
||||
"\"$funcName\"",
|
||||
", { a, b -> a.$funcName(b) })",
|
||||
if (binaryOperationsMapIterator.hasNext()) "," else ""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun KotlinType.asString(): String = "FirConstKind." + constructor.declarationDescriptor!!.name.asString()
|
||||
@@ -7,17 +7,14 @@ package org.jetbrains.kotlin.generators.evaluate
|
||||
|
||||
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.generators.util.GeneratorsFileUtil
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
import java.io.File
|
||||
|
||||
val DEST_FILE: File = File("compiler/frontend/src/org/jetbrains/kotlin/resolve/constants/evaluate/OperationsMapGenerated.kt")
|
||||
private val EXCLUDED_FUNCTIONS = listOf("rangeTo", "hashCode", "inc", "dec", "subSequence")
|
||||
private val EXCLUDED_FUNCTIONS: List<String> = listOf("rangeTo", "hashCode", "inc", "dec", "subSequence")
|
||||
|
||||
fun main() {
|
||||
GeneratorsFileUtil.writeFileIfContentChanged(DEST_FILE, generate())
|
||||
@@ -40,6 +37,7 @@ fun generate(): String {
|
||||
|
||||
val unaryOperationsMap = arrayListOf<Triple<String, List<KotlinType>, Boolean>>()
|
||||
val binaryOperationsMap = arrayListOf<Pair<String, List<KotlinType>>>()
|
||||
populateOperationsMap(unaryOperationsMap, binaryOperationsMap, EXCLUDED_FUNCTIONS)
|
||||
|
||||
val builtIns = DefaultBuiltIns.Instance
|
||||
|
||||
@@ -50,24 +48,6 @@ fun generate(): String {
|
||||
val integerTypes = allPrimitiveTypes.map { it.defaultType }.filter { it.isIntegerType() }
|
||||
val fpTypes = allPrimitiveTypes.map { it.defaultType }.filter { it.isFpType() }
|
||||
|
||||
for (descriptor in allPrimitiveTypes + builtIns.string) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val functions = descriptor.getMemberScope(listOf()).getContributedDescriptors()
|
||||
.filter { it is CallableDescriptor && !EXCLUDED_FUNCTIONS.contains(it.getName().asString()) } as List<CallableDescriptor>
|
||||
|
||||
for (function in functions) {
|
||||
val parametersTypes = function.getParametersTypes()
|
||||
|
||||
when (parametersTypes.size) {
|
||||
1 -> unaryOperationsMap.add(Triple(function.name.asString(), parametersTypes, function is FunctionDescriptor))
|
||||
2 -> binaryOperationsMap.add(function.name.asString() to parametersTypes)
|
||||
else -> throw IllegalStateException(
|
||||
"Couldn't add following method from builtins to operations map: ${function.name} in class ${descriptor.name}"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unaryOperationsMap.add(Triple("code", listOf(builtIns.charType), false))
|
||||
|
||||
for (type in integerTypes) {
|
||||
@@ -186,10 +166,6 @@ private fun KotlinType.isIntegerType(): Boolean =
|
||||
private fun KotlinType.isFpType(): Boolean =
|
||||
KotlinBuiltIns.isDouble(this) || KotlinBuiltIns.isFloat(this)
|
||||
|
||||
private fun CallableDescriptor.getParametersTypes(): List<KotlinType> =
|
||||
listOf((containingDeclaration as ClassDescriptor).defaultType) +
|
||||
valueParameters.map { it.type.makeNotNullable() }
|
||||
|
||||
private fun KotlinType.asString(): String = typeName.uppercase()
|
||||
|
||||
private val KotlinType.typeName: String
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.generators.evaluate
|
||||
|
||||
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
|
||||
|
||||
internal fun populateOperationsMap(
|
||||
unaryOperationsMap: ArrayList<Triple<String, List<KotlinType>, Boolean>>,
|
||||
binaryOperationsMap: ArrayList<Pair<String, List<KotlinType>>>,
|
||||
excludedFunctions: List<String>
|
||||
) {
|
||||
val builtIns = DefaultBuiltIns.Instance
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val allPrimitiveTypes = builtIns.builtInsPackageScope.getContributedDescriptors()
|
||||
.filter { it is ClassDescriptor && KotlinBuiltIns.isPrimitiveType(it.defaultType) } as List<ClassDescriptor>
|
||||
|
||||
for (descriptor in allPrimitiveTypes + builtIns.string) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val functions = descriptor.getMemberScope(listOf()).getContributedDescriptors()
|
||||
.filter { it is CallableDescriptor && !excludedFunctions.contains(it.getName().asString()) } as List<CallableDescriptor>
|
||||
|
||||
for (function in functions) {
|
||||
val parametersTypes = function.getParametersTypes()
|
||||
|
||||
when (parametersTypes.size) {
|
||||
1 -> unaryOperationsMap.add(Triple(function.name.asString(), parametersTypes, function is FunctionDescriptor))
|
||||
2 -> binaryOperationsMap.add(function.name.asString() to parametersTypes)
|
||||
else -> throw IllegalStateException(
|
||||
"Couldn't add following method from builtins to operations map: ${function.name} in class ${descriptor.name}"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun CallableDescriptor.getParametersTypes(): List<KotlinType> =
|
||||
listOf((containingDeclaration as ClassDescriptor).defaultType) +
|
||||
valueParameters.map { it.type.makeNotNullable() }
|
||||
Reference in New Issue
Block a user