[JS IR BE] Use constructor parameter to determine underlying type for inline classes

Inline classes from lazy IR may not have files.
This commit is contained in:
Svyatoslav Kuzmich
2019-04-17 19:03:07 +03:00
parent 3fd55673a8
commit 889b4d721d
2 changed files with 15 additions and 8 deletions
@@ -20,10 +20,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.classifierOrNull import org.jetbrains.kotlin.ir.types.classifierOrNull
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
import org.jetbrains.kotlin.ir.util.constructors import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.util.defaultType
import org.jetbrains.kotlin.ir.util.getInlineClassBackingField
import org.jetbrains.kotlin.ir.util.getInlinedClass
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
@@ -86,8 +83,8 @@ private class VarargTransformer(
val needUnboxing: Boolean val needUnboxing: Boolean
val arrayInlineClass = expression.type.getInlinedClass() val arrayInlineClass = expression.type.getInlinedClass()
if (arrayInlineClass != null) { if (arrayInlineClass != null) {
primitiveElementType = getInlineClassBackingField(elementType.getInlinedClass()!!).type primitiveElementType = getInlineClassUnderlyingType(elementType.getInlinedClass()!!)
primitiveExpressionType = getInlineClassBackingField(arrayInlineClass).type primitiveExpressionType = getInlineClassUnderlyingType(arrayInlineClass)
needUnboxing = true needUnboxing = true
} else { } else {
primitiveElementType = elementType primitiveElementType = elementType
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.ir.util package org.jetbrains.kotlin.ir.util
import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrConstructor
import org.jetbrains.kotlin.ir.declarations.IrField import org.jetbrains.kotlin.ir.declarations.IrField
import org.jetbrains.kotlin.ir.declarations.IrProperty import org.jetbrains.kotlin.ir.declarations.IrProperty
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
@@ -28,7 +29,7 @@ fun IrType.getInlinedClass(): IrClass? {
var fieldType: IrType var fieldType: IrType
var fieldInlinedClass = erased var fieldInlinedClass = erased
while (true) { while (true) {
fieldType = getInlineClassBackingField(fieldInlinedClass).type fieldType = getInlineClassUnderlyingType(fieldInlinedClass)
if (fieldType.isMarkedNullable()) { if (fieldType.isMarkedNullable()) {
return null return null
} }
@@ -55,6 +56,15 @@ private tailrec fun erase(type: IrType): IrClass? {
} }
} }
fun getInlineClassUnderlyingType(irClass: IrClass): IrType {
for (declaration in irClass.declarations) {
if (declaration is IrConstructor && declaration.isPrimary) {
return declaration.valueParameters[0].type
}
}
error("Inline class has no primary constructor: ${irClass.fqNameWhenAvailable}")
}
fun getInlineClassBackingField(irClass: IrClass): IrField { fun getInlineClassBackingField(irClass: IrClass): IrField {
for (declaration in irClass.declarations) { for (declaration in irClass.declarations) {
if (declaration is IrField) if (declaration is IrField)
@@ -63,5 +73,5 @@ fun getInlineClassBackingField(irClass: IrClass): IrField {
if (declaration is IrProperty) if (declaration is IrProperty)
return declaration.backingField ?: continue return declaration.backingField ?: continue
} }
error("Inline class has no field") error("Inline class has no field: ${irClass.fqNameWhenAvailable}")
} }