FIR2IR (refactoring): introduce Fir2IrTypeConverter
This commit is contained in:
@@ -22,18 +22,10 @@ import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
|||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrConstKind
|
import org.jetbrains.kotlin.ir.expressions.IrConstKind
|
||||||
import org.jetbrains.kotlin.ir.symbols.*
|
import org.jetbrains.kotlin.ir.symbols.*
|
||||||
import org.jetbrains.kotlin.ir.types.IrErrorType
|
import org.jetbrains.kotlin.ir.types.IrErrorType
|
||||||
import org.jetbrains.kotlin.ir.types.IrType
|
|
||||||
import org.jetbrains.kotlin.ir.types.IrTypeArgument
|
|
||||||
import org.jetbrains.kotlin.ir.types.impl.IrErrorTypeImpl
|
import org.jetbrains.kotlin.ir.types.impl.IrErrorTypeImpl
|
||||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
|
||||||
import org.jetbrains.kotlin.ir.types.impl.IrStarProjectionImpl
|
|
||||||
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
|
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.startOffsetSkippingComments
|
import org.jetbrains.kotlin.psi.psiUtil.startOffsetSkippingComments
|
||||||
@@ -70,93 +62,6 @@ class ConversionTypeContext internal constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun FirTypeRef.toIrType(
|
|
||||||
session: FirSession,
|
|
||||||
declarationStorage: Fir2IrDeclarationStorage,
|
|
||||||
irBuiltIns: IrBuiltIns,
|
|
||||||
typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT
|
|
||||||
): IrType {
|
|
||||||
if (this !is FirResolvedTypeRef) {
|
|
||||||
return createErrorType()
|
|
||||||
}
|
|
||||||
return type.toIrType(session, declarationStorage, irBuiltIns, typeContext)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun ConeKotlinType.toIrType(
|
|
||||||
session: FirSession,
|
|
||||||
declarationStorage: Fir2IrDeclarationStorage,
|
|
||||||
irBuiltIns: IrBuiltIns,
|
|
||||||
typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT
|
|
||||||
): IrType {
|
|
||||||
return when (this) {
|
|
||||||
is ConeKotlinErrorType -> createErrorType()
|
|
||||||
is ConeLookupTagBasedType -> {
|
|
||||||
val irSymbol = getArrayType(this.classId, irBuiltIns) ?: run {
|
|
||||||
val firSymbol = this.lookupTag.toSymbol(session) ?: return createErrorType()
|
|
||||||
firSymbol.toIrSymbol(session, declarationStorage, typeContext)
|
|
||||||
}
|
|
||||||
// TODO: annotations
|
|
||||||
IrSimpleTypeImpl(
|
|
||||||
irSymbol, !typeContext.definitelyNotNull && this.isMarkedNullable,
|
|
||||||
typeArguments.map { it.toIrTypeArgument(session, declarationStorage, irBuiltIns) },
|
|
||||||
emptyList()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
is ConeFlexibleType -> {
|
|
||||||
// TODO: yet we take more general type. Not quite sure it's Ok
|
|
||||||
upperBound.toIrType(session, declarationStorage, irBuiltIns, typeContext)
|
|
||||||
}
|
|
||||||
is ConeCapturedType -> TODO()
|
|
||||||
is ConeDefinitelyNotNullType -> {
|
|
||||||
original.toIrType(session, declarationStorage, irBuiltIns, typeContext.definitelyNotNull())
|
|
||||||
}
|
|
||||||
is ConeIntersectionType -> {
|
|
||||||
// TODO: add intersectionTypeApproximation
|
|
||||||
intersectedTypes.first().toIrType(session, declarationStorage, irBuiltIns, typeContext)
|
|
||||||
}
|
|
||||||
is ConeStubType -> createErrorType()
|
|
||||||
is ConeIntegerLiteralType -> getApproximatedType().toIrType(session, declarationStorage, irBuiltIns, typeContext)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getArrayType(classId: ClassId?, irBuiltIns: IrBuiltIns): IrClassifierSymbol? {
|
|
||||||
val irType = when (classId) {
|
|
||||||
ClassId(FqName("kotlin"), FqName("Array"), false) -> return irBuiltIns.arrayClass
|
|
||||||
ClassId(FqName("kotlin"), FqName("BooleanArray"), false) -> irBuiltIns.booleanType
|
|
||||||
ClassId(FqName("kotlin"), FqName("ByteArray"), false) -> irBuiltIns.byteType
|
|
||||||
ClassId(FqName("kotlin"), FqName("CharArray"), false) -> irBuiltIns.charType
|
|
||||||
ClassId(FqName("kotlin"), FqName("DoubleArray"), false) -> irBuiltIns.doubleType
|
|
||||||
ClassId(FqName("kotlin"), FqName("FloatArray"), false) -> irBuiltIns.floatType
|
|
||||||
ClassId(FqName("kotlin"), FqName("IntArray"), false) -> irBuiltIns.intType
|
|
||||||
ClassId(FqName("kotlin"), FqName("LongArray"), false) -> irBuiltIns.longType
|
|
||||||
ClassId(FqName("kotlin"), FqName("ShortArray"), false) -> irBuiltIns.shortType
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
return irType?.let { irBuiltIns.primitiveArrayForType.getValue(it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun ConeTypeProjection.toIrTypeArgument(
|
|
||||||
session: FirSession,
|
|
||||||
declarationStorage: Fir2IrDeclarationStorage,
|
|
||||||
irBuiltIns: IrBuiltIns
|
|
||||||
): IrTypeArgument {
|
|
||||||
return when (this) {
|
|
||||||
ConeStarProjection -> IrStarProjectionImpl
|
|
||||||
is ConeKotlinTypeProjectionIn -> {
|
|
||||||
val irType = this.type.toIrType(session, declarationStorage, irBuiltIns)
|
|
||||||
makeTypeProjection(irType, Variance.IN_VARIANCE)
|
|
||||||
}
|
|
||||||
is ConeKotlinTypeProjectionOut -> {
|
|
||||||
val irType = this.type.toIrType(session, declarationStorage, irBuiltIns)
|
|
||||||
makeTypeProjection(irType, Variance.OUT_VARIANCE)
|
|
||||||
}
|
|
||||||
is ConeKotlinType -> {
|
|
||||||
val irType = toIrType(session, declarationStorage, irBuiltIns)
|
|
||||||
makeTypeProjection(irType, Variance.INVARIANT)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun FirClassifierSymbol<*>.toIrSymbol(
|
fun FirClassifierSymbol<*>.toIrSymbol(
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
declarationStorage: Fir2IrDeclarationStorage,
|
declarationStorage: Fir2IrDeclarationStorage,
|
||||||
|
|||||||
+29
-34
@@ -46,8 +46,7 @@ import org.jetbrains.kotlin.psi.psiUtil.startOffsetSkippingComments
|
|||||||
class Fir2IrDeclarationStorage(
|
class Fir2IrDeclarationStorage(
|
||||||
private val session: FirSession,
|
private val session: FirSession,
|
||||||
private val irSymbolTable: SymbolTable,
|
private val irSymbolTable: SymbolTable,
|
||||||
private val moduleDescriptor: FirModuleDescriptor,
|
private val moduleDescriptor: FirModuleDescriptor
|
||||||
private val irBuiltIns: IrBuiltIns
|
|
||||||
) {
|
) {
|
||||||
private val firSymbolProvider = session.firSymbolProvider
|
private val firSymbolProvider = session.firSymbolProvider
|
||||||
|
|
||||||
@@ -75,7 +74,7 @@ class Fir2IrDeclarationStorage(
|
|||||||
|
|
||||||
private val localStorage = Fir2IrLocalStorage()
|
private val localStorage = Fir2IrLocalStorage()
|
||||||
|
|
||||||
private val unitType = session.builtinTypes.unitType.toIrType(session, this)
|
lateinit var typeConverter: Fir2IrTypeConverter
|
||||||
|
|
||||||
fun registerFile(firFile: FirFile, irFile: IrFile) {
|
fun registerFile(firFile: FirFile, irFile: IrFile) {
|
||||||
fileCache[firFile] = irFile
|
fileCache[firFile] = irFile
|
||||||
@@ -102,11 +101,11 @@ class Fir2IrDeclarationStorage(
|
|||||||
irSymbolTable.leaveScope(descriptor)
|
irSymbolTable.leaveScope(descriptor)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FirTypeRef.toIrType(
|
private fun FirTypeRef.toIrType(typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT): IrType =
|
||||||
session: FirSession,
|
with(typeConverter) { toIrType(typeContext) }
|
||||||
declarationStorage: Fir2IrDeclarationStorage,
|
|
||||||
typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT
|
private fun ConeKotlinType.toIrType(typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT): IrType =
|
||||||
) = toIrType(session, declarationStorage, irBuiltIns, typeContext)
|
with(typeConverter) { toIrType(typeContext) }
|
||||||
|
|
||||||
private fun getIrExternalPackageFragment(fqName: FqName): IrExternalPackageFragment {
|
private fun getIrExternalPackageFragment(fqName: FqName): IrExternalPackageFragment {
|
||||||
return fragmentCache.getOrPut(fqName) {
|
return fragmentCache.getOrPut(fqName) {
|
||||||
@@ -172,9 +171,7 @@ class Fir2IrDeclarationStorage(
|
|||||||
if (klass is FirRegularClass) {
|
if (klass is FirRegularClass) {
|
||||||
setTypeParameters(klass)
|
setTypeParameters(klass)
|
||||||
}
|
}
|
||||||
superTypes = klass.superTypeRefs.map { superTypeRef ->
|
superTypes = klass.superTypeRefs.map { superTypeRef -> superTypeRef.toIrType() }
|
||||||
superTypeRef.toIrType(session, this@Fir2IrDeclarationStorage)
|
|
||||||
}
|
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -348,7 +345,7 @@ class Fir2IrDeclarationStorage(
|
|||||||
}
|
}
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
val parent = simpleCachedParameter.parent
|
val parent = simpleCachedParameter.parent
|
||||||
if (parent !is IrSimpleFunction || parent.returnType == unitType) {
|
if (parent !is IrSimpleFunction || parent.returnType == typeConverter.unitType) {
|
||||||
return simpleCachedParameter
|
return simpleCachedParameter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -383,7 +380,7 @@ class Fir2IrDeclarationStorage(
|
|||||||
} else {
|
} else {
|
||||||
typeParameterCache[typeParameter] = irTypeParameter
|
typeParameterCache[typeParameter] = irTypeParameter
|
||||||
}
|
}
|
||||||
bounds.mapTo(irTypeParameter.superTypes) { it.toIrType(session, this@Fir2IrDeclarationStorage) }
|
bounds.mapTo(irTypeParameter.superTypes) { it.toIrType() }
|
||||||
irTypeParameter
|
irTypeParameter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -460,9 +457,7 @@ class Fir2IrDeclarationStorage(
|
|||||||
origin = if (forSetter) ConversionTypeOrigin.SETTER else ConversionTypeOrigin.DEFAULT
|
origin = if (forSetter) ConversionTypeOrigin.SETTER else ConversionTypeOrigin.DEFAULT
|
||||||
)
|
)
|
||||||
if (function is FirDefaultPropertySetter) {
|
if (function is FirDefaultPropertySetter) {
|
||||||
val type = function.valueParameters.first().returnTypeRef.toIrType(
|
val type = function.valueParameters.first().returnTypeRef.toIrType(ConversionTypeContext.DEFAULT.inSetter())
|
||||||
session, this@Fir2IrDeclarationStorage, ConversionTypeContext.DEFAULT.inSetter()
|
|
||||||
)
|
|
||||||
declareDefaultSetterParameter(type)
|
declareDefaultSetterParameter(type)
|
||||||
} else if (function != null) {
|
} else if (function != null) {
|
||||||
valueParameters = function.valueParameters.mapIndexed { index, valueParameter ->
|
valueParameters = function.valueParameters.mapIndexed { index, valueParameter ->
|
||||||
@@ -482,7 +477,7 @@ class Fir2IrDeclarationStorage(
|
|||||||
extensionReceiverParameter = receiverTypeRef.convertWithOffsets { startOffset, endOffset ->
|
extensionReceiverParameter = receiverTypeRef.convertWithOffsets { startOffset, endOffset ->
|
||||||
declareThisReceiverParameter(
|
declareThisReceiverParameter(
|
||||||
parent,
|
parent,
|
||||||
thisType = receiverTypeRef.toIrType(session, this@Fir2IrDeclarationStorage, typeContext),
|
thisType = receiverTypeRef.toIrType(typeContext),
|
||||||
thisOrigin = thisOrigin,
|
thisOrigin = thisOrigin,
|
||||||
startOffset = startOffset,
|
startOffset = startOffset,
|
||||||
endOffset = endOffset
|
endOffset = endOffset
|
||||||
@@ -542,7 +537,7 @@ class Fir2IrDeclarationStorage(
|
|||||||
IrFunctionImpl(
|
IrFunctionImpl(
|
||||||
startOffset, endOffset, updatedOrigin, symbol,
|
startOffset, endOffset, updatedOrigin, symbol,
|
||||||
function.name, function.visibility, function.modality!!,
|
function.name, function.visibility, function.modality!!,
|
||||||
function.returnTypeRef.toIrType(session, this),
|
function.returnTypeRef.toIrType(),
|
||||||
isInline = function.isInline,
|
isInline = function.isInline,
|
||||||
isExternal = function.isExternal,
|
isExternal = function.isExternal,
|
||||||
isTailrec = function.isTailRec,
|
isTailrec = function.isTailRec,
|
||||||
@@ -594,7 +589,7 @@ class Fir2IrDeclarationStorage(
|
|||||||
startOffset, endOffset, origin, symbol,
|
startOffset, endOffset, origin, symbol,
|
||||||
if (isLambda) Name.special("<anonymous>") else Name.special("<no name provided>"),
|
if (isLambda) Name.special("<anonymous>") else Name.special("<no name provided>"),
|
||||||
Visibilities.LOCAL, Modality.FINAL,
|
Visibilities.LOCAL, Modality.FINAL,
|
||||||
function.returnTypeRef.toIrType(session, this),
|
function.returnTypeRef.toIrType(),
|
||||||
isInline = false, isExternal = false, isTailrec = false,
|
isInline = false, isExternal = false, isTailrec = false,
|
||||||
// TODO: suspend lambda
|
// TODO: suspend lambda
|
||||||
isSuspend = false,
|
isSuspend = false,
|
||||||
@@ -630,7 +625,7 @@ class Fir2IrDeclarationStorage(
|
|||||||
IrConstructorImpl(
|
IrConstructorImpl(
|
||||||
startOffset, endOffset, origin, symbol,
|
startOffset, endOffset, origin, symbol,
|
||||||
Name.special("<init>"), visibility,
|
Name.special("<init>"), visibility,
|
||||||
constructor.returnTypeRef.toIrType(session, this),
|
constructor.returnTypeRef.toIrType(),
|
||||||
isInline = false, isExternal = false, isPrimary = isPrimary, isExpect = false
|
isInline = false, isExternal = false, isPrimary = isPrimary, isExpect = false
|
||||||
).bindAndDeclareParameters(constructor, descriptor, irParent, isStatic = true, shouldLeaveScope = shouldLeaveScope)
|
).bindAndDeclareParameters(constructor, descriptor, irParent, isStatic = true, shouldLeaveScope = shouldLeaveScope)
|
||||||
}
|
}
|
||||||
@@ -661,7 +656,7 @@ class Fir2IrDeclarationStorage(
|
|||||||
propertyAccessor?.psi?.endOffset ?: endOffset,
|
propertyAccessor?.psi?.endOffset ?: endOffset,
|
||||||
origin, descriptor
|
origin, descriptor
|
||||||
) { symbol ->
|
) { symbol ->
|
||||||
val accessorReturnType = if (isSetter) unitType else propertyType
|
val accessorReturnType = if (isSetter) typeConverter.unitType else propertyType
|
||||||
IrFunctionImpl(
|
IrFunctionImpl(
|
||||||
startOffset, endOffset, origin, symbol,
|
startOffset, endOffset, origin, symbol,
|
||||||
Name.special("<$prefix-${correspondingProperty.name}>"),
|
Name.special("<$prefix-${correspondingProperty.name}>"),
|
||||||
@@ -671,13 +666,15 @@ class Fir2IrDeclarationStorage(
|
|||||||
isFakeOverride = origin == IrDeclarationOrigin.FAKE_OVERRIDE,
|
isFakeOverride = origin == IrDeclarationOrigin.FAKE_OVERRIDE,
|
||||||
isOperator = false
|
isOperator = false
|
||||||
).apply {
|
).apply {
|
||||||
setTypeParameters(property, ConversionTypeContext(
|
setTypeParameters(
|
||||||
definitelyNotNull = false,
|
property, ConversionTypeContext(
|
||||||
origin = if (isSetter) ConversionTypeOrigin.SETTER else ConversionTypeOrigin.DEFAULT
|
definitelyNotNull = false,
|
||||||
))
|
origin = if (isSetter) ConversionTypeOrigin.SETTER else ConversionTypeOrigin.DEFAULT
|
||||||
|
)
|
||||||
|
)
|
||||||
if (propertyAccessor == null && isSetter) {
|
if (propertyAccessor == null && isSetter) {
|
||||||
declareDefaultSetterParameter(
|
declareDefaultSetterParameter(
|
||||||
property.returnTypeRef.toIrType(session, this@Fir2IrDeclarationStorage, ConversionTypeContext.DEFAULT.inSetter())
|
property.returnTypeRef.toIrType(ConversionTypeContext.DEFAULT.inSetter())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}.bindAndDeclareParameters(
|
}.bindAndDeclareParameters(
|
||||||
@@ -707,7 +704,7 @@ class Fir2IrDeclarationStorage(
|
|||||||
startOffset, endOffset, origin, symbol, enumEntry.name
|
startOffset, endOffset, origin, symbol, enumEntry.name
|
||||||
).apply {
|
).apply {
|
||||||
desc.bind(this)
|
desc.bind(this)
|
||||||
val irType = enumEntry.returnTypeRef.toIrType(session, this@Fir2IrDeclarationStorage)
|
val irType = enumEntry.returnTypeRef.toIrType()
|
||||||
if (irParent != null) {
|
if (irParent != null) {
|
||||||
this.parent = irParent
|
this.parent = irParent
|
||||||
}
|
}
|
||||||
@@ -758,7 +755,7 @@ class Fir2IrDeclarationStorage(
|
|||||||
isFakeOverride = origin == IrDeclarationOrigin.FAKE_OVERRIDE
|
isFakeOverride = origin == IrDeclarationOrigin.FAKE_OVERRIDE
|
||||||
).apply {
|
).apply {
|
||||||
descriptor.bind(this)
|
descriptor.bind(this)
|
||||||
val type = property.returnTypeRef.toIrType(session, this@Fir2IrDeclarationStorage)
|
val type = property.returnTypeRef.toIrType()
|
||||||
getter = createIrPropertyAccessor(
|
getter = createIrPropertyAccessor(
|
||||||
property.getter, property, this, type, irParent, false,
|
property.getter, property, this, type, irParent, false,
|
||||||
when {
|
when {
|
||||||
@@ -791,7 +788,7 @@ class Fir2IrDeclarationStorage(
|
|||||||
return fieldCache.getOrPut(field) {
|
return fieldCache.getOrPut(field) {
|
||||||
val descriptor = WrappedFieldDescriptor()
|
val descriptor = WrappedFieldDescriptor()
|
||||||
val origin = IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB
|
val origin = IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB
|
||||||
val type = field.returnTypeRef.toIrType(session, this)
|
val type = field.returnTypeRef.toIrType()
|
||||||
field.convertWithOffsets { startOffset, endOffset ->
|
field.convertWithOffsets { startOffset, endOffset ->
|
||||||
irSymbolTable.declareField(
|
irSymbolTable.declareField(
|
||||||
startOffset, endOffset,
|
startOffset, endOffset,
|
||||||
@@ -820,7 +817,7 @@ class Fir2IrDeclarationStorage(
|
|||||||
): IrValueParameter {
|
): IrValueParameter {
|
||||||
val descriptor = WrappedValueParameterDescriptor()
|
val descriptor = WrappedValueParameterDescriptor()
|
||||||
val origin = IrDeclarationOrigin.DEFINED
|
val origin = IrDeclarationOrigin.DEFINED
|
||||||
val type = valueParameter.returnTypeRef.toIrType(session, this)
|
val type = valueParameter.returnTypeRef.toIrType()
|
||||||
val irParameter = valueParameter.convertWithOffsets { startOffset, endOffset ->
|
val irParameter = valueParameter.convertWithOffsets { startOffset, endOffset ->
|
||||||
irSymbolTable.declareValueParameter(
|
irSymbolTable.declareValueParameter(
|
||||||
startOffset, endOffset, origin, descriptor, type
|
startOffset, endOffset, origin, descriptor, type
|
||||||
@@ -829,9 +826,7 @@ class Fir2IrDeclarationStorage(
|
|||||||
startOffset, endOffset, origin, symbol,
|
startOffset, endOffset, origin, symbol,
|
||||||
valueParameter.name, index, type,
|
valueParameter.name, index, type,
|
||||||
if (!valueParameter.isVararg) null
|
if (!valueParameter.isVararg) null
|
||||||
else valueParameter.returnTypeRef.coneTypeSafe<ConeKotlinType>()?.arrayElementType(session)?.toIrType(
|
else valueParameter.returnTypeRef.coneTypeSafe<ConeKotlinType>()?.arrayElementType(session)?.toIrType(typeContext),
|
||||||
session, this, irBuiltIns, typeContext
|
|
||||||
),
|
|
||||||
valueParameter.isCrossinline, valueParameter.isNoinline
|
valueParameter.isCrossinline, valueParameter.isNoinline
|
||||||
).apply {
|
).apply {
|
||||||
descriptor.bind(this)
|
descriptor.bind(this)
|
||||||
@@ -878,7 +873,7 @@ class Fir2IrDeclarationStorage(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun createAndSaveIrVariable(variable: FirVariable<*>, givenOrigin: IrDeclarationOrigin? = null): IrVariable {
|
fun createAndSaveIrVariable(variable: FirVariable<*>, givenOrigin: IrDeclarationOrigin? = null): IrVariable {
|
||||||
val type = variable.returnTypeRef.toIrType(session, this)
|
val type = variable.returnTypeRef.toIrType()
|
||||||
// Some temporary variables are produced in RawFirBuilder, but we consistently use special names for them.
|
// Some temporary variables are produced in RawFirBuilder, but we consistently use special names for them.
|
||||||
val origin = when {
|
val origin = when {
|
||||||
givenOrigin != null -> givenOrigin
|
givenOrigin != null -> givenOrigin
|
||||||
|
|||||||
@@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
* 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.fir.backend
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
|
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
|
import org.jetbrains.kotlin.ir.types.IrTypeArgument
|
||||||
|
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||||
|
import org.jetbrains.kotlin.ir.types.impl.IrStarProjectionImpl
|
||||||
|
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
|
||||||
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.types.Variance
|
||||||
|
|
||||||
|
class Fir2IrTypeConverter(
|
||||||
|
private val session: FirSession,
|
||||||
|
private val declarationStorage: Fir2IrDeclarationStorage,
|
||||||
|
private val irBuiltIns: IrBuiltIns
|
||||||
|
) {
|
||||||
|
lateinit var nothingType: IrType
|
||||||
|
lateinit var unitType: IrType
|
||||||
|
lateinit var booleanType: IrType
|
||||||
|
lateinit var stringType: IrType
|
||||||
|
|
||||||
|
fun initBuiltinTypes() {
|
||||||
|
nothingType = session.builtinTypes.nothingType.toIrType()
|
||||||
|
unitType = session.builtinTypes.unitType.toIrType()
|
||||||
|
booleanType = session.builtinTypes.booleanType.toIrType()
|
||||||
|
stringType = session.builtinTypes.stringType.toIrType()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun FirTypeRef.toIrType(typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT): IrType {
|
||||||
|
if (this !is FirResolvedTypeRef) {
|
||||||
|
return createErrorType()
|
||||||
|
}
|
||||||
|
return type.toIrType(typeContext)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun ConeKotlinType.toIrType(typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT): IrType {
|
||||||
|
return when (this) {
|
||||||
|
is ConeKotlinErrorType -> createErrorType()
|
||||||
|
is ConeLookupTagBasedType -> {
|
||||||
|
val irSymbol = getArrayType(this.classId) ?: run {
|
||||||
|
val firSymbol = this.lookupTag.toSymbol(session) ?: return createErrorType()
|
||||||
|
firSymbol.toIrSymbol(session, declarationStorage, typeContext)
|
||||||
|
}
|
||||||
|
// TODO: annotations
|
||||||
|
IrSimpleTypeImpl(
|
||||||
|
irSymbol, !typeContext.definitelyNotNull && this.isMarkedNullable,
|
||||||
|
typeArguments.map { it.toIrTypeArgument() },
|
||||||
|
emptyList()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
is ConeFlexibleType -> {
|
||||||
|
// TODO: yet we take more general type. Not quite sure it's Ok
|
||||||
|
upperBound.toIrType(typeContext)
|
||||||
|
}
|
||||||
|
is ConeCapturedType -> TODO()
|
||||||
|
is ConeDefinitelyNotNullType -> {
|
||||||
|
original.toIrType(typeContext.definitelyNotNull())
|
||||||
|
}
|
||||||
|
is ConeIntersectionType -> {
|
||||||
|
// TODO: add intersectionTypeApproximation
|
||||||
|
intersectedTypes.first().toIrType(typeContext)
|
||||||
|
}
|
||||||
|
is ConeStubType -> createErrorType()
|
||||||
|
is ConeIntegerLiteralType -> getApproximatedType().toIrType(typeContext)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun ConeTypeProjection.toIrTypeArgument(): IrTypeArgument {
|
||||||
|
return when (this) {
|
||||||
|
ConeStarProjection -> IrStarProjectionImpl
|
||||||
|
is ConeKotlinTypeProjectionIn -> {
|
||||||
|
val irType = this.type.toIrType()
|
||||||
|
makeTypeProjection(irType, Variance.IN_VARIANCE)
|
||||||
|
}
|
||||||
|
is ConeKotlinTypeProjectionOut -> {
|
||||||
|
val irType = this.type.toIrType()
|
||||||
|
makeTypeProjection(irType, Variance.OUT_VARIANCE)
|
||||||
|
}
|
||||||
|
is ConeKotlinType -> {
|
||||||
|
val irType = toIrType()
|
||||||
|
makeTypeProjection(irType, Variance.INVARIANT)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getArrayType(classId: ClassId?): IrClassifierSymbol? {
|
||||||
|
val irType = when (classId) {
|
||||||
|
ClassId(FqName("kotlin"), FqName("Array"), false) -> return irBuiltIns.arrayClass
|
||||||
|
ClassId(FqName("kotlin"), FqName("BooleanArray"), false) -> irBuiltIns.booleanType
|
||||||
|
ClassId(FqName("kotlin"), FqName("ByteArray"), false) -> irBuiltIns.byteType
|
||||||
|
ClassId(FqName("kotlin"), FqName("CharArray"), false) -> irBuiltIns.charType
|
||||||
|
ClassId(FqName("kotlin"), FqName("DoubleArray"), false) -> irBuiltIns.doubleType
|
||||||
|
ClassId(FqName("kotlin"), FqName("FloatArray"), false) -> irBuiltIns.floatType
|
||||||
|
ClassId(FqName("kotlin"), FqName("IntArray"), false) -> irBuiltIns.intType
|
||||||
|
ClassId(FqName("kotlin"), FqName("LongArray"), false) -> irBuiltIns.longType
|
||||||
|
ClassId(FqName("kotlin"), FqName("ShortArray"), false) -> irBuiltIns.shortType
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
return irType?.let { irBuiltIns.primitiveArrayForType.getValue(it) }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -68,15 +68,12 @@ class Fir2IrVisitor(
|
|||||||
|
|
||||||
private val integerApproximator = IntegerLiteralTypeApproximationTransformer(session.firSymbolProvider, session.inferenceContext)
|
private val integerApproximator = IntegerLiteralTypeApproximationTransformer(session.firSymbolProvider, session.inferenceContext)
|
||||||
|
|
||||||
private val declarationStorage = Fir2IrDeclarationStorage(session, symbolTable, moduleDescriptor, irBuiltIns)
|
private val declarationStorage = Fir2IrDeclarationStorage(session, symbolTable, moduleDescriptor)
|
||||||
|
|
||||||
private val nothingType = session.builtinTypes.nothingType.toIrType(session, declarationStorage)
|
private val typeConverter = Fir2IrTypeConverter(session, declarationStorage, irBuiltIns).also {
|
||||||
|
declarationStorage.typeConverter = it
|
||||||
private val unitType = session.builtinTypes.unitType.toIrType(session, declarationStorage)
|
it.initBuiltinTypes()
|
||||||
|
}
|
||||||
private val booleanType = session.builtinTypes.booleanType.toIrType(session, declarationStorage)
|
|
||||||
|
|
||||||
private val stringType = session.builtinTypes.stringType.toIrType(session, declarationStorage)
|
|
||||||
|
|
||||||
private fun ModuleDescriptor.findPackageFragmentForFile(file: FirFile): PackageFragmentDescriptor =
|
private fun ModuleDescriptor.findPackageFragmentForFile(file: FirFile): PackageFragmentDescriptor =
|
||||||
getPackage(file.packageFqName).fragments.first()
|
getPackage(file.packageFqName).fragments.first()
|
||||||
@@ -143,8 +140,9 @@ class Fir2IrVisitor(
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FirTypeRef.toIrType(session: FirSession, declarationStorage: Fir2IrDeclarationStorage) =
|
private fun FirTypeRef.toIrType(): IrType = with(typeConverter) { toIrType() }
|
||||||
toIrType(session, declarationStorage, irBuiltIns)
|
|
||||||
|
private fun ConeKotlinType.toIrType(): IrType = with(typeConverter) { toIrType() }
|
||||||
|
|
||||||
override fun visitElement(element: FirElement, data: Any?): IrElement {
|
override fun visitElement(element: FirElement, data: Any?): IrElement {
|
||||||
TODO("Should not be here: ${element.render()}")
|
TODO("Should not be here: ${element.render()}")
|
||||||
@@ -403,7 +401,7 @@ class Fir2IrVisitor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun FirDelegatedConstructorCall.toIrDelegatingConstructorCall(): IrCallWithIndexedArgumentsBase? {
|
private fun FirDelegatedConstructorCall.toIrDelegatingConstructorCall(): IrCallWithIndexedArgumentsBase? {
|
||||||
val constructedIrType = constructedTypeRef.toIrType(this@Fir2IrVisitor.session, declarationStorage)
|
val constructedIrType = constructedTypeRef.toIrType()
|
||||||
val constructorSymbol = (this.calleeReference as? FirResolvedNamedReference)?.resolvedSymbol as? FirConstructorSymbol
|
val constructorSymbol = (this.calleeReference as? FirResolvedNamedReference)?.resolvedSymbol as? FirConstructorSymbol
|
||||||
?: return null
|
?: return null
|
||||||
return convertWithOffsets { startOffset, endOffset ->
|
return convertWithOffsets { startOffset, endOffset ->
|
||||||
@@ -416,7 +414,7 @@ class Fir2IrVisitor(
|
|||||||
).apply {
|
).apply {
|
||||||
val typeArguments = (constructedTypeRef as? FirResolvedTypeRef)?.type?.typeArguments
|
val typeArguments = (constructedTypeRef as? FirResolvedTypeRef)?.type?.typeArguments
|
||||||
if (typeArguments?.isNotEmpty() == true) {
|
if (typeArguments?.isNotEmpty() == true) {
|
||||||
val irType = (typeArguments.first() as ConeKotlinTypeProjection).type.toIrType(session, declarationStorage, irBuiltIns)
|
val irType = (typeArguments.first() as ConeKotlinTypeProjection).type.toIrType()
|
||||||
putTypeArgument(0, irType)
|
putTypeArgument(0, irType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -451,7 +449,7 @@ class Fir2IrVisitor(
|
|||||||
setFunctionContent(irFunction.descriptor, anonymousFunction)
|
setFunctionContent(irFunction.descriptor, anonymousFunction)
|
||||||
}
|
}
|
||||||
|
|
||||||
val type = anonymousFunction.typeRef.toIrType(session, declarationStorage)
|
val type = anonymousFunction.typeRef.toIrType()
|
||||||
|
|
||||||
IrFunctionExpressionImpl(startOffset, endOffset, type, irFunction, IrStatementOrigin.LAMBDA)
|
IrFunctionExpressionImpl(startOffset, endOffset, type, irFunction, IrStatementOrigin.LAMBDA)
|
||||||
}
|
}
|
||||||
@@ -490,7 +488,7 @@ class Fir2IrVisitor(
|
|||||||
firInitializerExpression: FirExpression?,
|
firInitializerExpression: FirExpression?,
|
||||||
type: IrType? = null
|
type: IrType? = null
|
||||||
): IrField {
|
): IrField {
|
||||||
val inferredType = type ?: firInitializerExpression!!.typeRef.toIrType(session, declarationStorage)
|
val inferredType = type ?: firInitializerExpression!!.typeRef.toIrType()
|
||||||
return symbolTable.declareField(
|
return symbolTable.declareField(
|
||||||
startOffset, endOffset, origin, descriptor, inferredType
|
startOffset, endOffset, origin, descriptor, inferredType
|
||||||
) { symbol ->
|
) { symbol ->
|
||||||
@@ -519,7 +517,7 @@ class Fir2IrVisitor(
|
|||||||
val initializer = property.initializer
|
val initializer = property.initializer
|
||||||
val delegate = property.delegate
|
val delegate = property.delegate
|
||||||
val irParent = this.parent
|
val irParent = this.parent
|
||||||
val propertyType = property.returnTypeRef.toIrType(session, declarationStorage)
|
val propertyType = property.returnTypeRef.toIrType()
|
||||||
// TODO: this checks are very preliminary, FIR resolve should determine backing field presence itself
|
// TODO: this checks are very preliminary, FIR resolve should determine backing field presence itself
|
||||||
// TODO (2): backing field should be created inside declaration storage
|
// TODO (2): backing field should be created inside declaration storage
|
||||||
if (property.modality != Modality.ABSTRACT && (irParent !is IrClass || !irParent.isInterface)) {
|
if (property.modality != Modality.ABSTRACT && (irParent !is IrClass || !irParent.isInterface)) {
|
||||||
@@ -607,13 +605,13 @@ class Fir2IrVisitor(
|
|||||||
startOffset, endOffset,
|
startOffset, endOffset,
|
||||||
listOf(
|
listOf(
|
||||||
if (isSetter) {
|
if (isSetter) {
|
||||||
IrSetFieldImpl(startOffset, endOffset, fieldSymbol, unitType).apply {
|
IrSetFieldImpl(startOffset, endOffset, fieldSymbol, typeConverter.unitType).apply {
|
||||||
setReceiver(declaration)
|
setReceiver(declaration)
|
||||||
value = IrGetValueImpl(startOffset, endOffset, propertyType, valueParameters.first().symbol)
|
value = IrGetValueImpl(startOffset, endOffset, propertyType, valueParameters.first().symbol)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
IrReturnImpl(
|
IrReturnImpl(
|
||||||
startOffset, endOffset, nothingType, symbol,
|
startOffset, endOffset, typeConverter.nothingType, symbol,
|
||||||
IrGetFieldImpl(startOffset, endOffset, fieldSymbol, propertyType).setReceiver(declaration)
|
IrGetFieldImpl(startOffset, endOffset, fieldSymbol, propertyType).setReceiver(declaration)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -641,7 +639,7 @@ class Fir2IrVisitor(
|
|||||||
val result = returnExpression.result
|
val result = returnExpression.result
|
||||||
val descriptor = irTarget.descriptor
|
val descriptor = irTarget.descriptor
|
||||||
IrReturnImpl(
|
IrReturnImpl(
|
||||||
startOffset, endOffset, nothingType,
|
startOffset, endOffset, typeConverter.nothingType,
|
||||||
when (descriptor) {
|
when (descriptor) {
|
||||||
is ClassConstructorDescriptor -> symbolTable.referenceConstructor(descriptor)
|
is ClassConstructorDescriptor -> symbolTable.referenceConstructor(descriptor)
|
||||||
else -> symbolTable.referenceSimpleFunction(descriptor)
|
else -> symbolTable.referenceSimpleFunction(descriptor)
|
||||||
@@ -657,9 +655,9 @@ class Fir2IrVisitor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitVarargArgumentsExpression(varargArgumentsExpression: FirVarargArgumentsExpression, data: Any?): IrElement {
|
override fun visitVarargArgumentsExpression(varargArgumentsExpression: FirVarargArgumentsExpression, data: Any?): IrElement {
|
||||||
val irReturnType = varargArgumentsExpression.typeRef.toIrType(session, declarationStorage)
|
val irReturnType = varargArgumentsExpression.typeRef.toIrType()
|
||||||
return IrVarargImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irReturnType,
|
return IrVarargImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irReturnType,
|
||||||
varargArgumentsExpression.varargElementType.toIrType(session, declarationStorage),
|
varargArgumentsExpression.varargElementType.toIrType(),
|
||||||
varargArgumentsExpression.arguments.map { arg ->
|
varargArgumentsExpression.arguments.map { arg ->
|
||||||
arg.toIrExpression().run {
|
arg.toIrExpression().run {
|
||||||
if (arg is FirSpreadArgumentExpression) IrSpreadElementImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, this)
|
if (arg is FirSpreadArgumentExpression) IrSpreadElementImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, this)
|
||||||
@@ -687,7 +685,7 @@ class Fir2IrVisitor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun FirQualifiedAccess.toIrExpression(typeRef: FirTypeRef): IrExpression {
|
private fun FirQualifiedAccess.toIrExpression(typeRef: FirTypeRef): IrExpression {
|
||||||
val type = typeRef.toIrType(this@Fir2IrVisitor.session, declarationStorage)
|
val type = typeRef.toIrType()
|
||||||
val symbol = calleeReference.toSymbol(declarationStorage)
|
val symbol = calleeReference.toSymbol(declarationStorage)
|
||||||
return typeRef.convertWithOffsets { startOffset, endOffset ->
|
return typeRef.convertWithOffsets { startOffset, endOffset ->
|
||||||
if (calleeReference is FirSuperReference) {
|
if (calleeReference is FirSuperReference) {
|
||||||
@@ -725,7 +723,7 @@ class Fir2IrVisitor(
|
|||||||
private fun FirAnnotationCall.toIrExpression(): IrExpression {
|
private fun FirAnnotationCall.toIrExpression(): IrExpression {
|
||||||
val coneType = (annotationTypeRef as? FirResolvedTypeRef)?.type as? ConeLookupTagBasedType
|
val coneType = (annotationTypeRef as? FirResolvedTypeRef)?.type as? ConeLookupTagBasedType
|
||||||
val firSymbol = coneType?.lookupTag?.toSymbol(session) as? FirClassSymbol
|
val firSymbol = coneType?.lookupTag?.toSymbol(session) as? FirClassSymbol
|
||||||
val type = coneType?.toIrType(session, declarationStorage, irBuiltIns)
|
val type = coneType?.toIrType()
|
||||||
val symbol = type?.classifierOrNull
|
val symbol = type?.classifierOrNull
|
||||||
return convertWithOffsets { startOffset, endOffset ->
|
return convertWithOffsets { startOffset, endOffset ->
|
||||||
when (symbol) {
|
when (symbol) {
|
||||||
@@ -790,10 +788,7 @@ class Fir2IrVisitor(
|
|||||||
if (argumentsCount <= typeArgumentsCount) {
|
if (argumentsCount <= typeArgumentsCount) {
|
||||||
apply {
|
apply {
|
||||||
for ((index, argument) in access.typeArguments.withIndex()) {
|
for ((index, argument) in access.typeArguments.withIndex()) {
|
||||||
val argumentIrType = (argument as FirTypeProjectionWithVariance).typeRef.toIrType(
|
val argumentIrType = (argument as FirTypeProjectionWithVariance).typeRef.toIrType()
|
||||||
session,
|
|
||||||
declarationStorage
|
|
||||||
)
|
|
||||||
putTypeArgument(index, argumentIrType)
|
putTypeArgument(index, argumentIrType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -936,7 +931,7 @@ class Fir2IrVisitor(
|
|||||||
override fun visitExpressionWithSmartcast(expressionWithSmartcast: FirExpressionWithSmartcast, data: Any?): IrElement {
|
override fun visitExpressionWithSmartcast(expressionWithSmartcast: FirExpressionWithSmartcast, data: Any?): IrElement {
|
||||||
// Generate the expression with the original type and then cast it to the smart cast type.
|
// Generate the expression with the original type and then cast it to the smart cast type.
|
||||||
val value = expressionWithSmartcast.originalExpression.toIrExpression()
|
val value = expressionWithSmartcast.originalExpression.toIrExpression()
|
||||||
val castType = expressionWithSmartcast.typeRef.toIrType(session, declarationStorage)
|
val castType = expressionWithSmartcast.typeRef.toIrType()
|
||||||
if (value.type == castType) return value
|
if (value.type == castType) return value
|
||||||
return IrTypeOperatorCallImpl(
|
return IrTypeOperatorCallImpl(
|
||||||
value.startOffset,
|
value.startOffset,
|
||||||
@@ -950,7 +945,7 @@ class Fir2IrVisitor(
|
|||||||
|
|
||||||
override fun visitCallableReferenceAccess(callableReferenceAccess: FirCallableReferenceAccess, data: Any?): IrElement {
|
override fun visitCallableReferenceAccess(callableReferenceAccess: FirCallableReferenceAccess, data: Any?): IrElement {
|
||||||
val symbol = callableReferenceAccess.calleeReference.toSymbol(declarationStorage)
|
val symbol = callableReferenceAccess.calleeReference.toSymbol(declarationStorage)
|
||||||
val type = callableReferenceAccess.typeRef.toIrType(this@Fir2IrVisitor.session, declarationStorage)
|
val type = callableReferenceAccess.typeRef.toIrType()
|
||||||
return callableReferenceAccess.convertWithOffsets { startOffset, endOffset ->
|
return callableReferenceAccess.convertWithOffsets { startOffset, endOffset ->
|
||||||
when (symbol) {
|
when (symbol) {
|
||||||
is IrPropertySymbol -> {
|
is IrPropertySymbol -> {
|
||||||
@@ -996,7 +991,7 @@ class Fir2IrVisitor(
|
|||||||
if (symbol != null && symbol.isBound) {
|
if (symbol != null && symbol.isBound) {
|
||||||
when (symbol) {
|
when (symbol) {
|
||||||
is IrFieldSymbol -> IrSetFieldImpl(
|
is IrFieldSymbol -> IrSetFieldImpl(
|
||||||
startOffset, endOffset, symbol, unitType
|
startOffset, endOffset, symbol, typeConverter.unitType
|
||||||
).apply {
|
).apply {
|
||||||
value = variableAssignment.rValue.toIrExpression()
|
value = variableAssignment.rValue.toIrExpression()
|
||||||
}
|
}
|
||||||
@@ -1005,7 +1000,7 @@ class Fir2IrVisitor(
|
|||||||
val backingField = irProperty.backingField
|
val backingField = irProperty.backingField
|
||||||
if (backingField != null) {
|
if (backingField != null) {
|
||||||
IrSetFieldImpl(
|
IrSetFieldImpl(
|
||||||
startOffset, endOffset, backingField.symbol, unitType
|
startOffset, endOffset, backingField.symbol, typeConverter.unitType
|
||||||
).apply {
|
).apply {
|
||||||
value = variableAssignment.rValue.toIrExpression()
|
value = variableAssignment.rValue.toIrExpression()
|
||||||
}
|
}
|
||||||
@@ -1044,7 +1039,7 @@ class Fir2IrVisitor(
|
|||||||
} as T ?: constExpression.value
|
} as T ?: constExpression.value
|
||||||
IrConstImpl(
|
IrConstImpl(
|
||||||
startOffset, endOffset,
|
startOffset, endOffset,
|
||||||
constExpression.typeRef.toIrType(session, declarationStorage),
|
constExpression.typeRef.toIrType(),
|
||||||
kind, value
|
kind, value
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -1085,7 +1080,7 @@ class Fir2IrVisitor(
|
|||||||
is FirBlock -> convertToIrExpressionOrBlock()
|
is FirBlock -> convertToIrExpressionOrBlock()
|
||||||
is FirUnitExpression -> convertWithOffsets { startOffset, endOffset ->
|
is FirUnitExpression -> convertWithOffsets { startOffset, endOffset ->
|
||||||
IrGetObjectValueImpl(
|
IrGetObjectValueImpl(
|
||||||
startOffset, endOffset, unitType,
|
startOffset, endOffset, typeConverter.unitType,
|
||||||
symbolTable.referenceClass(irBuiltIns.builtIns.unit)
|
symbolTable.referenceClass(irBuiltIns.builtIns.unit)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -1123,7 +1118,7 @@ class Fir2IrVisitor(
|
|||||||
startOffset, endOffset,
|
startOffset, endOffset,
|
||||||
if (irStatements.isNotEmpty()) {
|
if (irStatements.isNotEmpty()) {
|
||||||
irStatements.filterNotNull().takeIf { it.isNotEmpty() }
|
irStatements.filterNotNull().takeIf { it.isNotEmpty() }
|
||||||
?: listOf(IrBlockImpl(startOffset, endOffset, unitType, null, emptyList()))
|
?: listOf(IrBlockImpl(startOffset, endOffset, typeConverter.unitType, null, emptyList()))
|
||||||
} else {
|
} else {
|
||||||
emptyList()
|
emptyList()
|
||||||
}
|
}
|
||||||
@@ -1139,7 +1134,7 @@ class Fir2IrVisitor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
val type =
|
val type =
|
||||||
(statements.lastOrNull() as? FirExpression)?.typeRef?.toIrType(this@Fir2IrVisitor.session, declarationStorage) ?: unitType
|
(statements.lastOrNull() as? FirExpression)?.typeRef?.toIrType() ?: typeConverter.unitType
|
||||||
return convertWithOffsets { startOffset, endOffset ->
|
return convertWithOffsets { startOffset, endOffset ->
|
||||||
IrBlockImpl(
|
IrBlockImpl(
|
||||||
startOffset, endOffset, type, origin,
|
startOffset, endOffset, type, origin,
|
||||||
@@ -1152,7 +1147,7 @@ class Fir2IrVisitor(
|
|||||||
return errorExpression.convertWithOffsets { startOffset, endOffset ->
|
return errorExpression.convertWithOffsets { startOffset, endOffset ->
|
||||||
IrErrorExpressionImpl(
|
IrErrorExpressionImpl(
|
||||||
startOffset, endOffset,
|
startOffset, endOffset,
|
||||||
errorExpression.typeRef.toIrType(session, declarationStorage),
|
errorExpression.typeRef.toIrType(),
|
||||||
errorExpression.diagnostic.reason
|
errorExpression.diagnostic.reason
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -1189,7 +1184,7 @@ class Fir2IrVisitor(
|
|||||||
whenExpression.convertWithOffsets { startOffset, endOffset ->
|
whenExpression.convertWithOffsets { startOffset, endOffset ->
|
||||||
val irWhen = IrWhenImpl(
|
val irWhen = IrWhenImpl(
|
||||||
startOffset, endOffset,
|
startOffset, endOffset,
|
||||||
whenExpression.typeRef.toIrType(session, declarationStorage),
|
whenExpression.typeRef.toIrType(),
|
||||||
origin
|
origin
|
||||||
).apply {
|
).apply {
|
||||||
for (branch in whenExpression.branches) {
|
for (branch in whenExpression.branches) {
|
||||||
@@ -1212,7 +1207,7 @@ class Fir2IrVisitor(
|
|||||||
val condition = whenBranch.condition
|
val condition = whenBranch.condition
|
||||||
val irResult = whenBranch.result.toIrExpression()
|
val irResult = whenBranch.result.toIrExpression()
|
||||||
if (condition is FirElseIfTrueCondition) {
|
if (condition is FirElseIfTrueCondition) {
|
||||||
IrElseBranchImpl(IrConstImpl.boolean(irResult.startOffset, irResult.endOffset, booleanType, true), irResult)
|
IrElseBranchImpl(IrConstImpl.boolean(irResult.startOffset, irResult.endOffset, typeConverter.booleanType, true), irResult)
|
||||||
} else {
|
} else {
|
||||||
IrBranchImpl(startOffset, endOffset, condition.toIrExpression(), irResult)
|
IrBranchImpl(startOffset, endOffset, condition.toIrExpression(), irResult)
|
||||||
}
|
}
|
||||||
@@ -1231,7 +1226,7 @@ class Fir2IrVisitor(
|
|||||||
override fun visitDoWhileLoop(doWhileLoop: FirDoWhileLoop, data: Any?): IrElement {
|
override fun visitDoWhileLoop(doWhileLoop: FirDoWhileLoop, data: Any?): IrElement {
|
||||||
return doWhileLoop.convertWithOffsets { startOffset, endOffset ->
|
return doWhileLoop.convertWithOffsets { startOffset, endOffset ->
|
||||||
IrDoWhileLoopImpl(
|
IrDoWhileLoopImpl(
|
||||||
startOffset, endOffset, unitType,
|
startOffset, endOffset, typeConverter.unitType,
|
||||||
IrStatementOrigin.DO_WHILE_LOOP
|
IrStatementOrigin.DO_WHILE_LOOP
|
||||||
).apply {
|
).apply {
|
||||||
loopMap[doWhileLoop] = this
|
loopMap[doWhileLoop] = this
|
||||||
@@ -1247,7 +1242,7 @@ class Fir2IrVisitor(
|
|||||||
return whileLoop.convertWithOffsets { startOffset, endOffset ->
|
return whileLoop.convertWithOffsets { startOffset, endOffset ->
|
||||||
val origin = if (whileLoop.psi is KtForExpression) IrStatementOrigin.FOR_LOOP_INNER_WHILE
|
val origin = if (whileLoop.psi is KtForExpression) IrStatementOrigin.FOR_LOOP_INNER_WHILE
|
||||||
else IrStatementOrigin.WHILE_LOOP
|
else IrStatementOrigin.WHILE_LOOP
|
||||||
IrWhileLoopImpl(startOffset, endOffset, unitType, origin).apply {
|
IrWhileLoopImpl(startOffset, endOffset, typeConverter.unitType, origin).apply {
|
||||||
loopMap[whileLoop] = this
|
loopMap[whileLoop] = this
|
||||||
label = whileLoop.label?.name
|
label = whileLoop.label?.name
|
||||||
condition = whileLoop.condition.toIrExpression()
|
condition = whileLoop.condition.toIrExpression()
|
||||||
@@ -1264,7 +1259,7 @@ class Fir2IrVisitor(
|
|||||||
val firLoop = target.labeledElement
|
val firLoop = target.labeledElement
|
||||||
val irLoop = loopMap[firLoop]
|
val irLoop = loopMap[firLoop]
|
||||||
if (irLoop == null) {
|
if (irLoop == null) {
|
||||||
IrErrorExpressionImpl(startOffset, endOffset, nothingType, "Unbound loop: ${render()}")
|
IrErrorExpressionImpl(startOffset, endOffset, typeConverter.nothingType, "Unbound loop: ${render()}")
|
||||||
} else {
|
} else {
|
||||||
f(startOffset, endOffset, irLoop).apply {
|
f(startOffset, endOffset, irLoop).apply {
|
||||||
label = irLoop.label.takeIf { target.labelName != null }
|
label = irLoop.label.takeIf { target.labelName != null }
|
||||||
@@ -1275,26 +1270,26 @@ class Fir2IrVisitor(
|
|||||||
|
|
||||||
override fun visitBreakExpression(breakExpression: FirBreakExpression, data: Any?): IrElement {
|
override fun visitBreakExpression(breakExpression: FirBreakExpression, data: Any?): IrElement {
|
||||||
return breakExpression.convertJumpWithOffsets { startOffset, endOffset, irLoop ->
|
return breakExpression.convertJumpWithOffsets { startOffset, endOffset, irLoop ->
|
||||||
IrBreakImpl(startOffset, endOffset, nothingType, irLoop)
|
IrBreakImpl(startOffset, endOffset, typeConverter.nothingType, irLoop)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitContinueExpression(continueExpression: FirContinueExpression, data: Any?): IrElement {
|
override fun visitContinueExpression(continueExpression: FirContinueExpression, data: Any?): IrElement {
|
||||||
return continueExpression.convertJumpWithOffsets { startOffset, endOffset, irLoop ->
|
return continueExpression.convertJumpWithOffsets { startOffset, endOffset, irLoop ->
|
||||||
IrContinueImpl(startOffset, endOffset, nothingType, irLoop)
|
IrContinueImpl(startOffset, endOffset, typeConverter.nothingType, irLoop)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitThrowExpression(throwExpression: FirThrowExpression, data: Any?): IrElement {
|
override fun visitThrowExpression(throwExpression: FirThrowExpression, data: Any?): IrElement {
|
||||||
return throwExpression.convertWithOffsets { startOffset, endOffset ->
|
return throwExpression.convertWithOffsets { startOffset, endOffset ->
|
||||||
IrThrowImpl(startOffset, endOffset, nothingType, throwExpression.exception.toIrExpression())
|
IrThrowImpl(startOffset, endOffset, typeConverter.nothingType, throwExpression.exception.toIrExpression())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitTryExpression(tryExpression: FirTryExpression, data: Any?): IrElement {
|
override fun visitTryExpression(tryExpression: FirTryExpression, data: Any?): IrElement {
|
||||||
return tryExpression.convertWithOffsets { startOffset, endOffset ->
|
return tryExpression.convertWithOffsets { startOffset, endOffset ->
|
||||||
IrTryImpl(
|
IrTryImpl(
|
||||||
startOffset, endOffset, tryExpression.typeRef.toIrType(session, declarationStorage),
|
startOffset, endOffset, tryExpression.typeRef.toIrType(),
|
||||||
tryExpression.tryBlock.convertToIrExpressionOrBlock(),
|
tryExpression.tryBlock.convertToIrExpressionOrBlock(),
|
||||||
tryExpression.catches.map { it.accept(this, data) as IrCatch },
|
tryExpression.catches.map { it.accept(this, data) as IrCatch },
|
||||||
tryExpression.finallyBlock?.convertToIrExpressionOrBlock()
|
tryExpression.finallyBlock?.convertToIrExpressionOrBlock()
|
||||||
@@ -1328,7 +1323,7 @@ class Fir2IrVisitor(
|
|||||||
return primitiveOp2(
|
return primitiveOp2(
|
||||||
startOffset, endOffset,
|
startOffset, endOffset,
|
||||||
symbol!!,
|
symbol!!,
|
||||||
booleanType,
|
typeConverter.booleanType,
|
||||||
origin,
|
origin,
|
||||||
visitFunctionCall(comparisonExpression.compareToCall, null),
|
visitFunctionCall(comparisonExpression.compareToCall, null),
|
||||||
IrConstImpl.int(startOffset, endOffset, irBuiltIns.intType, 0)
|
IrConstImpl.int(startOffset, endOffset, irBuiltIns.intType, 0)
|
||||||
@@ -1356,7 +1351,7 @@ class Fir2IrVisitor(
|
|||||||
val (symbol, origin) = getSymbolAndOriginForComparison(operation, simpleType.classifierOrFail)
|
val (symbol, origin) = getSymbolAndOriginForComparison(operation, simpleType.classifierOrFail)
|
||||||
|
|
||||||
return primitiveOp2(
|
return primitiveOp2(
|
||||||
startOffset, endOffset, symbol!!, booleanType, origin,
|
startOffset, endOffset, symbol!!, typeConverter.booleanType, origin,
|
||||||
comparisonExpression.left.toIrExpression(), comparisonExpression.right.toIrExpression()
|
comparisonExpression.left.toIrExpression(), comparisonExpression.right.toIrExpression()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -1378,11 +1373,11 @@ class Fir2IrVisitor(
|
|||||||
startOffset: Int, endOffset: Int, operation: FirOperation, arguments: List<FirExpression>
|
startOffset: Int, endOffset: Int, operation: FirOperation, arguments: List<FirExpression>
|
||||||
): IrExpression {
|
): IrExpression {
|
||||||
val (type, symbol, origin) = when (operation) {
|
val (type, symbol, origin) = when (operation) {
|
||||||
FirOperation.EQ -> Triple(booleanType, irBuiltIns.eqeqSymbol, IrStatementOrigin.EQEQ)
|
FirOperation.EQ -> Triple(typeConverter.booleanType, irBuiltIns.eqeqSymbol, IrStatementOrigin.EQEQ)
|
||||||
FirOperation.NOT_EQ -> Triple(booleanType, irBuiltIns.eqeqSymbol, IrStatementOrigin.EXCLEQ)
|
FirOperation.NOT_EQ -> Triple(typeConverter.booleanType, irBuiltIns.eqeqSymbol, IrStatementOrigin.EXCLEQ)
|
||||||
FirOperation.IDENTITY -> Triple(booleanType, irBuiltIns.eqeqeqSymbol, IrStatementOrigin.EQEQEQ)
|
FirOperation.IDENTITY -> Triple(typeConverter.booleanType, irBuiltIns.eqeqeqSymbol, IrStatementOrigin.EQEQEQ)
|
||||||
FirOperation.NOT_IDENTITY -> Triple(booleanType, irBuiltIns.eqeqeqSymbol, IrStatementOrigin.EXCLEQEQ)
|
FirOperation.NOT_IDENTITY -> Triple(typeConverter.booleanType, irBuiltIns.eqeqeqSymbol, IrStatementOrigin.EXCLEQEQ)
|
||||||
FirOperation.EXCL -> Triple(booleanType, irBuiltIns.booleanNotSymbol, IrStatementOrigin.EXCL)
|
FirOperation.EXCL -> Triple(typeConverter.booleanType, irBuiltIns.booleanNotSymbol, IrStatementOrigin.EXCL)
|
||||||
FirOperation.LT, FirOperation.GT,
|
FirOperation.LT, FirOperation.GT,
|
||||||
FirOperation.LT_EQ, FirOperation.GT_EQ,
|
FirOperation.LT_EQ, FirOperation.GT_EQ,
|
||||||
FirOperation.OTHER, FirOperation.ASSIGN, FirOperation.PLUS_ASSIGN,
|
FirOperation.OTHER, FirOperation.ASSIGN, FirOperation.PLUS_ASSIGN,
|
||||||
@@ -1400,7 +1395,7 @@ class Fir2IrVisitor(
|
|||||||
primitiveOp2(startOffset, endOffset, symbol, type, origin, arguments[0].toIrExpression(), arguments[1].toIrExpression())
|
primitiveOp2(startOffset, endOffset, symbol, type, origin, arguments[0].toIrExpression(), arguments[1].toIrExpression())
|
||||||
}
|
}
|
||||||
if (operation !in NEGATED_OPERATIONS) return result
|
if (operation !in NEGATED_OPERATIONS) return result
|
||||||
return primitiveOp1(startOffset, endOffset, irBuiltIns.booleanNotSymbol, booleanType, origin, result)
|
return primitiveOp1(startOffset, endOffset, irBuiltIns.booleanNotSymbol, typeConverter.booleanType, origin, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitOperatorCall(operatorCall: FirOperatorCall, data: Any?): IrElement {
|
override fun visitOperatorCall(operatorCall: FirOperatorCall, data: Any?): IrElement {
|
||||||
@@ -1412,7 +1407,7 @@ class Fir2IrVisitor(
|
|||||||
override fun visitStringConcatenationCall(stringConcatenationCall: FirStringConcatenationCall, data: Any?): IrElement {
|
override fun visitStringConcatenationCall(stringConcatenationCall: FirStringConcatenationCall, data: Any?): IrElement {
|
||||||
return stringConcatenationCall.convertWithOffsets { startOffset, endOffset ->
|
return stringConcatenationCall.convertWithOffsets { startOffset, endOffset ->
|
||||||
IrStringConcatenationImpl(
|
IrStringConcatenationImpl(
|
||||||
startOffset, endOffset, stringType,
|
startOffset, endOffset, typeConverter.stringType,
|
||||||
stringConcatenationCall.arguments.map { it.toIrExpression() }
|
stringConcatenationCall.arguments.map { it.toIrExpression() }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -1420,10 +1415,10 @@ class Fir2IrVisitor(
|
|||||||
|
|
||||||
override fun visitTypeOperatorCall(typeOperatorCall: FirTypeOperatorCall, data: Any?): IrElement {
|
override fun visitTypeOperatorCall(typeOperatorCall: FirTypeOperatorCall, data: Any?): IrElement {
|
||||||
return typeOperatorCall.convertWithOffsets { startOffset, endOffset ->
|
return typeOperatorCall.convertWithOffsets { startOffset, endOffset ->
|
||||||
val irTypeOperand = typeOperatorCall.conversionTypeRef.toIrType(session, declarationStorage)
|
val irTypeOperand = typeOperatorCall.conversionTypeRef.toIrType()
|
||||||
val (irType, irTypeOperator) = when (typeOperatorCall.operation) {
|
val (irType, irTypeOperator) = when (typeOperatorCall.operation) {
|
||||||
FirOperation.IS -> booleanType to IrTypeOperator.INSTANCEOF
|
FirOperation.IS -> typeConverter.booleanType to IrTypeOperator.INSTANCEOF
|
||||||
FirOperation.NOT_IS -> booleanType to IrTypeOperator.NOT_INSTANCEOF
|
FirOperation.NOT_IS -> typeConverter.booleanType to IrTypeOperator.NOT_INSTANCEOF
|
||||||
FirOperation.AS -> irTypeOperand to IrTypeOperator.CAST
|
FirOperation.AS -> irTypeOperand to IrTypeOperator.CAST
|
||||||
FirOperation.SAFE_AS -> irTypeOperand.makeNullable() to IrTypeOperator.SAFE_CAST
|
FirOperation.SAFE_AS -> irTypeOperand.makeNullable() to IrTypeOperator.SAFE_CAST
|
||||||
else -> TODO("Should not be here: ${typeOperatorCall.operation} in type operator call")
|
else -> TODO("Should not be here: ${typeOperatorCall.operation} in type operator call")
|
||||||
@@ -1440,11 +1435,11 @@ class Fir2IrVisitor(
|
|||||||
return checkNotNullCall.convertWithOffsets { startOffset, endOffset ->
|
return checkNotNullCall.convertWithOffsets { startOffset, endOffset ->
|
||||||
IrCallImpl(
|
IrCallImpl(
|
||||||
startOffset, endOffset,
|
startOffset, endOffset,
|
||||||
checkNotNullCall.typeRef.toIrType(session, declarationStorage),
|
checkNotNullCall.typeRef.toIrType(),
|
||||||
irBuiltIns.checkNotNullSymbol,
|
irBuiltIns.checkNotNullSymbol,
|
||||||
IrStatementOrigin.EXCLEXCL
|
IrStatementOrigin.EXCLEXCL
|
||||||
).apply {
|
).apply {
|
||||||
putTypeArgument(0, checkNotNullCall.argument.typeRef.toIrType(session, declarationStorage).makeNotNull())
|
putTypeArgument(0, checkNotNullCall.argument.typeRef.toIrType().makeNotNull())
|
||||||
putValueArgument(0, checkNotNullCall.argument.toIrExpression())
|
putValueArgument(0, checkNotNullCall.argument.toIrExpression())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1453,12 +1448,12 @@ class Fir2IrVisitor(
|
|||||||
override fun visitGetClassCall(getClassCall: FirGetClassCall, data: Any?): IrElement {
|
override fun visitGetClassCall(getClassCall: FirGetClassCall, data: Any?): IrElement {
|
||||||
return getClassCall.convertWithOffsets { startOffset, endOffset ->
|
return getClassCall.convertWithOffsets { startOffset, endOffset ->
|
||||||
val argument = getClassCall.argument
|
val argument = getClassCall.argument
|
||||||
val irType = getClassCall.typeRef.toIrType(session, declarationStorage)
|
val irType = getClassCall.typeRef.toIrType()
|
||||||
if (argument is FirResolvedReifiedParameterReference) {
|
if (argument is FirResolvedReifiedParameterReference) {
|
||||||
IrClassReferenceImpl(
|
IrClassReferenceImpl(
|
||||||
startOffset, endOffset, irType,
|
startOffset, endOffset, irType,
|
||||||
argument.symbol.toTypeParameterSymbol(declarationStorage),
|
argument.symbol.toTypeParameterSymbol(declarationStorage),
|
||||||
argument.typeRef.toIrType(session, declarationStorage)
|
argument.typeRef.toIrType()
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
IrGetClassImpl(
|
IrGetClassImpl(
|
||||||
@@ -1472,7 +1467,7 @@ class Fir2IrVisitor(
|
|||||||
override fun visitArraySetCall(arraySetCall: FirArraySetCall, data: Any?): IrElement {
|
override fun visitArraySetCall(arraySetCall: FirArraySetCall, data: Any?): IrElement {
|
||||||
return arraySetCall.convertWithOffsets { startOffset, endOffset ->
|
return arraySetCall.convertWithOffsets { startOffset, endOffset ->
|
||||||
IrErrorCallExpressionImpl(
|
IrErrorCallExpressionImpl(
|
||||||
startOffset, endOffset, unitType,
|
startOffset, endOffset, typeConverter.unitType,
|
||||||
"FirArraySetCall (resolve isn't supported yet)"
|
"FirArraySetCall (resolve isn't supported yet)"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -1484,7 +1479,7 @@ class Fir2IrVisitor(
|
|||||||
return resolvedQualifier.convertWithOffsets { startOffset, endOffset ->
|
return resolvedQualifier.convertWithOffsets { startOffset, endOffset ->
|
||||||
IrGetObjectValueImpl(
|
IrGetObjectValueImpl(
|
||||||
startOffset, endOffset,
|
startOffset, endOffset,
|
||||||
resolvedQualifier.typeRef.toIrType(session, declarationStorage),
|
resolvedQualifier.typeRef.toIrType(),
|
||||||
classSymbol.toIrSymbol(session, declarationStorage) as IrClassSymbol
|
classSymbol.toIrSymbol(session, declarationStorage) as IrClassSymbol
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user