FIR: generate operations map for CompileTimeConstantEvaluator
This commit is contained in:
@@ -5,7 +5,6 @@ plugins {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile(project(":compiler:fir:tree"))
|
compile(project(":compiler:fir:tree"))
|
||||||
compileOnly(project(":kotlin-reflect-api"))
|
|
||||||
|
|
||||||
compileOnly(intellijCoreDep()) { includeJars("intellij-core", rootProject = rootProject) }
|
compileOnly(intellijCoreDep()) { includeJars("intellij-core", rootProject = rootProject) }
|
||||||
}
|
}
|
||||||
|
|||||||
+22
-184
@@ -15,21 +15,20 @@ import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
|||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.types.impl.FirImplicitBuiltinTypeRef
|
import org.jetbrains.kotlin.fir.types.impl.FirImplicitBuiltinTypeRef
|
||||||
import org.jetbrains.kotlin.fir.types.impl.FirImplicitIntTypeRef
|
import org.jetbrains.kotlin.fir.types.impl.FirImplicitIntTypeRef
|
||||||
import kotlin.reflect.full.declaredFunctions
|
import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
||||||
import kotlin.reflect.full.valueParameters
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An evaluator that transform numeric operation, such as div, into compile-time constant iff involved operands, such as explicit receiver
|
* An evaluator that transform numeric operation, such as div, into compile-time constant iff involved operands, such as explicit receiver
|
||||||
* and the argument, are compile-time constant as well.
|
* and the argument, are compile-time constant as well.
|
||||||
*/
|
*/
|
||||||
// TODO: Handle boolean operators and const property loading
|
|
||||||
class CompileTimeConstantEvaluator {
|
class CompileTimeConstantEvaluator {
|
||||||
|
|
||||||
fun evaluate(expression: FirExpression): FirConstExpression<*>? =
|
// TODO: Handle boolean operators, const property loading, class reference, array, annotation values, etc.
|
||||||
if (expression is FirFunctionCall) {
|
fun evaluate(expression: FirExpression): ConstantValue<*>? =
|
||||||
evaluate(expression)
|
when (expression) {
|
||||||
} else {
|
is FirConstExpression<*> -> expression.value as? ConstantValue<*>
|
||||||
null
|
is FirFunctionCall -> evaluate(expression)?.value as? ConstantValue<*>
|
||||||
|
else -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun evaluate(functionCall: FirFunctionCall): FirConstExpression<*>? {
|
private fun evaluate(functionCall: FirFunctionCall): FirConstExpression<*>? {
|
||||||
@@ -98,32 +97,13 @@ class CompileTimeConstantEvaluator {
|
|||||||
|
|
||||||
// Unary operators
|
// Unary operators
|
||||||
private fun FirConstExpression<out Number>.evaluate(function: FirSimpleFunction): FirConstExpression<out Number>? {
|
private fun FirConstExpression<out Number>.evaluate(function: FirSimpleFunction): FirConstExpression<out Number>? {
|
||||||
val number = typedValue
|
val f = unaryOperations[UnaryOperationKey(kind, function.name.asString())] ?: return null
|
||||||
return when (function.name.asString()) {
|
// TODO: need some systematic check, e.g., integer overflow
|
||||||
"hashCode" ->
|
return try {
|
||||||
buildConstExpression(source, FirConstKind.Int, number.hashCode())
|
val r = f(typedValue)
|
||||||
"dec" ->
|
r.toFirConstKind()!!.toConstExpression(source, r)
|
||||||
kind.toConstExpression(source, number.dec())
|
} catch (e: Exception) {
|
||||||
"inc" ->
|
null
|
||||||
kind.toConstExpression(source, number.inc())
|
|
||||||
"unaryMinus" ->
|
|
||||||
kind.toConstExpression(source, number.unaryMinus())
|
|
||||||
"unaryPlus" ->
|
|
||||||
kind.toConstExpression(source, number.unaryPlus())
|
|
||||||
"toByte" ->
|
|
||||||
buildConstExpression(source, FirConstKind.Byte, number.toByte())
|
|
||||||
"toDouble" ->
|
|
||||||
buildConstExpression(source, FirConstKind.Double, number.toDouble())
|
|
||||||
"toFloat" ->
|
|
||||||
buildConstExpression(source, FirConstKind.Float, number.toFloat())
|
|
||||||
"toInt" ->
|
|
||||||
buildConstExpression(source, FirConstKind.Int, number.toInt())
|
|
||||||
"toLong" ->
|
|
||||||
buildConstExpression(source, FirConstKind.Long, number.toLong())
|
|
||||||
"toShort" ->
|
|
||||||
buildConstExpression(source, FirConstKind.Short, number.toShort())
|
|
||||||
else ->
|
|
||||||
null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,158 +112,16 @@ class CompileTimeConstantEvaluator {
|
|||||||
function: FirSimpleFunction,
|
function: FirSimpleFunction,
|
||||||
other: FirConstExpression<out Number>
|
other: FirConstExpression<out Number>
|
||||||
): FirConstExpression<out Number>? {
|
): FirConstExpression<out Number>? {
|
||||||
val n1 = typedValue
|
val f = binaryOperations[BinaryOperationKey(kind, other.kind, function.name.asString())] ?: return null
|
||||||
val n2 = other.typedValue
|
// TODO: need some systematic check, e.g., div by zero (1 / 0 v.s. 1 / 0.f)
|
||||||
return when (function.name.asString()) {
|
return try {
|
||||||
// TODO: more binary operators
|
val r = f(typedValue, other.typedValue)
|
||||||
"plus" ->
|
r.toFirConstKind()!!.toConstExpression(source, r)
|
||||||
n1.plus(n2).let { v -> v.toFirConstKind()!!.toConstExpression(source, v) }
|
} catch (e: Exception) {
|
||||||
else ->
|
null
|
||||||
null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////// UNARY OPERATORS
|
|
||||||
|
|
||||||
private fun Number.dec(): Number =
|
|
||||||
when (this) {
|
|
||||||
is Byte -> this.dec()
|
|
||||||
is Double -> this.dec()
|
|
||||||
is Float -> this.dec()
|
|
||||||
is Int -> this.dec()
|
|
||||||
is Long -> this.dec()
|
|
||||||
is Short -> this.dec()
|
|
||||||
else -> error("Unexpected Number kind: ${this.javaClass}")
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Number.inc(): Number =
|
|
||||||
when (this) {
|
|
||||||
is Byte -> this.inc()
|
|
||||||
is Double -> this.inc()
|
|
||||||
is Float -> this.inc()
|
|
||||||
is Int -> this.inc()
|
|
||||||
is Long -> this.inc()
|
|
||||||
is Short -> this.inc()
|
|
||||||
else -> error("Unexpected Number kind: ${this.javaClass}")
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Number.unaryMinus(): Number =
|
|
||||||
when (this) {
|
|
||||||
is Byte -> this.unaryMinus()
|
|
||||||
is Double -> this.unaryMinus()
|
|
||||||
is Float -> this.unaryMinus()
|
|
||||||
is Int -> this.unaryMinus()
|
|
||||||
is Long -> this.unaryMinus()
|
|
||||||
is Short -> this.unaryMinus()
|
|
||||||
else -> error("Unexpected Number kind: ${this.javaClass}")
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Number.unaryPlus(): Number =
|
|
||||||
when (this) {
|
|
||||||
is Byte -> this.unaryPlus()
|
|
||||||
is Double -> this.unaryPlus()
|
|
||||||
is Float -> this.unaryPlus()
|
|
||||||
is Int -> this.unaryPlus()
|
|
||||||
is Long -> this.unaryPlus()
|
|
||||||
is Short -> this.unaryPlus()
|
|
||||||
else -> error("Unexpected Number kind: ${this.javaClass}")
|
|
||||||
}
|
|
||||||
|
|
||||||
////// BINARY OPERATORS
|
|
||||||
|
|
||||||
// Design choice: reflection, which requires iteration over all declared functions every time, v.s., exhaustive type matching.
|
|
||||||
private fun Number.binaryOperation(name: String, other: Number): Number? {
|
|
||||||
val otherType = when (other) {
|
|
||||||
is Byte -> Byte::class
|
|
||||||
is Double -> Double::class
|
|
||||||
is Float -> Float::class
|
|
||||||
is Int -> Int::class
|
|
||||||
is Long -> Long::class
|
|
||||||
is Short -> Short::class
|
|
||||||
else -> error("Unexpected Number kind: ${this.javaClass}")
|
|
||||||
}
|
|
||||||
return this::class.declaredFunctions.find { kFunction ->
|
|
||||||
kFunction.name == name && kFunction.valueParameters.size == 1 && kFunction.valueParameters[0].type.classifier == otherType
|
|
||||||
}?.call(other) as? Number
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Number.plus(other: Number): Number =
|
|
||||||
when (this) {
|
|
||||||
is Byte -> this.plus(other)
|
|
||||||
is Double -> this.plus(other)
|
|
||||||
is Float -> this.plus(other)
|
|
||||||
is Int -> this.plus(other)
|
|
||||||
is Long -> this.plus(other)
|
|
||||||
is Short -> this.plus(other)
|
|
||||||
else -> error("Unexpected Number kind: ${this.javaClass}")
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Byte.plus(other: Number): Number =
|
|
||||||
when (other) {
|
|
||||||
is Byte -> this.plus(other)
|
|
||||||
is Double -> this.plus(other)
|
|
||||||
is Float -> this.plus(other)
|
|
||||||
is Int -> this.plus(other)
|
|
||||||
is Long -> this.plus(other)
|
|
||||||
is Short -> this.plus(other)
|
|
||||||
else -> error("Unexpected Number kind: ${this.javaClass}")
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Double.plus(other: Number): Number =
|
|
||||||
when (other) {
|
|
||||||
is Byte -> this.plus(other)
|
|
||||||
is Double -> this.plus(other)
|
|
||||||
is Float -> this.plus(other)
|
|
||||||
is Int -> this.plus(other)
|
|
||||||
is Long -> this.plus(other)
|
|
||||||
is Short -> this.plus(other)
|
|
||||||
else -> error("Unexpected Number kind: ${this.javaClass}")
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Float.plus(other: Number): Number =
|
|
||||||
when (other) {
|
|
||||||
is Byte -> this.plus(other)
|
|
||||||
is Double -> this.plus(other)
|
|
||||||
is Float -> this.plus(other)
|
|
||||||
is Int -> this.plus(other)
|
|
||||||
is Long -> this.plus(other)
|
|
||||||
is Short -> this.plus(other)
|
|
||||||
else -> error("Unexpected Number kind: ${this.javaClass}")
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Int.plus(other: Number): Number =
|
|
||||||
when (other) {
|
|
||||||
is Byte -> this.plus(other)
|
|
||||||
is Double -> this.plus(other)
|
|
||||||
is Float -> this.plus(other)
|
|
||||||
is Int -> this.plus(other)
|
|
||||||
is Long -> this.plus(other)
|
|
||||||
is Short -> this.plus(other)
|
|
||||||
else -> error("Unexpected Number kind: ${this.javaClass}")
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Long.plus(other: Number): Number =
|
|
||||||
when (other) {
|
|
||||||
is Byte -> this.plus(other)
|
|
||||||
is Double -> this.plus(other)
|
|
||||||
is Float -> this.plus(other)
|
|
||||||
is Int -> this.plus(other)
|
|
||||||
is Long -> this.plus(other)
|
|
||||||
is Short -> this.plus(other)
|
|
||||||
else -> error("Unexpected Number kind: ${this.javaClass}")
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Short.plus(other: Number): Number =
|
|
||||||
when (other) {
|
|
||||||
is Byte -> this.plus(other)
|
|
||||||
is Double -> this.plus(other)
|
|
||||||
is Float -> this.plus(other)
|
|
||||||
is Int -> this.plus(other)
|
|
||||||
is Long -> this.plus(other)
|
|
||||||
is Short -> this.plus(other)
|
|
||||||
else -> error("Unexpected Number kind: ${this.javaClass}")
|
|
||||||
}
|
|
||||||
|
|
||||||
////// KINDS
|
////// KINDS
|
||||||
|
|
||||||
private fun FirTypeRef.toFirConstKind(): FirConstKind<out Number>? =
|
private fun FirTypeRef.toFirConstKind(): FirConstKind<out Number>? =
|
||||||
@@ -357,7 +195,7 @@ class CompileTimeConstantEvaluator {
|
|||||||
|
|
||||||
// TODO: rangeTo?
|
// TODO: rangeTo?
|
||||||
private val binaryOperatorNames: Set<String> = setOf(
|
private val binaryOperatorNames: Set<String> = setOf(
|
||||||
"compareTo", "equals",
|
// TODO: "compareTo", "equals",
|
||||||
"div", "minus", "mod", "plus", "rem", "times"
|
"div", "minus", "mod", "plus", "rem", "times"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+293
@@ -0,0 +1,293 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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>
|
||||||
|
|
||||||
|
internal val unaryOperations: HashMap<UnaryOperationKey<*>, Function1<Number, Number>> = hashMapOf(
|
||||||
|
unaryOperation(FirConstKind.Byte, "dec", { a -> a.dec() }),
|
||||||
|
unaryOperation(FirConstKind.Byte, "hashCode", { a -> a.hashCode() }),
|
||||||
|
unaryOperation(FirConstKind.Byte, "inc", { a -> a.inc() }),
|
||||||
|
unaryOperation(FirConstKind.Byte, "toByte", { a -> a.toByte() }),
|
||||||
|
unaryOperation(FirConstKind.Byte, "toDouble", { a -> a.toDouble() }),
|
||||||
|
unaryOperation(FirConstKind.Byte, "toFloat", { a -> a.toFloat() }),
|
||||||
|
unaryOperation(FirConstKind.Byte, "toInt", { a -> a.toInt() }),
|
||||||
|
unaryOperation(FirConstKind.Byte, "toLong", { a -> a.toLong() }),
|
||||||
|
unaryOperation(FirConstKind.Byte, "toShort", { a -> a.toShort() }),
|
||||||
|
unaryOperation(FirConstKind.Byte, "unaryMinus", { a -> a.unaryMinus() }),
|
||||||
|
unaryOperation(FirConstKind.Byte, "unaryPlus", { a -> a.unaryPlus() }),
|
||||||
|
unaryOperation(FirConstKind.Double, "dec", { a -> a.dec() }),
|
||||||
|
unaryOperation(FirConstKind.Double, "hashCode", { a -> a.hashCode() }),
|
||||||
|
unaryOperation(FirConstKind.Double, "inc", { a -> a.inc() }),
|
||||||
|
unaryOperation(FirConstKind.Double, "toByte", { a -> a.toByte() }),
|
||||||
|
unaryOperation(FirConstKind.Double, "toDouble", { a -> a.toDouble() }),
|
||||||
|
unaryOperation(FirConstKind.Double, "toFloat", { a -> a.toFloat() }),
|
||||||
|
unaryOperation(FirConstKind.Double, "toInt", { a -> a.toInt() }),
|
||||||
|
unaryOperation(FirConstKind.Double, "toLong", { a -> a.toLong() }),
|
||||||
|
unaryOperation(FirConstKind.Double, "toShort", { a -> a.toShort() }),
|
||||||
|
unaryOperation(FirConstKind.Double, "unaryMinus", { a -> a.unaryMinus() }),
|
||||||
|
unaryOperation(FirConstKind.Double, "unaryPlus", { a -> a.unaryPlus() }),
|
||||||
|
unaryOperation(FirConstKind.Float, "dec", { a -> a.dec() }),
|
||||||
|
unaryOperation(FirConstKind.Float, "hashCode", { a -> a.hashCode() }),
|
||||||
|
unaryOperation(FirConstKind.Float, "inc", { a -> a.inc() }),
|
||||||
|
unaryOperation(FirConstKind.Float, "toByte", { a -> a.toByte() }),
|
||||||
|
unaryOperation(FirConstKind.Float, "toDouble", { a -> a.toDouble() }),
|
||||||
|
unaryOperation(FirConstKind.Float, "toFloat", { a -> a.toFloat() }),
|
||||||
|
unaryOperation(FirConstKind.Float, "toInt", { a -> a.toInt() }),
|
||||||
|
unaryOperation(FirConstKind.Float, "toLong", { a -> a.toLong() }),
|
||||||
|
unaryOperation(FirConstKind.Float, "toShort", { a -> a.toShort() }),
|
||||||
|
unaryOperation(FirConstKind.Float, "unaryMinus", { a -> a.unaryMinus() }),
|
||||||
|
unaryOperation(FirConstKind.Float, "unaryPlus", { a -> a.unaryPlus() }),
|
||||||
|
unaryOperation(FirConstKind.Int, "dec", { a -> a.dec() }),
|
||||||
|
unaryOperation(FirConstKind.Int, "hashCode", { a -> a.hashCode() }),
|
||||||
|
unaryOperation(FirConstKind.Int, "inc", { a -> a.inc() }),
|
||||||
|
unaryOperation(FirConstKind.Int, "inv", { a -> a.inv() }),
|
||||||
|
unaryOperation(FirConstKind.Int, "toByte", { a -> a.toByte() }),
|
||||||
|
unaryOperation(FirConstKind.Int, "toDouble", { a -> a.toDouble() }),
|
||||||
|
unaryOperation(FirConstKind.Int, "toFloat", { a -> a.toFloat() }),
|
||||||
|
unaryOperation(FirConstKind.Int, "toInt", { a -> a.toInt() }),
|
||||||
|
unaryOperation(FirConstKind.Int, "toLong", { a -> a.toLong() }),
|
||||||
|
unaryOperation(FirConstKind.Int, "toShort", { a -> a.toShort() }),
|
||||||
|
unaryOperation(FirConstKind.Int, "unaryMinus", { a -> a.unaryMinus() }),
|
||||||
|
unaryOperation(FirConstKind.Int, "unaryPlus", { a -> a.unaryPlus() }),
|
||||||
|
unaryOperation(FirConstKind.Long, "dec", { a -> a.dec() }),
|
||||||
|
unaryOperation(FirConstKind.Long, "hashCode", { a -> a.hashCode() }),
|
||||||
|
unaryOperation(FirConstKind.Long, "inc", { a -> a.inc() }),
|
||||||
|
unaryOperation(FirConstKind.Long, "inv", { a -> a.inv() }),
|
||||||
|
unaryOperation(FirConstKind.Long, "toByte", { a -> a.toByte() }),
|
||||||
|
unaryOperation(FirConstKind.Long, "toDouble", { a -> a.toDouble() }),
|
||||||
|
unaryOperation(FirConstKind.Long, "toFloat", { a -> a.toFloat() }),
|
||||||
|
unaryOperation(FirConstKind.Long, "toInt", { a -> a.toInt() }),
|
||||||
|
unaryOperation(FirConstKind.Long, "toLong", { a -> a.toLong() }),
|
||||||
|
unaryOperation(FirConstKind.Long, "toShort", { a -> a.toShort() }),
|
||||||
|
unaryOperation(FirConstKind.Long, "unaryMinus", { a -> a.unaryMinus() }),
|
||||||
|
unaryOperation(FirConstKind.Long, "unaryPlus", { a -> a.unaryPlus() }),
|
||||||
|
unaryOperation(FirConstKind.Short, "dec", { a -> a.dec() }),
|
||||||
|
unaryOperation(FirConstKind.Short, "hashCode", { a -> a.hashCode() }),
|
||||||
|
unaryOperation(FirConstKind.Short, "inc", { a -> a.inc() }),
|
||||||
|
unaryOperation(FirConstKind.Short, "toByte", { a -> a.toByte() }),
|
||||||
|
unaryOperation(FirConstKind.Short, "toDouble", { a -> a.toDouble() }),
|
||||||
|
unaryOperation(FirConstKind.Short, "toFloat", { a -> a.toFloat() }),
|
||||||
|
unaryOperation(FirConstKind.Short, "toInt", { a -> a.toInt() }),
|
||||||
|
unaryOperation(FirConstKind.Short, "toLong", { a -> a.toLong() }),
|
||||||
|
unaryOperation(FirConstKind.Short, "toShort", { a -> a.toShort() }),
|
||||||
|
unaryOperation(FirConstKind.Short, "unaryMinus", { a -> a.unaryMinus() }),
|
||||||
|
unaryOperation(FirConstKind.Short, "unaryPlus", { a -> a.unaryPlus() }),
|
||||||
|
)
|
||||||
|
|
||||||
|
internal val binaryOperations: HashMap<BinaryOperationKey<*, *>, Function2<Number, Number, Number>> = hashMapOf(
|
||||||
|
binaryOperation(FirConstKind.Byte, FirConstKind.Byte, "div", { a, b -> a.div(b) }),
|
||||||
|
binaryOperation(FirConstKind.Byte, FirConstKind.Double, "div", { a, b -> a.div(b) }),
|
||||||
|
binaryOperation(FirConstKind.Byte, FirConstKind.Float, "div", { a, b -> a.div(b) }),
|
||||||
|
binaryOperation(FirConstKind.Byte, FirConstKind.Int, "div", { a, b -> a.div(b) }),
|
||||||
|
binaryOperation(FirConstKind.Byte, FirConstKind.Long, "div", { a, b -> a.div(b) }),
|
||||||
|
binaryOperation(FirConstKind.Byte, FirConstKind.Short, "div", { a, b -> a.div(b) }),
|
||||||
|
binaryOperation(FirConstKind.Byte, FirConstKind.Byte, "minus", { a, b -> a.minus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Byte, FirConstKind.Double, "minus", { a, b -> a.minus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Byte, FirConstKind.Float, "minus", { a, b -> a.minus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Byte, FirConstKind.Int, "minus", { a, b -> a.minus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Byte, FirConstKind.Long, "minus", { a, b -> a.minus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Byte, FirConstKind.Short, "minus", { a, b -> a.minus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Byte, FirConstKind.Byte, "plus", { a, b -> a.plus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Byte, FirConstKind.Double, "plus", { a, b -> a.plus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Byte, FirConstKind.Float, "plus", { a, b -> a.plus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Byte, FirConstKind.Int, "plus", { a, b -> a.plus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Byte, FirConstKind.Long, "plus", { a, b -> a.plus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Byte, FirConstKind.Short, "plus", { a, b -> a.plus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Byte, FirConstKind.Byte, "rem", { a, b -> a.rem(b) }),
|
||||||
|
binaryOperation(FirConstKind.Byte, FirConstKind.Double, "rem", { a, b -> a.rem(b) }),
|
||||||
|
binaryOperation(FirConstKind.Byte, FirConstKind.Float, "rem", { a, b -> a.rem(b) }),
|
||||||
|
binaryOperation(FirConstKind.Byte, FirConstKind.Int, "rem", { a, b -> a.rem(b) }),
|
||||||
|
binaryOperation(FirConstKind.Byte, FirConstKind.Long, "rem", { a, b -> a.rem(b) }),
|
||||||
|
binaryOperation(FirConstKind.Byte, FirConstKind.Short, "rem", { a, b -> a.rem(b) }),
|
||||||
|
binaryOperation(FirConstKind.Byte, FirConstKind.Byte, "times", { a, b -> a.times(b) }),
|
||||||
|
binaryOperation(FirConstKind.Byte, FirConstKind.Double, "times", { a, b -> a.times(b) }),
|
||||||
|
binaryOperation(FirConstKind.Byte, FirConstKind.Float, "times", { a, b -> a.times(b) }),
|
||||||
|
binaryOperation(FirConstKind.Byte, FirConstKind.Int, "times", { a, b -> a.times(b) }),
|
||||||
|
binaryOperation(FirConstKind.Byte, FirConstKind.Long, "times", { a, b -> a.times(b) }),
|
||||||
|
binaryOperation(FirConstKind.Byte, FirConstKind.Short, "times", { a, b -> a.times(b) }),
|
||||||
|
binaryOperation(FirConstKind.Double, FirConstKind.Byte, "div", { a, b -> a.div(b) }),
|
||||||
|
binaryOperation(FirConstKind.Double, FirConstKind.Double, "div", { a, b -> a.div(b) }),
|
||||||
|
binaryOperation(FirConstKind.Double, FirConstKind.Float, "div", { a, b -> a.div(b) }),
|
||||||
|
binaryOperation(FirConstKind.Double, FirConstKind.Int, "div", { a, b -> a.div(b) }),
|
||||||
|
binaryOperation(FirConstKind.Double, FirConstKind.Long, "div", { a, b -> a.div(b) }),
|
||||||
|
binaryOperation(FirConstKind.Double, FirConstKind.Short, "div", { a, b -> a.div(b) }),
|
||||||
|
binaryOperation(FirConstKind.Double, FirConstKind.Byte, "minus", { a, b -> a.minus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Double, FirConstKind.Double, "minus", { a, b -> a.minus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Double, FirConstKind.Float, "minus", { a, b -> a.minus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Double, FirConstKind.Int, "minus", { a, b -> a.minus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Double, FirConstKind.Long, "minus", { a, b -> a.minus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Double, FirConstKind.Short, "minus", { a, b -> a.minus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Double, FirConstKind.Byte, "plus", { a, b -> a.plus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Double, FirConstKind.Double, "plus", { a, b -> a.plus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Double, FirConstKind.Float, "plus", { a, b -> a.plus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Double, FirConstKind.Int, "plus", { a, b -> a.plus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Double, FirConstKind.Long, "plus", { a, b -> a.plus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Double, FirConstKind.Short, "plus", { a, b -> a.plus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Double, FirConstKind.Byte, "rem", { a, b -> a.rem(b) }),
|
||||||
|
binaryOperation(FirConstKind.Double, FirConstKind.Double, "rem", { a, b -> a.rem(b) }),
|
||||||
|
binaryOperation(FirConstKind.Double, FirConstKind.Float, "rem", { a, b -> a.rem(b) }),
|
||||||
|
binaryOperation(FirConstKind.Double, FirConstKind.Int, "rem", { a, b -> a.rem(b) }),
|
||||||
|
binaryOperation(FirConstKind.Double, FirConstKind.Long, "rem", { a, b -> a.rem(b) }),
|
||||||
|
binaryOperation(FirConstKind.Double, FirConstKind.Short, "rem", { a, b -> a.rem(b) }),
|
||||||
|
binaryOperation(FirConstKind.Double, FirConstKind.Byte, "times", { a, b -> a.times(b) }),
|
||||||
|
binaryOperation(FirConstKind.Double, FirConstKind.Double, "times", { a, b -> a.times(b) }),
|
||||||
|
binaryOperation(FirConstKind.Double, FirConstKind.Float, "times", { a, b -> a.times(b) }),
|
||||||
|
binaryOperation(FirConstKind.Double, FirConstKind.Int, "times", { a, b -> a.times(b) }),
|
||||||
|
binaryOperation(FirConstKind.Double, FirConstKind.Long, "times", { a, b -> a.times(b) }),
|
||||||
|
binaryOperation(FirConstKind.Double, FirConstKind.Short, "times", { a, b -> a.times(b) }),
|
||||||
|
binaryOperation(FirConstKind.Float, FirConstKind.Byte, "div", { a, b -> a.div(b) }),
|
||||||
|
binaryOperation(FirConstKind.Float, FirConstKind.Double, "div", { a, b -> a.div(b) }),
|
||||||
|
binaryOperation(FirConstKind.Float, FirConstKind.Float, "div", { a, b -> a.div(b) }),
|
||||||
|
binaryOperation(FirConstKind.Float, FirConstKind.Int, "div", { a, b -> a.div(b) }),
|
||||||
|
binaryOperation(FirConstKind.Float, FirConstKind.Long, "div", { a, b -> a.div(b) }),
|
||||||
|
binaryOperation(FirConstKind.Float, FirConstKind.Short, "div", { a, b -> a.div(b) }),
|
||||||
|
binaryOperation(FirConstKind.Float, FirConstKind.Byte, "minus", { a, b -> a.minus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Float, FirConstKind.Double, "minus", { a, b -> a.minus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Float, FirConstKind.Float, "minus", { a, b -> a.minus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Float, FirConstKind.Int, "minus", { a, b -> a.minus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Float, FirConstKind.Long, "minus", { a, b -> a.minus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Float, FirConstKind.Short, "minus", { a, b -> a.minus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Float, FirConstKind.Byte, "plus", { a, b -> a.plus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Float, FirConstKind.Double, "plus", { a, b -> a.plus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Float, FirConstKind.Float, "plus", { a, b -> a.plus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Float, FirConstKind.Int, "plus", { a, b -> a.plus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Float, FirConstKind.Long, "plus", { a, b -> a.plus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Float, FirConstKind.Short, "plus", { a, b -> a.plus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Float, FirConstKind.Byte, "rem", { a, b -> a.rem(b) }),
|
||||||
|
binaryOperation(FirConstKind.Float, FirConstKind.Double, "rem", { a, b -> a.rem(b) }),
|
||||||
|
binaryOperation(FirConstKind.Float, FirConstKind.Float, "rem", { a, b -> a.rem(b) }),
|
||||||
|
binaryOperation(FirConstKind.Float, FirConstKind.Int, "rem", { a, b -> a.rem(b) }),
|
||||||
|
binaryOperation(FirConstKind.Float, FirConstKind.Long, "rem", { a, b -> a.rem(b) }),
|
||||||
|
binaryOperation(FirConstKind.Float, FirConstKind.Short, "rem", { a, b -> a.rem(b) }),
|
||||||
|
binaryOperation(FirConstKind.Float, FirConstKind.Byte, "times", { a, b -> a.times(b) }),
|
||||||
|
binaryOperation(FirConstKind.Float, FirConstKind.Double, "times", { a, b -> a.times(b) }),
|
||||||
|
binaryOperation(FirConstKind.Float, FirConstKind.Float, "times", { a, b -> a.times(b) }),
|
||||||
|
binaryOperation(FirConstKind.Float, FirConstKind.Int, "times", { a, b -> a.times(b) }),
|
||||||
|
binaryOperation(FirConstKind.Float, FirConstKind.Long, "times", { a, b -> a.times(b) }),
|
||||||
|
binaryOperation(FirConstKind.Float, FirConstKind.Short, "times", { a, b -> a.times(b) }),
|
||||||
|
binaryOperation(FirConstKind.Int, FirConstKind.Byte, "div", { a, b -> a.div(b) }),
|
||||||
|
binaryOperation(FirConstKind.Int, FirConstKind.Double, "div", { a, b -> a.div(b) }),
|
||||||
|
binaryOperation(FirConstKind.Int, FirConstKind.Float, "div", { a, b -> a.div(b) }),
|
||||||
|
binaryOperation(FirConstKind.Int, FirConstKind.Int, "div", { a, b -> a.div(b) }),
|
||||||
|
binaryOperation(FirConstKind.Int, FirConstKind.Long, "div", { a, b -> a.div(b) }),
|
||||||
|
binaryOperation(FirConstKind.Int, FirConstKind.Short, "div", { a, b -> a.div(b) }),
|
||||||
|
binaryOperation(FirConstKind.Int, FirConstKind.Byte, "minus", { a, b -> a.minus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Int, FirConstKind.Double, "minus", { a, b -> a.minus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Int, FirConstKind.Float, "minus", { a, b -> a.minus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Int, FirConstKind.Int, "minus", { a, b -> a.minus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Int, FirConstKind.Long, "minus", { a, b -> a.minus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Int, FirConstKind.Short, "minus", { a, b -> a.minus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Int, FirConstKind.Byte, "plus", { a, b -> a.plus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Int, FirConstKind.Double, "plus", { a, b -> a.plus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Int, FirConstKind.Float, "plus", { a, b -> a.plus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Int, FirConstKind.Int, "plus", { a, b -> a.plus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Int, FirConstKind.Long, "plus", { a, b -> a.plus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Int, FirConstKind.Short, "plus", { a, b -> a.plus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Int, FirConstKind.Byte, "rem", { a, b -> a.rem(b) }),
|
||||||
|
binaryOperation(FirConstKind.Int, FirConstKind.Double, "rem", { a, b -> a.rem(b) }),
|
||||||
|
binaryOperation(FirConstKind.Int, FirConstKind.Float, "rem", { a, b -> a.rem(b) }),
|
||||||
|
binaryOperation(FirConstKind.Int, FirConstKind.Int, "rem", { a, b -> a.rem(b) }),
|
||||||
|
binaryOperation(FirConstKind.Int, FirConstKind.Long, "rem", { a, b -> a.rem(b) }),
|
||||||
|
binaryOperation(FirConstKind.Int, FirConstKind.Short, "rem", { a, b -> a.rem(b) }),
|
||||||
|
binaryOperation(FirConstKind.Int, FirConstKind.Byte, "times", { a, b -> a.times(b) }),
|
||||||
|
binaryOperation(FirConstKind.Int, FirConstKind.Double, "times", { a, b -> a.times(b) }),
|
||||||
|
binaryOperation(FirConstKind.Int, FirConstKind.Float, "times", { a, b -> a.times(b) }),
|
||||||
|
binaryOperation(FirConstKind.Int, FirConstKind.Int, "times", { a, b -> a.times(b) }),
|
||||||
|
binaryOperation(FirConstKind.Int, FirConstKind.Long, "times", { a, b -> a.times(b) }),
|
||||||
|
binaryOperation(FirConstKind.Int, FirConstKind.Short, "times", { a, b -> a.times(b) }),
|
||||||
|
binaryOperation(FirConstKind.Long, FirConstKind.Byte, "div", { a, b -> a.div(b) }),
|
||||||
|
binaryOperation(FirConstKind.Long, FirConstKind.Double, "div", { a, b -> a.div(b) }),
|
||||||
|
binaryOperation(FirConstKind.Long, FirConstKind.Float, "div", { a, b -> a.div(b) }),
|
||||||
|
binaryOperation(FirConstKind.Long, FirConstKind.Int, "div", { a, b -> a.div(b) }),
|
||||||
|
binaryOperation(FirConstKind.Long, FirConstKind.Long, "div", { a, b -> a.div(b) }),
|
||||||
|
binaryOperation(FirConstKind.Long, FirConstKind.Short, "div", { a, b -> a.div(b) }),
|
||||||
|
binaryOperation(FirConstKind.Long, FirConstKind.Byte, "minus", { a, b -> a.minus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Long, FirConstKind.Double, "minus", { a, b -> a.minus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Long, FirConstKind.Float, "minus", { a, b -> a.minus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Long, FirConstKind.Int, "minus", { a, b -> a.minus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Long, FirConstKind.Long, "minus", { a, b -> a.minus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Long, FirConstKind.Short, "minus", { a, b -> a.minus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Long, FirConstKind.Byte, "plus", { a, b -> a.plus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Long, FirConstKind.Double, "plus", { a, b -> a.plus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Long, FirConstKind.Float, "plus", { a, b -> a.plus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Long, FirConstKind.Int, "plus", { a, b -> a.plus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Long, FirConstKind.Long, "plus", { a, b -> a.plus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Long, FirConstKind.Short, "plus", { a, b -> a.plus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Long, FirConstKind.Byte, "rem", { a, b -> a.rem(b) }),
|
||||||
|
binaryOperation(FirConstKind.Long, FirConstKind.Double, "rem", { a, b -> a.rem(b) }),
|
||||||
|
binaryOperation(FirConstKind.Long, FirConstKind.Float, "rem", { a, b -> a.rem(b) }),
|
||||||
|
binaryOperation(FirConstKind.Long, FirConstKind.Int, "rem", { a, b -> a.rem(b) }),
|
||||||
|
binaryOperation(FirConstKind.Long, FirConstKind.Long, "rem", { a, b -> a.rem(b) }),
|
||||||
|
binaryOperation(FirConstKind.Long, FirConstKind.Short, "rem", { a, b -> a.rem(b) }),
|
||||||
|
binaryOperation(FirConstKind.Long, FirConstKind.Byte, "times", { a, b -> a.times(b) }),
|
||||||
|
binaryOperation(FirConstKind.Long, FirConstKind.Double, "times", { a, b -> a.times(b) }),
|
||||||
|
binaryOperation(FirConstKind.Long, FirConstKind.Float, "times", { a, b -> a.times(b) }),
|
||||||
|
binaryOperation(FirConstKind.Long, FirConstKind.Int, "times", { a, b -> a.times(b) }),
|
||||||
|
binaryOperation(FirConstKind.Long, FirConstKind.Long, "times", { a, b -> a.times(b) }),
|
||||||
|
binaryOperation(FirConstKind.Long, FirConstKind.Short, "times", { a, b -> a.times(b) }),
|
||||||
|
binaryOperation(FirConstKind.Short, FirConstKind.Byte, "div", { a, b -> a.div(b) }),
|
||||||
|
binaryOperation(FirConstKind.Short, FirConstKind.Double, "div", { a, b -> a.div(b) }),
|
||||||
|
binaryOperation(FirConstKind.Short, FirConstKind.Float, "div", { a, b -> a.div(b) }),
|
||||||
|
binaryOperation(FirConstKind.Short, FirConstKind.Int, "div", { a, b -> a.div(b) }),
|
||||||
|
binaryOperation(FirConstKind.Short, FirConstKind.Long, "div", { a, b -> a.div(b) }),
|
||||||
|
binaryOperation(FirConstKind.Short, FirConstKind.Short, "div", { a, b -> a.div(b) }),
|
||||||
|
binaryOperation(FirConstKind.Short, FirConstKind.Byte, "minus", { a, b -> a.minus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Short, FirConstKind.Double, "minus", { a, b -> a.minus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Short, FirConstKind.Float, "minus", { a, b -> a.minus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Short, FirConstKind.Int, "minus", { a, b -> a.minus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Short, FirConstKind.Long, "minus", { a, b -> a.minus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Short, FirConstKind.Short, "minus", { a, b -> a.minus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Short, FirConstKind.Byte, "plus", { a, b -> a.plus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Short, FirConstKind.Double, "plus", { a, b -> a.plus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Short, FirConstKind.Float, "plus", { a, b -> a.plus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Short, FirConstKind.Int, "plus", { a, b -> a.plus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Short, FirConstKind.Long, "plus", { a, b -> a.plus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Short, FirConstKind.Short, "plus", { a, b -> a.plus(b) }),
|
||||||
|
binaryOperation(FirConstKind.Short, FirConstKind.Byte, "rem", { a, b -> a.rem(b) }),
|
||||||
|
binaryOperation(FirConstKind.Short, FirConstKind.Double, "rem", { a, b -> a.rem(b) }),
|
||||||
|
binaryOperation(FirConstKind.Short, FirConstKind.Float, "rem", { a, b -> a.rem(b) }),
|
||||||
|
binaryOperation(FirConstKind.Short, FirConstKind.Int, "rem", { a, b -> a.rem(b) }),
|
||||||
|
binaryOperation(FirConstKind.Short, FirConstKind.Long, "rem", { a, b -> a.rem(b) }),
|
||||||
|
binaryOperation(FirConstKind.Short, FirConstKind.Short, "rem", { a, b -> a.rem(b) }),
|
||||||
|
binaryOperation(FirConstKind.Short, FirConstKind.Byte, "times", { a, b -> a.times(b) }),
|
||||||
|
binaryOperation(FirConstKind.Short, FirConstKind.Double, "times", { a, b -> a.times(b) }),
|
||||||
|
binaryOperation(FirConstKind.Short, FirConstKind.Float, "times", { a, b -> a.times(b) }),
|
||||||
|
binaryOperation(FirConstKind.Short, FirConstKind.Int, "times", { a, b -> a.times(b) }),
|
||||||
|
binaryOperation(FirConstKind.Short, FirConstKind.Long, "times", { a, b -> a.times(b) }),
|
||||||
|
binaryOperation(FirConstKind.Short, FirConstKind.Short, "times", { a, b -> a.times(b) }),
|
||||||
|
)
|
||||||
@@ -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.DefaultBuiltIns
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
|
||||||
import org.jetbrains.kotlin.generators.util.GeneratorsFileUtil
|
import org.jetbrains.kotlin.generators.util.GeneratorsFileUtil
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
|
|
||||||
import org.jetbrains.kotlin.utils.Printer
|
import org.jetbrains.kotlin.utils.Printer
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
val DEST_FILE: File = File("compiler/frontend/src/org/jetbrains/kotlin/resolve/constants/evaluate/OperationsMapGenerated.kt")
|
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() {
|
fun main() {
|
||||||
GeneratorsFileUtil.writeFileIfContentChanged(DEST_FILE, generate())
|
GeneratorsFileUtil.writeFileIfContentChanged(DEST_FILE, generate())
|
||||||
@@ -40,6 +37,7 @@ fun generate(): String {
|
|||||||
|
|
||||||
val unaryOperationsMap = arrayListOf<Triple<String, List<KotlinType>, Boolean>>()
|
val unaryOperationsMap = arrayListOf<Triple<String, List<KotlinType>, Boolean>>()
|
||||||
val binaryOperationsMap = arrayListOf<Pair<String, List<KotlinType>>>()
|
val binaryOperationsMap = arrayListOf<Pair<String, List<KotlinType>>>()
|
||||||
|
populateOperationsMap(unaryOperationsMap, binaryOperationsMap, EXCLUDED_FUNCTIONS)
|
||||||
|
|
||||||
val builtIns = DefaultBuiltIns.Instance
|
val builtIns = DefaultBuiltIns.Instance
|
||||||
|
|
||||||
@@ -50,24 +48,6 @@ fun generate(): String {
|
|||||||
val integerTypes = allPrimitiveTypes.map { it.defaultType }.filter { it.isIntegerType() }
|
val integerTypes = allPrimitiveTypes.map { it.defaultType }.filter { it.isIntegerType() }
|
||||||
val fpTypes = allPrimitiveTypes.map { it.defaultType }.filter { it.isFpType() }
|
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))
|
unaryOperationsMap.add(Triple("code", listOf(builtIns.charType), false))
|
||||||
|
|
||||||
for (type in integerTypes) {
|
for (type in integerTypes) {
|
||||||
@@ -186,10 +166,6 @@ private fun KotlinType.isIntegerType(): Boolean =
|
|||||||
private fun KotlinType.isFpType(): Boolean =
|
private fun KotlinType.isFpType(): Boolean =
|
||||||
KotlinBuiltIns.isDouble(this) || KotlinBuiltIns.isFloat(this)
|
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 fun KotlinType.asString(): String = typeName.uppercase()
|
||||||
|
|
||||||
private val KotlinType.typeName: String
|
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() }
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* 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.test.evaluate
|
||||||
|
|
||||||
|
import junit.framework.TestCase
|
||||||
|
import org.jetbrains.kotlin.generators.evaluate.FIR_DEST_FILE
|
||||||
|
import org.jetbrains.kotlin.generators.evaluate.generateFirMap
|
||||||
|
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||||
|
|
||||||
|
class GenerateFirOperationsMapTest : TestCase() {
|
||||||
|
fun testGeneratedDataIsUpToDate() {
|
||||||
|
val text = generateFirMap()
|
||||||
|
KotlinTestUtils.assertEqualsToFile(FIR_DEST_FILE, text)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user