[FIR2IR] Add pre-caching of built-in classes to avoid their duplications

This commit is contained in:
Mikhail Glukhikh
2020-03-17 17:07:18 +03:00
parent 0bf4cac601
commit 6739135d17
46 changed files with 30 additions and 61 deletions
@@ -8,7 +8,9 @@ package org.jetbrains.kotlin.fir.backend
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.resolve.firProvider
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.types.FirTypeRef
@@ -45,6 +47,24 @@ class Fir2IrClassifierStorage(
private fun FirTypeRef.toIrType(typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT): IrType =
with(typeConverter) { toIrType(typeContext) }
fun preCacheBuiltinClasses() {
for ((classId, irBuiltinSymbol) in typeConverter.classIdToSymbolMap) {
val firClass = ConeClassLikeLookupTagImpl(classId).toSymbol(session)!!.fir as FirRegularClass
val irClass = irBuiltinSymbol.owner
classCache[firClass] = irClass
processClassHeader(firClass, irClass)
declarationStorage.preCacheBuiltinClassConstructorIfAny(firClass, irClass)
}
for ((primitiveClassId, primitiveArrayId) in StandardClassIds.primitiveArrayTypeByElementType) {
val firClass = ConeClassLikeLookupTagImpl(primitiveArrayId).toSymbol(session)!!.fir as FirRegularClass
val irType = typeConverter.classIdToTypeMap[primitiveClassId]
val irClass = irBuiltIns.primitiveArrayForType[irType]!!.owner
classCache[firClass] = irClass
processClassHeader(firClass, irClass)
declarationStorage.preCacheBuiltinClassConstructorIfAny(firClass, irClass)
}
}
internal fun IrDeclaration.declareThisReceiverParameter(
parent: IrDeclarationParent,
thisType: IrType,
@@ -354,14 +374,6 @@ class Fir2IrClassifierStorage(
fun getIrClassSymbol(firClassSymbol: FirClassSymbol<*>): IrClassSymbol {
val firClass = firClassSymbol.fir
getCachedIrClass(firClass)?.let { return symbolTable.referenceClass(it.descriptor) }
val builtinClassSymbol = when (firClassSymbol.classId) {
StandardClassIds.Any -> irBuiltIns.anyClass
else -> null
}
if (builtinClassSymbol != null && firClass is FirRegularClass) {
classCache[firClass] = builtinClassSymbol.owner
return symbolTable.referenceClass(builtinClassSymbol.descriptor)
}
// TODO: remove all this code and change to unbound symbol creation
val irClass = createIrClass(firClass)
if (firClass is FirAnonymousObject || firClass is FirRegularClass && firClass.visibility == Visibilities.LOCAL) {
@@ -186,7 +186,9 @@ class Fir2IrConverter(
val externalDependenciesGenerator = ExternalDependenciesGenerator(
symbolTable, generateTypicalIrProviderList(irModuleFragment.descriptor, builtIns, symbolTable)
)
// Necessary call to generate built-in IR classes
externalDependenciesGenerator.generateUnboundSymbolsAsDependencies()
classifierStorage.preCacheBuiltinClasses()
for (firFile in firFiles) {
converter.processClassHeaders(firFile)
}
@@ -66,6 +66,12 @@ class Fir2IrDeclarationStorage(
private val localStorage = Fir2IrLocalStorage()
internal fun preCacheBuiltinClassConstructorIfAny(firClass: FirRegularClass, irClass: IrClass) {
val primaryConstructor = firClass.getPrimaryConstructorIfAny() ?: return
val irConstructor = irClass.constructors.firstOrNull() ?: return
constructorCache[primaryConstructor] = irConstructor
}
fun registerFile(firFile: FirFile, irFile: IrFile) {
fileCache[firFile] = irFile
}
@@ -653,15 +659,6 @@ class Fir2IrDeclarationStorage(
fun getIrConstructorSymbol(firConstructorSymbol: FirConstructorSymbol): IrConstructorSymbol {
val firConstructor = firConstructorSymbol.fir
getCachedIrConstructor(firConstructor)?.let { return symbolTable.referenceConstructor(it.descriptor) }
val builtinParent = when (firConstructorSymbol.callableId.classId) {
StandardClassIds.Any -> irBuiltIns.anyClass
else -> null
}
if (builtinParent != null) {
val constructorSymbol = builtinParent.constructors.first()
constructorCache[firConstructor] = constructorSymbol.owner
return symbolTable.referenceConstructor(constructorSymbol.descriptor)
}
val irParent = findIrParent(firConstructor) as IrClass
val parentOrigin = (irParent as? IrDeclaration)?.origin ?: IrDeclarationOrigin.DEFINED
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.types.Variance
class Fir2IrTypeConverter(
private val components: Fir2IrComponents
) : Fir2IrComponents by components {
private val classIdToSymbolMap = mapOf(
internal val classIdToSymbolMap = mapOf(
StandardClassIds.Nothing to irBuiltIns.nothingClass,
StandardClassIds.Unit to irBuiltIns.unitClass,
StandardClassIds.Boolean to irBuiltIns.booleanClass,
@@ -37,7 +37,7 @@ class Fir2IrTypeConverter(
StandardClassIds.Array to irBuiltIns.arrayClass
)
private val classIdToTypeMap = mapOf(
internal val classIdToTypeMap = mapOf(
StandardClassIds.Nothing to irBuiltIns.nothingType,
StandardClassIds.Unit to irBuiltIns.unitType,
StandardClassIds.Boolean to irBuiltIns.booleanType,
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// WITH_RUNTIME
import kotlin.test.assertEquals
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// WITH_RUNTIME
import kotlin.test.assertEquals
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
operator fun Array<String>.get(index1: Int, index2: Int) = this[index1 + index2]
operator fun Array<String>.set(index1: Int, index2: Int, elem: String) {
this[index1 + index2] = elem
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
operator fun Array<String>.get(index1: Int, index2: Int) = this[index1 + index2]
operator fun Array<String>.set(index1: Int, index2: Int, elem: String) {
this[index1 + index2] = elem
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// KJS_WITH_FULL_RUNTIME
// WITH_RUNTIME
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// KJS_WITH_FULL_RUNTIME
// WITH_RUNTIME
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
class Foo(
val width: Int,
val height: Int,
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
fun box(): String {
val x = Array<Int>(5, { it } ).iterator()
var i = 0
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
fun box() : String {
val data = Array<Array<Boolean>>(3) { Array<Boolean>(4, {false}) }
for(d in data) {
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
class C(val i: Int) {
operator fun component1() = i + 1
operator fun component2() = i + 2
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
class C(val i: Int) {
}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
class C(val i: Int) {
operator fun component1() = i + 1
operator fun component2() = i + 2
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
operator fun Int.component1() = this + 1
operator fun Int.component2() = this + 2
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
operator fun Int.component1() = this + 1
operator fun Int.component2() = this + 2
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
fun box(): String {
val a = Array(2) { DoubleArray(3) }
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
fun box(): String {
val transform = transform(Array(1) { BooleanArray(1) })
if (!transform[0][0]) return "OK"
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
operator fun Long.component1() = this + 1
operator fun Long.component2() = this + 2
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
operator fun Long.component1() = this + 1
operator fun Long.component2() = this + 2
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
typealias ArrayS = Array<String>
fun testArray() {
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
class A() {
class B(val i: Int) {
}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// KJS_WITH_FULL_RUNTIME
// WITH_RUNTIME
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// WITH_RUNTIME
import kotlin.test.assertEquals
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// KT-25514 Support usage of function reference with vararg where function of array is expected in new inference
fun foo(x: Int, vararg y: String): String = y[0]
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
class MyNumber(val i: Int) {
operator fun inc(): MyNumber = MyNumber(i+1)
}
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
class mInt(val i : Int) {
override fun toString() : String = "mint: $i"
operator fun plus(i : Int) = mInt(this.i + i)
@@ -1,5 +1,4 @@
// !LANGUAGE: +AllowBreakAndContinueInsideWhen
// IGNORE_BACKEND_FIR: JVM_IR
fun testFor() {
val xs = IntArray(10) { i -> i }
@@ -1,5 +1,4 @@
// !LANGUAGE: +AllowBreakAndContinueInsideWhen
// IGNORE_BACKEND_FIR: JVM_IR
fun testFor() {
val xs = IntArray(10) { i -> i }
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// KJS_WITH_FULL_RUNTIME
// WITH_RUNTIME
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// KJS_WITH_FULL_RUNTIME
// WITH_RUNTIME
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
data class A(val x: Array<Int>, val y: IntArray)
fun foo(x: Array<Int>, y: IntArray) = A(x, y)
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
data class A(val x: Int, val y: String)
fun box(): String {
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// KJS_WITH_FULL_RUNTIME
// WITH_RUNTIME
fun foo() {
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
inline fun <reified T> jaggedArray(x: (Int, Int) -> T): Array<Array<T>> = Array(1) { i ->
Array(1) { j -> x(i, j) }
}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
inline fun <reified T> jaggedArray(x: (Int, Int, Int) -> T): Array<Array<Array<T>>> = Array(1) { i ->
Array(1) {
j -> Array(1) { k -> x(i, j, k) }
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// WITH_RUNTIME
// KJS_WITH_FULL_RUNTIME
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// WITH_RUNTIME
// KJS_WITH_FULL_RUNTIME
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// WITH_RUNTIME
// KJS_WITH_FULL_RUNTIME
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// WITH_RUNTIME
// KJS_WITH_FULL_RUNTIME
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
typealias BoolArray = Array<Boolean>
typealias IArray = IntArray
typealias MyArray<T> = Array<T>