diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt index ec5d19db417..16d76adf383 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt @@ -22,18 +22,10 @@ import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.types.* 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.symbols.* 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.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.psi.psiUtil.endOffset 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( session: FirSession, declarationStorage: Fir2IrDeclarationStorage, diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt index 64c2de601f5..1b5180858f8 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt @@ -46,8 +46,7 @@ import org.jetbrains.kotlin.psi.psiUtil.startOffsetSkippingComments class Fir2IrDeclarationStorage( private val session: FirSession, private val irSymbolTable: SymbolTable, - private val moduleDescriptor: FirModuleDescriptor, - private val irBuiltIns: IrBuiltIns + private val moduleDescriptor: FirModuleDescriptor ) { private val firSymbolProvider = session.firSymbolProvider @@ -75,7 +74,7 @@ class Fir2IrDeclarationStorage( private val localStorage = Fir2IrLocalStorage() - private val unitType = session.builtinTypes.unitType.toIrType(session, this) + lateinit var typeConverter: Fir2IrTypeConverter fun registerFile(firFile: FirFile, irFile: IrFile) { fileCache[firFile] = irFile @@ -102,11 +101,11 @@ class Fir2IrDeclarationStorage( irSymbolTable.leaveScope(descriptor) } - private fun FirTypeRef.toIrType( - session: FirSession, - declarationStorage: Fir2IrDeclarationStorage, - typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT - ) = toIrType(session, declarationStorage, irBuiltIns, typeContext) + private fun FirTypeRef.toIrType(typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT): IrType = + with(typeConverter) { toIrType(typeContext) } + + private fun ConeKotlinType.toIrType(typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT): IrType = + with(typeConverter) { toIrType(typeContext) } private fun getIrExternalPackageFragment(fqName: FqName): IrExternalPackageFragment { return fragmentCache.getOrPut(fqName) { @@ -172,9 +171,7 @@ class Fir2IrDeclarationStorage( if (klass is FirRegularClass) { setTypeParameters(klass) } - superTypes = klass.superTypeRefs.map { superTypeRef -> - superTypeRef.toIrType(session, this@Fir2IrDeclarationStorage) - } + superTypes = klass.superTypeRefs.map { superTypeRef -> superTypeRef.toIrType() } return this } @@ -348,7 +345,7 @@ class Fir2IrDeclarationStorage( } if (index < 0) { val parent = simpleCachedParameter.parent - if (parent !is IrSimpleFunction || parent.returnType == unitType) { + if (parent !is IrSimpleFunction || parent.returnType == typeConverter.unitType) { return simpleCachedParameter } } @@ -383,7 +380,7 @@ class Fir2IrDeclarationStorage( } else { typeParameterCache[typeParameter] = irTypeParameter } - bounds.mapTo(irTypeParameter.superTypes) { it.toIrType(session, this@Fir2IrDeclarationStorage) } + bounds.mapTo(irTypeParameter.superTypes) { it.toIrType() } irTypeParameter } } @@ -460,9 +457,7 @@ class Fir2IrDeclarationStorage( origin = if (forSetter) ConversionTypeOrigin.SETTER else ConversionTypeOrigin.DEFAULT ) if (function is FirDefaultPropertySetter) { - val type = function.valueParameters.first().returnTypeRef.toIrType( - session, this@Fir2IrDeclarationStorage, ConversionTypeContext.DEFAULT.inSetter() - ) + val type = function.valueParameters.first().returnTypeRef.toIrType(ConversionTypeContext.DEFAULT.inSetter()) declareDefaultSetterParameter(type) } else if (function != null) { valueParameters = function.valueParameters.mapIndexed { index, valueParameter -> @@ -482,7 +477,7 @@ class Fir2IrDeclarationStorage( extensionReceiverParameter = receiverTypeRef.convertWithOffsets { startOffset, endOffset -> declareThisReceiverParameter( parent, - thisType = receiverTypeRef.toIrType(session, this@Fir2IrDeclarationStorage, typeContext), + thisType = receiverTypeRef.toIrType(typeContext), thisOrigin = thisOrigin, startOffset = startOffset, endOffset = endOffset @@ -542,7 +537,7 @@ class Fir2IrDeclarationStorage( IrFunctionImpl( startOffset, endOffset, updatedOrigin, symbol, function.name, function.visibility, function.modality!!, - function.returnTypeRef.toIrType(session, this), + function.returnTypeRef.toIrType(), isInline = function.isInline, isExternal = function.isExternal, isTailrec = function.isTailRec, @@ -594,7 +589,7 @@ class Fir2IrDeclarationStorage( startOffset, endOffset, origin, symbol, if (isLambda) Name.special("") else Name.special(""), Visibilities.LOCAL, Modality.FINAL, - function.returnTypeRef.toIrType(session, this), + function.returnTypeRef.toIrType(), isInline = false, isExternal = false, isTailrec = false, // TODO: suspend lambda isSuspend = false, @@ -630,7 +625,7 @@ class Fir2IrDeclarationStorage( IrConstructorImpl( startOffset, endOffset, origin, symbol, Name.special(""), visibility, - constructor.returnTypeRef.toIrType(session, this), + constructor.returnTypeRef.toIrType(), isInline = false, isExternal = false, isPrimary = isPrimary, isExpect = false ).bindAndDeclareParameters(constructor, descriptor, irParent, isStatic = true, shouldLeaveScope = shouldLeaveScope) } @@ -661,7 +656,7 @@ class Fir2IrDeclarationStorage( propertyAccessor?.psi?.endOffset ?: endOffset, origin, descriptor ) { symbol -> - val accessorReturnType = if (isSetter) unitType else propertyType + val accessorReturnType = if (isSetter) typeConverter.unitType else propertyType IrFunctionImpl( startOffset, endOffset, origin, symbol, Name.special("<$prefix-${correspondingProperty.name}>"), @@ -671,13 +666,15 @@ class Fir2IrDeclarationStorage( isFakeOverride = origin == IrDeclarationOrigin.FAKE_OVERRIDE, isOperator = false ).apply { - setTypeParameters(property, ConversionTypeContext( - definitelyNotNull = false, - origin = if (isSetter) ConversionTypeOrigin.SETTER else ConversionTypeOrigin.DEFAULT - )) + setTypeParameters( + property, ConversionTypeContext( + definitelyNotNull = false, + origin = if (isSetter) ConversionTypeOrigin.SETTER else ConversionTypeOrigin.DEFAULT + ) + ) if (propertyAccessor == null && isSetter) { declareDefaultSetterParameter( - property.returnTypeRef.toIrType(session, this@Fir2IrDeclarationStorage, ConversionTypeContext.DEFAULT.inSetter()) + property.returnTypeRef.toIrType(ConversionTypeContext.DEFAULT.inSetter()) ) } }.bindAndDeclareParameters( @@ -707,7 +704,7 @@ class Fir2IrDeclarationStorage( startOffset, endOffset, origin, symbol, enumEntry.name ).apply { desc.bind(this) - val irType = enumEntry.returnTypeRef.toIrType(session, this@Fir2IrDeclarationStorage) + val irType = enumEntry.returnTypeRef.toIrType() if (irParent != null) { this.parent = irParent } @@ -758,7 +755,7 @@ class Fir2IrDeclarationStorage( isFakeOverride = origin == IrDeclarationOrigin.FAKE_OVERRIDE ).apply { descriptor.bind(this) - val type = property.returnTypeRef.toIrType(session, this@Fir2IrDeclarationStorage) + val type = property.returnTypeRef.toIrType() getter = createIrPropertyAccessor( property.getter, property, this, type, irParent, false, when { @@ -791,7 +788,7 @@ class Fir2IrDeclarationStorage( return fieldCache.getOrPut(field) { val descriptor = WrappedFieldDescriptor() val origin = IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB - val type = field.returnTypeRef.toIrType(session, this) + val type = field.returnTypeRef.toIrType() field.convertWithOffsets { startOffset, endOffset -> irSymbolTable.declareField( startOffset, endOffset, @@ -820,7 +817,7 @@ class Fir2IrDeclarationStorage( ): IrValueParameter { val descriptor = WrappedValueParameterDescriptor() val origin = IrDeclarationOrigin.DEFINED - val type = valueParameter.returnTypeRef.toIrType(session, this) + val type = valueParameter.returnTypeRef.toIrType() val irParameter = valueParameter.convertWithOffsets { startOffset, endOffset -> irSymbolTable.declareValueParameter( startOffset, endOffset, origin, descriptor, type @@ -829,9 +826,7 @@ class Fir2IrDeclarationStorage( startOffset, endOffset, origin, symbol, valueParameter.name, index, type, if (!valueParameter.isVararg) null - else valueParameter.returnTypeRef.coneTypeSafe()?.arrayElementType(session)?.toIrType( - session, this, irBuiltIns, typeContext - ), + else valueParameter.returnTypeRef.coneTypeSafe()?.arrayElementType(session)?.toIrType(typeContext), valueParameter.isCrossinline, valueParameter.isNoinline ).apply { descriptor.bind(this) @@ -878,7 +873,7 @@ class Fir2IrDeclarationStorage( } 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. val origin = when { givenOrigin != null -> givenOrigin diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrTypeConverter.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrTypeConverter.kt new file mode 100644 index 00000000000..b461b2c3e87 --- /dev/null +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrTypeConverter.kt @@ -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) } + } +} \ No newline at end of file diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt index c693e661d3e..7bcac9452a5 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt @@ -68,15 +68,12 @@ class Fir2IrVisitor( 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 unitType = session.builtinTypes.unitType.toIrType(session, declarationStorage) - - private val booleanType = session.builtinTypes.booleanType.toIrType(session, declarationStorage) - - private val stringType = session.builtinTypes.stringType.toIrType(session, declarationStorage) + private val typeConverter = Fir2IrTypeConverter(session, declarationStorage, irBuiltIns).also { + declarationStorage.typeConverter = it + it.initBuiltinTypes() + } private fun ModuleDescriptor.findPackageFragmentForFile(file: FirFile): PackageFragmentDescriptor = getPackage(file.packageFqName).fragments.first() @@ -143,8 +140,9 @@ class Fir2IrVisitor( return result } - private fun FirTypeRef.toIrType(session: FirSession, declarationStorage: Fir2IrDeclarationStorage) = - toIrType(session, declarationStorage, irBuiltIns) + private fun FirTypeRef.toIrType(): IrType = with(typeConverter) { toIrType() } + + private fun ConeKotlinType.toIrType(): IrType = with(typeConverter) { toIrType() } override fun visitElement(element: FirElement, data: Any?): IrElement { TODO("Should not be here: ${element.render()}") @@ -403,7 +401,7 @@ class Fir2IrVisitor( } 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 ?: return null return convertWithOffsets { startOffset, endOffset -> @@ -416,7 +414,7 @@ class Fir2IrVisitor( ).apply { val typeArguments = (constructedTypeRef as? FirResolvedTypeRef)?.type?.typeArguments 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) } } @@ -451,7 +449,7 @@ class Fir2IrVisitor( setFunctionContent(irFunction.descriptor, anonymousFunction) } - val type = anonymousFunction.typeRef.toIrType(session, declarationStorage) + val type = anonymousFunction.typeRef.toIrType() IrFunctionExpressionImpl(startOffset, endOffset, type, irFunction, IrStatementOrigin.LAMBDA) } @@ -490,7 +488,7 @@ class Fir2IrVisitor( firInitializerExpression: FirExpression?, type: IrType? = null ): IrField { - val inferredType = type ?: firInitializerExpression!!.typeRef.toIrType(session, declarationStorage) + val inferredType = type ?: firInitializerExpression!!.typeRef.toIrType() return symbolTable.declareField( startOffset, endOffset, origin, descriptor, inferredType ) { symbol -> @@ -519,7 +517,7 @@ class Fir2IrVisitor( val initializer = property.initializer val delegate = property.delegate 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 (2): backing field should be created inside declaration storage if (property.modality != Modality.ABSTRACT && (irParent !is IrClass || !irParent.isInterface)) { @@ -607,13 +605,13 @@ class Fir2IrVisitor( startOffset, endOffset, listOf( if (isSetter) { - IrSetFieldImpl(startOffset, endOffset, fieldSymbol, unitType).apply { + IrSetFieldImpl(startOffset, endOffset, fieldSymbol, typeConverter.unitType).apply { setReceiver(declaration) value = IrGetValueImpl(startOffset, endOffset, propertyType, valueParameters.first().symbol) } } else { IrReturnImpl( - startOffset, endOffset, nothingType, symbol, + startOffset, endOffset, typeConverter.nothingType, symbol, IrGetFieldImpl(startOffset, endOffset, fieldSymbol, propertyType).setReceiver(declaration) ) } @@ -641,7 +639,7 @@ class Fir2IrVisitor( val result = returnExpression.result val descriptor = irTarget.descriptor IrReturnImpl( - startOffset, endOffset, nothingType, + startOffset, endOffset, typeConverter.nothingType, when (descriptor) { is ClassConstructorDescriptor -> symbolTable.referenceConstructor(descriptor) else -> symbolTable.referenceSimpleFunction(descriptor) @@ -657,9 +655,9 @@ class Fir2IrVisitor( } 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, - varargArgumentsExpression.varargElementType.toIrType(session, declarationStorage), + varargArgumentsExpression.varargElementType.toIrType(), varargArgumentsExpression.arguments.map { arg -> arg.toIrExpression().run { if (arg is FirSpreadArgumentExpression) IrSpreadElementImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, this) @@ -687,7 +685,7 @@ class Fir2IrVisitor( } private fun FirQualifiedAccess.toIrExpression(typeRef: FirTypeRef): IrExpression { - val type = typeRef.toIrType(this@Fir2IrVisitor.session, declarationStorage) + val type = typeRef.toIrType() val symbol = calleeReference.toSymbol(declarationStorage) return typeRef.convertWithOffsets { startOffset, endOffset -> if (calleeReference is FirSuperReference) { @@ -725,7 +723,7 @@ class Fir2IrVisitor( private fun FirAnnotationCall.toIrExpression(): IrExpression { val coneType = (annotationTypeRef as? FirResolvedTypeRef)?.type as? ConeLookupTagBasedType val firSymbol = coneType?.lookupTag?.toSymbol(session) as? FirClassSymbol - val type = coneType?.toIrType(session, declarationStorage, irBuiltIns) + val type = coneType?.toIrType() val symbol = type?.classifierOrNull return convertWithOffsets { startOffset, endOffset -> when (symbol) { @@ -790,10 +788,7 @@ class Fir2IrVisitor( if (argumentsCount <= typeArgumentsCount) { apply { for ((index, argument) in access.typeArguments.withIndex()) { - val argumentIrType = (argument as FirTypeProjectionWithVariance).typeRef.toIrType( - session, - declarationStorage - ) + val argumentIrType = (argument as FirTypeProjectionWithVariance).typeRef.toIrType() putTypeArgument(index, argumentIrType) } } @@ -936,7 +931,7 @@ class Fir2IrVisitor( override fun visitExpressionWithSmartcast(expressionWithSmartcast: FirExpressionWithSmartcast, data: Any?): IrElement { // Generate the expression with the original type and then cast it to the smart cast type. val value = expressionWithSmartcast.originalExpression.toIrExpression() - val castType = expressionWithSmartcast.typeRef.toIrType(session, declarationStorage) + val castType = expressionWithSmartcast.typeRef.toIrType() if (value.type == castType) return value return IrTypeOperatorCallImpl( value.startOffset, @@ -950,7 +945,7 @@ class Fir2IrVisitor( override fun visitCallableReferenceAccess(callableReferenceAccess: FirCallableReferenceAccess, data: Any?): IrElement { 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 -> when (symbol) { is IrPropertySymbol -> { @@ -996,7 +991,7 @@ class Fir2IrVisitor( if (symbol != null && symbol.isBound) { when (symbol) { is IrFieldSymbol -> IrSetFieldImpl( - startOffset, endOffset, symbol, unitType + startOffset, endOffset, symbol, typeConverter.unitType ).apply { value = variableAssignment.rValue.toIrExpression() } @@ -1005,7 +1000,7 @@ class Fir2IrVisitor( val backingField = irProperty.backingField if (backingField != null) { IrSetFieldImpl( - startOffset, endOffset, backingField.symbol, unitType + startOffset, endOffset, backingField.symbol, typeConverter.unitType ).apply { value = variableAssignment.rValue.toIrExpression() } @@ -1044,7 +1039,7 @@ class Fir2IrVisitor( } as T ?: constExpression.value IrConstImpl( startOffset, endOffset, - constExpression.typeRef.toIrType(session, declarationStorage), + constExpression.typeRef.toIrType(), kind, value ) } @@ -1085,7 +1080,7 @@ class Fir2IrVisitor( is FirBlock -> convertToIrExpressionOrBlock() is FirUnitExpression -> convertWithOffsets { startOffset, endOffset -> IrGetObjectValueImpl( - startOffset, endOffset, unitType, + startOffset, endOffset, typeConverter.unitType, symbolTable.referenceClass(irBuiltIns.builtIns.unit) ) } @@ -1123,7 +1118,7 @@ class Fir2IrVisitor( startOffset, endOffset, if (irStatements.isNotEmpty()) { irStatements.filterNotNull().takeIf { it.isNotEmpty() } - ?: listOf(IrBlockImpl(startOffset, endOffset, unitType, null, emptyList())) + ?: listOf(IrBlockImpl(startOffset, endOffset, typeConverter.unitType, null, emptyList())) } else { emptyList() } @@ -1139,7 +1134,7 @@ class Fir2IrVisitor( } } 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 -> IrBlockImpl( startOffset, endOffset, type, origin, @@ -1152,7 +1147,7 @@ class Fir2IrVisitor( return errorExpression.convertWithOffsets { startOffset, endOffset -> IrErrorExpressionImpl( startOffset, endOffset, - errorExpression.typeRef.toIrType(session, declarationStorage), + errorExpression.typeRef.toIrType(), errorExpression.diagnostic.reason ) } @@ -1189,7 +1184,7 @@ class Fir2IrVisitor( whenExpression.convertWithOffsets { startOffset, endOffset -> val irWhen = IrWhenImpl( startOffset, endOffset, - whenExpression.typeRef.toIrType(session, declarationStorage), + whenExpression.typeRef.toIrType(), origin ).apply { for (branch in whenExpression.branches) { @@ -1212,7 +1207,7 @@ class Fir2IrVisitor( val condition = whenBranch.condition val irResult = whenBranch.result.toIrExpression() 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 { IrBranchImpl(startOffset, endOffset, condition.toIrExpression(), irResult) } @@ -1231,7 +1226,7 @@ class Fir2IrVisitor( override fun visitDoWhileLoop(doWhileLoop: FirDoWhileLoop, data: Any?): IrElement { return doWhileLoop.convertWithOffsets { startOffset, endOffset -> IrDoWhileLoopImpl( - startOffset, endOffset, unitType, + startOffset, endOffset, typeConverter.unitType, IrStatementOrigin.DO_WHILE_LOOP ).apply { loopMap[doWhileLoop] = this @@ -1247,7 +1242,7 @@ class Fir2IrVisitor( return whileLoop.convertWithOffsets { startOffset, endOffset -> val origin = if (whileLoop.psi is KtForExpression) IrStatementOrigin.FOR_LOOP_INNER_WHILE else IrStatementOrigin.WHILE_LOOP - IrWhileLoopImpl(startOffset, endOffset, unitType, origin).apply { + IrWhileLoopImpl(startOffset, endOffset, typeConverter.unitType, origin).apply { loopMap[whileLoop] = this label = whileLoop.label?.name condition = whileLoop.condition.toIrExpression() @@ -1264,7 +1259,7 @@ class Fir2IrVisitor( val firLoop = target.labeledElement val irLoop = loopMap[firLoop] if (irLoop == null) { - IrErrorExpressionImpl(startOffset, endOffset, nothingType, "Unbound loop: ${render()}") + IrErrorExpressionImpl(startOffset, endOffset, typeConverter.nothingType, "Unbound loop: ${render()}") } else { f(startOffset, endOffset, irLoop).apply { label = irLoop.label.takeIf { target.labelName != null } @@ -1275,26 +1270,26 @@ class Fir2IrVisitor( override fun visitBreakExpression(breakExpression: FirBreakExpression, data: Any?): IrElement { 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 { 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 { 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 { return tryExpression.convertWithOffsets { startOffset, endOffset -> IrTryImpl( - startOffset, endOffset, tryExpression.typeRef.toIrType(session, declarationStorage), + startOffset, endOffset, tryExpression.typeRef.toIrType(), tryExpression.tryBlock.convertToIrExpressionOrBlock(), tryExpression.catches.map { it.accept(this, data) as IrCatch }, tryExpression.finallyBlock?.convertToIrExpressionOrBlock() @@ -1328,7 +1323,7 @@ class Fir2IrVisitor( return primitiveOp2( startOffset, endOffset, symbol!!, - booleanType, + typeConverter.booleanType, origin, visitFunctionCall(comparisonExpression.compareToCall, null), IrConstImpl.int(startOffset, endOffset, irBuiltIns.intType, 0) @@ -1356,7 +1351,7 @@ class Fir2IrVisitor( val (symbol, origin) = getSymbolAndOriginForComparison(operation, simpleType.classifierOrFail) return primitiveOp2( - startOffset, endOffset, symbol!!, booleanType, origin, + startOffset, endOffset, symbol!!, typeConverter.booleanType, origin, comparisonExpression.left.toIrExpression(), comparisonExpression.right.toIrExpression() ) } @@ -1378,11 +1373,11 @@ class Fir2IrVisitor( startOffset: Int, endOffset: Int, operation: FirOperation, arguments: List ): IrExpression { val (type, symbol, origin) = when (operation) { - FirOperation.EQ -> Triple(booleanType, irBuiltIns.eqeqSymbol, IrStatementOrigin.EQEQ) - FirOperation.NOT_EQ -> Triple(booleanType, irBuiltIns.eqeqSymbol, IrStatementOrigin.EXCLEQ) - FirOperation.IDENTITY -> Triple(booleanType, irBuiltIns.eqeqeqSymbol, IrStatementOrigin.EQEQEQ) - FirOperation.NOT_IDENTITY -> Triple(booleanType, irBuiltIns.eqeqeqSymbol, IrStatementOrigin.EXCLEQEQ) - FirOperation.EXCL -> Triple(booleanType, irBuiltIns.booleanNotSymbol, IrStatementOrigin.EXCL) + FirOperation.EQ -> Triple(typeConverter.booleanType, irBuiltIns.eqeqSymbol, IrStatementOrigin.EQEQ) + FirOperation.NOT_EQ -> Triple(typeConverter.booleanType, irBuiltIns.eqeqSymbol, IrStatementOrigin.EXCLEQ) + FirOperation.IDENTITY -> Triple(typeConverter.booleanType, irBuiltIns.eqeqeqSymbol, IrStatementOrigin.EQEQEQ) + FirOperation.NOT_IDENTITY -> Triple(typeConverter.booleanType, irBuiltIns.eqeqeqSymbol, IrStatementOrigin.EXCLEQEQ) + FirOperation.EXCL -> Triple(typeConverter.booleanType, irBuiltIns.booleanNotSymbol, IrStatementOrigin.EXCL) FirOperation.LT, FirOperation.GT, FirOperation.LT_EQ, FirOperation.GT_EQ, 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()) } 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 { @@ -1412,7 +1407,7 @@ class Fir2IrVisitor( override fun visitStringConcatenationCall(stringConcatenationCall: FirStringConcatenationCall, data: Any?): IrElement { return stringConcatenationCall.convertWithOffsets { startOffset, endOffset -> IrStringConcatenationImpl( - startOffset, endOffset, stringType, + startOffset, endOffset, typeConverter.stringType, stringConcatenationCall.arguments.map { it.toIrExpression() } ) } @@ -1420,10 +1415,10 @@ class Fir2IrVisitor( override fun visitTypeOperatorCall(typeOperatorCall: FirTypeOperatorCall, data: Any?): IrElement { return typeOperatorCall.convertWithOffsets { startOffset, endOffset -> - val irTypeOperand = typeOperatorCall.conversionTypeRef.toIrType(session, declarationStorage) + val irTypeOperand = typeOperatorCall.conversionTypeRef.toIrType() val (irType, irTypeOperator) = when (typeOperatorCall.operation) { - FirOperation.IS -> booleanType to IrTypeOperator.INSTANCEOF - FirOperation.NOT_IS -> booleanType to IrTypeOperator.NOT_INSTANCEOF + FirOperation.IS -> typeConverter.booleanType to IrTypeOperator.INSTANCEOF + FirOperation.NOT_IS -> typeConverter.booleanType to IrTypeOperator.NOT_INSTANCEOF FirOperation.AS -> irTypeOperand to IrTypeOperator.CAST FirOperation.SAFE_AS -> irTypeOperand.makeNullable() to IrTypeOperator.SAFE_CAST else -> TODO("Should not be here: ${typeOperatorCall.operation} in type operator call") @@ -1440,11 +1435,11 @@ class Fir2IrVisitor( return checkNotNullCall.convertWithOffsets { startOffset, endOffset -> IrCallImpl( startOffset, endOffset, - checkNotNullCall.typeRef.toIrType(session, declarationStorage), + checkNotNullCall.typeRef.toIrType(), irBuiltIns.checkNotNullSymbol, IrStatementOrigin.EXCLEXCL ).apply { - putTypeArgument(0, checkNotNullCall.argument.typeRef.toIrType(session, declarationStorage).makeNotNull()) + putTypeArgument(0, checkNotNullCall.argument.typeRef.toIrType().makeNotNull()) putValueArgument(0, checkNotNullCall.argument.toIrExpression()) } } @@ -1453,12 +1448,12 @@ class Fir2IrVisitor( override fun visitGetClassCall(getClassCall: FirGetClassCall, data: Any?): IrElement { return getClassCall.convertWithOffsets { startOffset, endOffset -> val argument = getClassCall.argument - val irType = getClassCall.typeRef.toIrType(session, declarationStorage) + val irType = getClassCall.typeRef.toIrType() if (argument is FirResolvedReifiedParameterReference) { IrClassReferenceImpl( startOffset, endOffset, irType, argument.symbol.toTypeParameterSymbol(declarationStorage), - argument.typeRef.toIrType(session, declarationStorage) + argument.typeRef.toIrType() ) } else { IrGetClassImpl( @@ -1472,7 +1467,7 @@ class Fir2IrVisitor( override fun visitArraySetCall(arraySetCall: FirArraySetCall, data: Any?): IrElement { return arraySetCall.convertWithOffsets { startOffset, endOffset -> IrErrorCallExpressionImpl( - startOffset, endOffset, unitType, + startOffset, endOffset, typeConverter.unitType, "FirArraySetCall (resolve isn't supported yet)" ) } @@ -1484,7 +1479,7 @@ class Fir2IrVisitor( return resolvedQualifier.convertWithOffsets { startOffset, endOffset -> IrGetObjectValueImpl( startOffset, endOffset, - resolvedQualifier.typeRef.toIrType(session, declarationStorage), + resolvedQualifier.typeRef.toIrType(), classSymbol.toIrSymbol(session, declarationStorage) as IrClassSymbol ) }