[FIR2IR] Extract separate classifier storage from declaration storage
This commit is contained in:
@@ -21,7 +21,6 @@ import org.jetbrains.kotlin.fir.references.FirThisReference
|
|||||||
import org.jetbrains.kotlin.fir.references.impl.FirPropertyFromParameterResolvedNamedReference
|
import org.jetbrains.kotlin.fir.references.impl.FirPropertyFromParameterResolvedNamedReference
|
||||||
import org.jetbrains.kotlin.fir.resolve.*
|
import org.jetbrains.kotlin.fir.resolve.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.SyntheticPropertySymbol
|
import org.jetbrains.kotlin.fir.resolve.calls.SyntheticPropertySymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.AccessorSymbol
|
import org.jetbrains.kotlin.fir.symbols.AccessorSymbol
|
||||||
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.*
|
||||||
@@ -70,28 +69,32 @@ class ConversionTypeContext internal constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun FirClassifierSymbol<*>.toIrSymbol(
|
fun FirClassifierSymbol<*>.toSymbol(
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
declarationStorage: Fir2IrDeclarationStorage,
|
classifierStorage: Fir2IrClassifierStorage,
|
||||||
typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT
|
typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT
|
||||||
): IrClassifierSymbol {
|
): IrClassifierSymbol {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
is FirTypeParameterSymbol -> {
|
is FirTypeParameterSymbol -> {
|
||||||
declarationStorage.getIrTypeParameterSymbol(this, typeContext)
|
classifierStorage.getIrTypeParameterSymbol(this, typeContext)
|
||||||
}
|
}
|
||||||
is FirTypeAliasSymbol -> {
|
is FirTypeAliasSymbol -> {
|
||||||
val typeAlias = fir
|
val typeAlias = fir
|
||||||
val coneClassLikeType = (typeAlias.expandedTypeRef as FirResolvedTypeRef).type as ConeClassLikeType
|
val coneClassLikeType = (typeAlias.expandedTypeRef as FirResolvedTypeRef).type as ConeClassLikeType
|
||||||
coneClassLikeType.lookupTag.toSymbol(session)!!.toIrSymbol(session, declarationStorage)
|
coneClassLikeType.lookupTag.toSymbol(session)!!.toSymbol(session, classifierStorage)
|
||||||
}
|
}
|
||||||
is FirClassSymbol -> {
|
is FirClassSymbol -> {
|
||||||
declarationStorage.getIrClassSymbol(this)
|
classifierStorage.getIrClassSymbol(this)
|
||||||
}
|
}
|
||||||
else -> throw AssertionError("Should not be here: $this")
|
else -> throw AssertionError("Should not be here: $this")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun FirReference.toSymbol(declarationStorage: Fir2IrDeclarationStorage): IrSymbol? {
|
fun FirReference.toSymbol(
|
||||||
|
session: FirSession,
|
||||||
|
classifierStorage: Fir2IrClassifierStorage,
|
||||||
|
declarationStorage: Fir2IrDeclarationStorage
|
||||||
|
): IrSymbol? {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
is FirResolvedNamedReference -> {
|
is FirResolvedNamedReference -> {
|
||||||
when (val resolvedSymbol = resolvedSymbol) {
|
when (val resolvedSymbol = resolvedSymbol) {
|
||||||
@@ -100,15 +103,18 @@ fun FirReference.toSymbol(declarationStorage: Fir2IrDeclarationStorage): IrSymbo
|
|||||||
resolvedSymbol.overriddenSymbol?.takeIf { it.callableId == resolvedSymbol.callableId } ?: resolvedSymbol
|
resolvedSymbol.overriddenSymbol?.takeIf { it.callableId == resolvedSymbol.callableId } ?: resolvedSymbol
|
||||||
originalCallableSymbol.toSymbol(declarationStorage)
|
originalCallableSymbol.toSymbol(declarationStorage)
|
||||||
}
|
}
|
||||||
|
is FirClassifierSymbol<*> -> {
|
||||||
|
resolvedSymbol.toSymbol(session, classifierStorage)
|
||||||
|
}
|
||||||
else -> {
|
else -> {
|
||||||
resolvedSymbol.toSymbol(declarationStorage)
|
throw AssertionError("Unknown symbol: $resolvedSymbol")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is FirThisReference -> {
|
is FirThisReference -> {
|
||||||
when (val boundSymbol = boundSymbol?.toSymbol(declarationStorage)) {
|
when (val boundSymbol = boundSymbol) {
|
||||||
is IrClassSymbol -> boundSymbol.owner.thisReceiver?.symbol
|
is FirClassSymbol<*> -> classifierStorage.getIrClassSymbol(boundSymbol).owner.thisReceiver?.symbol
|
||||||
is IrFunctionSymbol -> boundSymbol.owner.extensionReceiverParameter?.symbol
|
is FirFunctionSymbol -> declarationStorage.getIrFunctionSymbol(boundSymbol).owner.extensionReceiverParameter?.symbol
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -116,10 +122,11 @@ fun FirReference.toSymbol(declarationStorage: Fir2IrDeclarationStorage): IrSymbo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun AbstractFirBasedSymbol<*>.toSymbol(declarationStorage: Fir2IrDeclarationStorage): IrSymbol? = when (this) {
|
private fun FirCallableSymbol<*>.toSymbol(declarationStorage: Fir2IrDeclarationStorage): IrSymbol? = when (this) {
|
||||||
is FirClassSymbol -> declarationStorage.getIrClassSymbol(this)
|
|
||||||
is FirFunctionSymbol<*> -> declarationStorage.getIrFunctionSymbol(this)
|
is FirFunctionSymbol<*> -> declarationStorage.getIrFunctionSymbol(this)
|
||||||
is FirPropertySymbol -> if (fir.isLocal) declarationStorage.getIrValueSymbol(this) else declarationStorage.getIrPropertyOrFieldSymbol(this)
|
is FirPropertySymbol -> {
|
||||||
|
if (fir.isLocal) declarationStorage.getIrValueSymbol(this) else declarationStorage.getIrPropertyOrFieldSymbol(this)
|
||||||
|
}
|
||||||
is FirFieldSymbol -> declarationStorage.getIrPropertyOrFieldSymbol(this)
|
is FirFieldSymbol -> declarationStorage.getIrPropertyOrFieldSymbol(this)
|
||||||
is FirBackingFieldSymbol -> declarationStorage.getIrBackingFieldSymbol(this)
|
is FirBackingFieldSymbol -> declarationStorage.getIrBackingFieldSymbol(this)
|
||||||
is FirDelegateFieldSymbol<*> -> declarationStorage.getIrBackingFieldSymbol(this)
|
is FirDelegateFieldSymbol<*> -> declarationStorage.getIrBackingFieldSymbol(this)
|
||||||
|
|||||||
@@ -0,0 +1,364 @@
|
|||||||
|
/*
|
||||||
|
* 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.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.firProvider
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.impl.IrEnumEntryImpl
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.impl.IrTypeParameterImpl
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
|
||||||
|
import org.jetbrains.kotlin.ir.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.impl.IrEnumConstructorCallImpl
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBodyImpl
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
|
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||||
|
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||||
|
import org.jetbrains.kotlin.ir.util.constructors
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
|
class Fir2IrClassifierStorage(
|
||||||
|
session: FirSession,
|
||||||
|
private val irSymbolTable: SymbolTable
|
||||||
|
) {
|
||||||
|
private val firProvider = session.firProvider
|
||||||
|
|
||||||
|
private val classCache = mutableMapOf<FirRegularClass, IrClass>()
|
||||||
|
|
||||||
|
private val typeParameterCache = mutableMapOf<FirTypeParameter, IrTypeParameter>()
|
||||||
|
|
||||||
|
private val typeParameterCacheForSetter = mutableMapOf<FirTypeParameter, IrTypeParameter>()
|
||||||
|
|
||||||
|
private val enumEntryCache = mutableMapOf<FirEnumEntry, IrEnumEntry>()
|
||||||
|
|
||||||
|
private val localStorage = Fir2IrLocalStorage()
|
||||||
|
|
||||||
|
lateinit var typeConverter: Fir2IrTypeConverter
|
||||||
|
|
||||||
|
lateinit var declarationStorage: Fir2IrDeclarationStorage
|
||||||
|
|
||||||
|
private fun FirTypeRef.toIrType(typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT): IrType =
|
||||||
|
with(typeConverter) { toIrType(typeContext) }
|
||||||
|
|
||||||
|
internal fun IrDeclaration.declareThisReceiverParameter(
|
||||||
|
parent: IrDeclarationParent,
|
||||||
|
thisType: IrType,
|
||||||
|
thisOrigin: IrDeclarationOrigin,
|
||||||
|
startOffset: Int = this.startOffset,
|
||||||
|
endOffset: Int = this.endOffset
|
||||||
|
): IrValueParameter {
|
||||||
|
val receiverDescriptor = WrappedReceiverParameterDescriptor()
|
||||||
|
return irSymbolTable.declareValueParameter(
|
||||||
|
startOffset, endOffset, thisOrigin, receiverDescriptor, thisType
|
||||||
|
) { symbol ->
|
||||||
|
IrValueParameterImpl(
|
||||||
|
startOffset, endOffset, thisOrigin, symbol,
|
||||||
|
Name.special("<this>"), -1, thisType,
|
||||||
|
varargElementType = null, isCrossinline = false, isNoinline = false
|
||||||
|
).apply {
|
||||||
|
this.parent = parent
|
||||||
|
receiverDescriptor.bind(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun IrClass.setThisReceiver() {
|
||||||
|
irSymbolTable.enterScope(descriptor)
|
||||||
|
val typeArguments = this.typeParameters.map {
|
||||||
|
IrSimpleTypeImpl(it.symbol, false, emptyList(), emptyList())
|
||||||
|
}
|
||||||
|
thisReceiver = declareThisReceiverParameter(
|
||||||
|
parent = this,
|
||||||
|
thisType = IrSimpleTypeImpl(symbol, false, typeArguments, emptyList()),
|
||||||
|
thisOrigin = IrDeclarationOrigin.INSTANCE_RECEIVER
|
||||||
|
)
|
||||||
|
irSymbolTable.leaveScope(descriptor)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun preCacheTypeParameters(owner: FirTypeParametersOwner) {
|
||||||
|
owner.typeParameters.mapIndexed { index, typeParameter ->
|
||||||
|
getIrTypeParameter(typeParameter, index)
|
||||||
|
if (owner is FirProperty && owner.isVar) {
|
||||||
|
getIrTypeParameter(typeParameter, index, ConversionTypeContext.DEFAULT.inSetter())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun IrTypeParametersContainer.setTypeParameters(
|
||||||
|
owner: FirTypeParametersOwner,
|
||||||
|
typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT
|
||||||
|
) {
|
||||||
|
typeParameters = owner.typeParameters.mapIndexed { index, typeParameter ->
|
||||||
|
getIrTypeParameter(typeParameter, index, typeContext).apply { parent = this@setTypeParameters }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun IrClass.declareSupertypesAndTypeParameters(klass: FirClass<*>): IrClass {
|
||||||
|
if (klass is FirRegularClass) {
|
||||||
|
setTypeParameters(klass)
|
||||||
|
}
|
||||||
|
superTypes = klass.superTypeRefs.map { superTypeRef -> superTypeRef.toIrType() }
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getCachedIrClass(klass: FirClass<*>): IrClass? {
|
||||||
|
return if (klass is FirAnonymousObject || klass is FirRegularClass && klass.visibility == Visibilities.LOCAL) {
|
||||||
|
localStorage.getLocalClass(klass)
|
||||||
|
} else {
|
||||||
|
classCache[klass]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun FirRegularClass.enumClassModality(): Modality {
|
||||||
|
return when {
|
||||||
|
declarations.any { it is FirCallableMemberDeclaration<*> && it.modality == Modality.ABSTRACT } -> {
|
||||||
|
Modality.ABSTRACT
|
||||||
|
}
|
||||||
|
declarations.any { it is FirEnumEntry && it.initializer != null } -> {
|
||||||
|
Modality.OPEN
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
Modality.FINAL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun createIrClass(klass: FirClass<*>, parent: IrDeclarationParent? = null): IrClass {
|
||||||
|
// NB: klass can be either FirRegularClass or FirAnonymousObject
|
||||||
|
if (klass is FirAnonymousObject) {
|
||||||
|
return createIrAnonymousObject(klass, irParent = parent)
|
||||||
|
}
|
||||||
|
val regularClass = klass as FirRegularClass
|
||||||
|
val origin =
|
||||||
|
if (firProvider.getFirClassifierContainerFileIfAny(klass.symbol) != null) IrDeclarationOrigin.DEFINED
|
||||||
|
else IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB
|
||||||
|
val irClass = registerIrClass(regularClass, parent, origin)
|
||||||
|
processClassHeader(regularClass, irClass)
|
||||||
|
return irClass
|
||||||
|
}
|
||||||
|
|
||||||
|
fun processClassHeader(regularClass: FirRegularClass, irClass: IrClass = getCachedIrClass(regularClass)!!): IrClass {
|
||||||
|
irClass.declareSupertypesAndTypeParameters(regularClass)
|
||||||
|
irClass.setThisReceiver()
|
||||||
|
return irClass
|
||||||
|
}
|
||||||
|
|
||||||
|
fun registerIrClass(
|
||||||
|
regularClass: FirRegularClass,
|
||||||
|
parent: IrDeclarationParent? = null,
|
||||||
|
origin: IrDeclarationOrigin = IrDeclarationOrigin.DEFINED
|
||||||
|
): IrClass {
|
||||||
|
val descriptor = WrappedClassDescriptor()
|
||||||
|
val visibility = regularClass.visibility
|
||||||
|
val modality = if (regularClass.classKind == ClassKind.ENUM_CLASS) {
|
||||||
|
regularClass.enumClassModality()
|
||||||
|
} else {
|
||||||
|
regularClass.modality ?: Modality.FINAL
|
||||||
|
}
|
||||||
|
val irClass = regularClass.convertWithOffsets { startOffset, endOffset ->
|
||||||
|
irSymbolTable.declareClass(startOffset, endOffset, origin, descriptor, modality, visibility) { symbol ->
|
||||||
|
IrClassImpl(
|
||||||
|
startOffset,
|
||||||
|
endOffset,
|
||||||
|
origin,
|
||||||
|
symbol,
|
||||||
|
regularClass.name,
|
||||||
|
regularClass.classKind,
|
||||||
|
visibility,
|
||||||
|
modality,
|
||||||
|
isCompanion = regularClass.isCompanion,
|
||||||
|
isInner = regularClass.isInner,
|
||||||
|
isData = regularClass.isData,
|
||||||
|
isExternal = regularClass.isExternal,
|
||||||
|
isInline = regularClass.isInline,
|
||||||
|
isExpect = regularClass.isExpect,
|
||||||
|
isFun = false // TODO FirRegularClass.isFun
|
||||||
|
).apply {
|
||||||
|
descriptor.bind(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (parent != null) {
|
||||||
|
irClass.parent = parent
|
||||||
|
}
|
||||||
|
if (regularClass.visibility == Visibilities.LOCAL) {
|
||||||
|
localStorage.putLocalClass(regularClass, irClass)
|
||||||
|
} else {
|
||||||
|
classCache[regularClass] = irClass
|
||||||
|
}
|
||||||
|
return irClass
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createIrAnonymousObject(
|
||||||
|
anonymousObject: FirAnonymousObject,
|
||||||
|
visibility: Visibility = Visibilities.LOCAL,
|
||||||
|
name: Name = Name.special("<no name provided>"),
|
||||||
|
irParent: IrDeclarationParent? = null
|
||||||
|
): IrClass {
|
||||||
|
val descriptor = WrappedClassDescriptor()
|
||||||
|
val origin = IrDeclarationOrigin.DEFINED
|
||||||
|
val modality = Modality.FINAL
|
||||||
|
val result = anonymousObject.convertWithOffsets { startOffset, endOffset ->
|
||||||
|
irSymbolTable.declareClass(startOffset, endOffset, origin, descriptor, modality, visibility) { symbol ->
|
||||||
|
IrClassImpl(
|
||||||
|
startOffset, endOffset, origin, symbol, name,
|
||||||
|
// NB: for unknown reason, IR uses 'CLASS' kind for simple anonymous objects
|
||||||
|
anonymousObject.classKind.takeIf { it == ClassKind.ENUM_ENTRY } ?: ClassKind.CLASS,
|
||||||
|
visibility, modality,
|
||||||
|
isCompanion = false, isInner = false, isData = false,
|
||||||
|
isExternal = false, isInline = false, isExpect = false, isFun = false
|
||||||
|
).apply {
|
||||||
|
descriptor.bind(this)
|
||||||
|
setThisReceiver()
|
||||||
|
if (irParent != null) {
|
||||||
|
this.parent = irParent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.declareSupertypesAndTypeParameters(anonymousObject)
|
||||||
|
localStorage.putLocalClass(anonymousObject, result)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getIrAnonymousObjectForEnumEntry(anonymousObject: FirAnonymousObject, name: Name, irParent: IrClass?): IrClass {
|
||||||
|
localStorage.getLocalClass(anonymousObject)?.let { return it }
|
||||||
|
return createIrAnonymousObject(anonymousObject, Visibilities.PRIVATE, name, irParent)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getIrTypeParameter(
|
||||||
|
typeParameter: FirTypeParameter,
|
||||||
|
index: Int = -1,
|
||||||
|
typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT
|
||||||
|
): IrTypeParameter {
|
||||||
|
// Here transformation is a bit difficult because one FIR property type parameter
|
||||||
|
// can be transformed to two different type parameters: one for getter and another one for setter
|
||||||
|
val simpleCachedParameter = typeParameterCache[typeParameter]
|
||||||
|
if (simpleCachedParameter != null) {
|
||||||
|
if (typeContext.origin != ConversionTypeOrigin.SETTER) {
|
||||||
|
return simpleCachedParameter
|
||||||
|
}
|
||||||
|
if (index < 0) {
|
||||||
|
val parent = simpleCachedParameter.parent
|
||||||
|
if (parent !is IrSimpleFunction || parent.returnType == typeConverter.unitType) {
|
||||||
|
return simpleCachedParameter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (typeContext.origin == ConversionTypeOrigin.SETTER) {
|
||||||
|
typeParameterCacheForSetter[typeParameter]?.let { return it }
|
||||||
|
}
|
||||||
|
return typeParameter.run {
|
||||||
|
// Yet I don't want to enable this requirement because it breaks some tests
|
||||||
|
// However, if we get here it *should* mean that type parameter index is given explicitly
|
||||||
|
// At this moment (20.02.2020) this requirement breaks 11/355 Fir2IrText tests
|
||||||
|
// require(index != -1)
|
||||||
|
val descriptor = WrappedTypeParameterDescriptor()
|
||||||
|
val origin = IrDeclarationOrigin.DEFINED
|
||||||
|
val irTypeParameter =
|
||||||
|
convertWithOffsets { startOffset, endOffset ->
|
||||||
|
irSymbolTable.declareGlobalTypeParameter(startOffset, endOffset, origin, descriptor) { symbol ->
|
||||||
|
IrTypeParameterImpl(
|
||||||
|
startOffset, endOffset, origin, symbol,
|
||||||
|
name, if (index < 0) 0 else index,
|
||||||
|
isReified,
|
||||||
|
variance
|
||||||
|
).apply {
|
||||||
|
descriptor.bind(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cache the type parameter BEFORE processing its bounds/supertypes, to properly handle recursive type bounds.
|
||||||
|
if (typeContext.origin == ConversionTypeOrigin.SETTER) {
|
||||||
|
typeParameterCacheForSetter[typeParameter] = irTypeParameter
|
||||||
|
} else {
|
||||||
|
typeParameterCache[typeParameter] = irTypeParameter
|
||||||
|
}
|
||||||
|
bounds.mapTo(irTypeParameter.superTypes) { it.toIrType() }
|
||||||
|
irTypeParameter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun putEnumEntryClassInScope(enumEntry: FirEnumEntry, correspondingClass: IrClass) {
|
||||||
|
localStorage.putLocalClass(enumEntry.initializer as FirAnonymousObject, correspondingClass)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getCachedIrEnumEntry(enumEntry: FirEnumEntry): IrEnumEntry? = enumEntryCache[enumEntry]
|
||||||
|
|
||||||
|
fun createIrEnumEntry(
|
||||||
|
enumEntry: FirEnumEntry,
|
||||||
|
irParent: IrClass?,
|
||||||
|
origin: IrDeclarationOrigin = IrDeclarationOrigin.DEFINED
|
||||||
|
): IrEnumEntry {
|
||||||
|
return enumEntry.convertWithOffsets { startOffset, endOffset ->
|
||||||
|
val desc = WrappedEnumEntryDescriptor()
|
||||||
|
declarationStorage.enterScope(desc)
|
||||||
|
val result = irSymbolTable.declareEnumEntry(startOffset, endOffset, origin, desc) { symbol ->
|
||||||
|
IrEnumEntryImpl(
|
||||||
|
startOffset, endOffset, origin, symbol, enumEntry.name
|
||||||
|
).apply {
|
||||||
|
desc.bind(this)
|
||||||
|
val irType = enumEntry.returnTypeRef.toIrType()
|
||||||
|
if (irParent != null) {
|
||||||
|
this.parent = irParent
|
||||||
|
}
|
||||||
|
val initializer = enumEntry.initializer
|
||||||
|
if (initializer != null) {
|
||||||
|
initializer as FirAnonymousObject
|
||||||
|
val klass = getIrAnonymousObjectForEnumEntry(initializer, enumEntry.name, irParent)
|
||||||
|
|
||||||
|
this.correspondingClass = klass
|
||||||
|
} else if (irParent != null) {
|
||||||
|
this.initializerExpression = IrExpressionBodyImpl(
|
||||||
|
IrEnumConstructorCallImpl(startOffset, endOffset, irType, irParent.constructors.first().symbol)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
declarationStorage.leaveScope(desc)
|
||||||
|
enumEntryCache[enumEntry] = result
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getIrClassSymbol(firClassSymbol: FirClassSymbol<*>): IrClassSymbol {
|
||||||
|
val firClass = firClassSymbol.fir
|
||||||
|
getCachedIrClass(firClass)?.let { return irSymbolTable.referenceClass(it.descriptor) }
|
||||||
|
// TODO: remove all this code and change to unbound symbol creation
|
||||||
|
val irClass = createIrClass(firClass)
|
||||||
|
if (firClass is FirAnonymousObject || firClass is FirRegularClass && firClass.visibility == Visibilities.LOCAL) {
|
||||||
|
return irSymbolTable.referenceClass(irClass.descriptor)
|
||||||
|
}
|
||||||
|
val classId = firClassSymbol.classId
|
||||||
|
val parentId = classId.outerClassId
|
||||||
|
val irParent = declarationStorage.findIrParent(classId.packageFqName, parentId, firClassSymbol)
|
||||||
|
if (irParent != null) {
|
||||||
|
irClass.parent = irParent
|
||||||
|
}
|
||||||
|
if (irParent is IrExternalPackageFragment) {
|
||||||
|
declarationStorage.addDeclarationsToExternalClass(firClass as FirRegularClass, irClass)
|
||||||
|
}
|
||||||
|
|
||||||
|
return irSymbolTable.referenceClass(irClass.descriptor)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getIrTypeParameterSymbol(
|
||||||
|
firTypeParameterSymbol: FirTypeParameterSymbol,
|
||||||
|
typeContext: ConversionTypeContext
|
||||||
|
): IrTypeParameterSymbol {
|
||||||
|
// TODO: use cached type parameter here
|
||||||
|
val irTypeParameter = getIrTypeParameter(firTypeParameterSymbol.fir, typeContext = typeContext)
|
||||||
|
return irSymbolTable.referenceTypeParameter(irTypeParameter.descriptor)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.psi2ir.PsiSourceManager
|
|||||||
class Fir2IrConverter(
|
class Fir2IrConverter(
|
||||||
private val moduleDescriptor: FirModuleDescriptor,
|
private val moduleDescriptor: FirModuleDescriptor,
|
||||||
private val sourceManager: PsiSourceManager,
|
private val sourceManager: PsiSourceManager,
|
||||||
|
private val classifierStorage: Fir2IrClassifierStorage,
|
||||||
private val declarationStorage: Fir2IrDeclarationStorage
|
private val declarationStorage: Fir2IrDeclarationStorage
|
||||||
) {
|
) {
|
||||||
|
|
||||||
@@ -71,7 +72,7 @@ class Fir2IrConverter(
|
|||||||
|
|
||||||
fun processAnonymousObjectMembers(
|
fun processAnonymousObjectMembers(
|
||||||
anonymousObject: FirAnonymousObject,
|
anonymousObject: FirAnonymousObject,
|
||||||
irClass: IrClass = declarationStorage.getCachedIrClass(anonymousObject)!!
|
irClass: IrClass = classifierStorage.getCachedIrClass(anonymousObject)!!
|
||||||
): IrClass {
|
): IrClass {
|
||||||
anonymousObject.getPrimaryConstructorIfAny()?.let {
|
anonymousObject.getPrimaryConstructorIfAny()?.let {
|
||||||
irClass.declarations += declarationStorage.createIrConstructor(it, irClass)
|
irClass.declarations += declarationStorage.createIrConstructor(it, irClass)
|
||||||
@@ -89,7 +90,7 @@ class Fir2IrConverter(
|
|||||||
|
|
||||||
private fun processClassMembers(
|
private fun processClassMembers(
|
||||||
regularClass: FirRegularClass,
|
regularClass: FirRegularClass,
|
||||||
irClass: IrClass = declarationStorage.getCachedIrClass(regularClass)!!
|
irClass: IrClass = classifierStorage.getCachedIrClass(regularClass)!!
|
||||||
): IrClass {
|
): IrClass {
|
||||||
regularClass.getPrimaryConstructorIfAny()?.let {
|
regularClass.getPrimaryConstructorIfAny()?.let {
|
||||||
irClass.declarations += declarationStorage.createIrConstructor(it, irClass)
|
irClass.declarations += declarationStorage.createIrConstructor(it, irClass)
|
||||||
@@ -102,7 +103,7 @@ class Fir2IrConverter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun registerClassAndNestedClasses(regularClass: FirRegularClass, parent: IrDeclarationParent): IrClass {
|
private fun registerClassAndNestedClasses(regularClass: FirRegularClass, parent: IrDeclarationParent): IrClass {
|
||||||
val irClass = declarationStorage.registerIrClass(regularClass, parent)
|
val irClass = classifierStorage.registerIrClass(regularClass, parent)
|
||||||
regularClass.declarations.forEach {
|
regularClass.declarations.forEach {
|
||||||
if (it is FirRegularClass) {
|
if (it is FirRegularClass) {
|
||||||
registerClassAndNestedClasses(it, irClass)
|
registerClassAndNestedClasses(it, irClass)
|
||||||
@@ -112,7 +113,7 @@ class Fir2IrConverter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun processClassAndNestedClassHeaders(regularClass: FirRegularClass) {
|
private fun processClassAndNestedClassHeaders(regularClass: FirRegularClass) {
|
||||||
declarationStorage.processClassHeader(regularClass)
|
classifierStorage.processClassHeader(regularClass)
|
||||||
regularClass.declarations.forEach {
|
regularClass.declarations.forEach {
|
||||||
if (it is FirRegularClass) {
|
if (it is FirRegularClass) {
|
||||||
processClassAndNestedClassHeaders(it)
|
processClassAndNestedClassHeaders(it)
|
||||||
@@ -137,7 +138,7 @@ class Fir2IrConverter(
|
|||||||
null
|
null
|
||||||
}
|
}
|
||||||
is FirEnumEntry -> {
|
is FirEnumEntry -> {
|
||||||
declarationStorage.createIrEnumEntry(declaration, parent as IrClass)
|
classifierStorage.createIrEnumEntry(declaration, parent as IrClass)
|
||||||
}
|
}
|
||||||
is FirAnonymousInitializer -> {
|
is FirAnonymousInitializer -> {
|
||||||
declarationStorage.createIrAnonymousInitializer(declaration, parent as IrClass)
|
declarationStorage.createIrAnonymousInitializer(declaration, parent as IrClass)
|
||||||
@@ -169,12 +170,16 @@ class Fir2IrConverter(
|
|||||||
val builtIns = IrBuiltIns(moduleDescriptor.builtIns, typeTranslator, signaturer, symbolTable)
|
val builtIns = IrBuiltIns(moduleDescriptor.builtIns, typeTranslator, signaturer, symbolTable)
|
||||||
val sourceManager = PsiSourceManager()
|
val sourceManager = PsiSourceManager()
|
||||||
val declarationStorage = Fir2IrDeclarationStorage(session, symbolTable, moduleDescriptor)
|
val declarationStorage = Fir2IrDeclarationStorage(session, symbolTable, moduleDescriptor)
|
||||||
val typeConverter = Fir2IrTypeConverter(session, declarationStorage, builtIns)
|
val classifierStorage = Fir2IrClassifierStorage(session, symbolTable)
|
||||||
|
val typeConverter = Fir2IrTypeConverter(session, classifierStorage, builtIns)
|
||||||
declarationStorage.typeConverter = typeConverter
|
declarationStorage.typeConverter = typeConverter
|
||||||
|
classifierStorage.typeConverter = typeConverter
|
||||||
|
declarationStorage.classifierStorage = classifierStorage
|
||||||
|
classifierStorage.declarationStorage = declarationStorage
|
||||||
typeConverter.initBuiltinTypes()
|
typeConverter.initBuiltinTypes()
|
||||||
val irFiles = mutableListOf<IrFile>()
|
val irFiles = mutableListOf<IrFile>()
|
||||||
|
|
||||||
val converter = Fir2IrConverter(moduleDescriptor, sourceManager, declarationStorage)
|
val converter = Fir2IrConverter(moduleDescriptor, sourceManager, classifierStorage, declarationStorage)
|
||||||
for (firFile in firFiles) {
|
for (firFile in firFiles) {
|
||||||
converter.registerFileAndClasses(firFile)
|
converter.registerFileAndClasses(firFile)
|
||||||
}
|
}
|
||||||
@@ -186,7 +191,7 @@ class Fir2IrConverter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val fir2irVisitor = Fir2IrVisitor(
|
val fir2irVisitor = Fir2IrVisitor(
|
||||||
session, symbolTable, declarationStorage, converter, typeConverter, builtIns, fakeOverrideMode
|
session, symbolTable, classifierStorage, declarationStorage, converter, typeConverter, builtIns, fakeOverrideMode
|
||||||
)
|
)
|
||||||
for (firFile in firFiles) {
|
for (firFile in firFiles) {
|
||||||
val irFile = firFile.accept(fir2irVisitor, null) as IrFile
|
val irFile = firFile.accept(fir2irVisitor, null) as IrFile
|
||||||
|
|||||||
+40
-352
@@ -5,7 +5,9 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.backend
|
package org.jetbrains.kotlin.fir.backend
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter
|
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter
|
||||||
@@ -28,14 +30,11 @@ import org.jetbrains.kotlin.ir.declarations.*
|
|||||||
import org.jetbrains.kotlin.ir.declarations.impl.*
|
import org.jetbrains.kotlin.ir.declarations.impl.*
|
||||||
import org.jetbrains.kotlin.ir.descriptors.*
|
import org.jetbrains.kotlin.ir.descriptors.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrEnumConstructorCallImpl
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrErrorExpressionImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrErrorExpressionImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBodyImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBodyImpl
|
||||||
import org.jetbrains.kotlin.ir.symbols.*
|
import org.jetbrains.kotlin.ir.symbols.*
|
||||||
import org.jetbrains.kotlin.ir.types.IrType
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
|
||||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||||
import org.jetbrains.kotlin.ir.util.constructors
|
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -56,12 +55,6 @@ class Fir2IrDeclarationStorage(
|
|||||||
|
|
||||||
private val fileCache = mutableMapOf<FirFile, IrFile>()
|
private val fileCache = mutableMapOf<FirFile, IrFile>()
|
||||||
|
|
||||||
private val classCache = mutableMapOf<FirRegularClass, IrClass>()
|
|
||||||
|
|
||||||
private val typeParameterCache = mutableMapOf<FirTypeParameter, IrTypeParameter>()
|
|
||||||
|
|
||||||
private val typeParameterCacheForSetter = mutableMapOf<FirTypeParameter, IrTypeParameter>()
|
|
||||||
|
|
||||||
private val functionCache = mutableMapOf<FirFunction<*>, IrSimpleFunction>()
|
private val functionCache = mutableMapOf<FirFunction<*>, IrSimpleFunction>()
|
||||||
|
|
||||||
private val constructorCache = mutableMapOf<FirConstructor, IrConstructor>()
|
private val constructorCache = mutableMapOf<FirConstructor, IrConstructor>()
|
||||||
@@ -72,12 +65,12 @@ class Fir2IrDeclarationStorage(
|
|||||||
|
|
||||||
private val fieldCache = mutableMapOf<FirField, IrField>()
|
private val fieldCache = mutableMapOf<FirField, IrField>()
|
||||||
|
|
||||||
private val enumEntryCache = mutableMapOf<FirEnumEntry, IrEnumEntry>()
|
|
||||||
|
|
||||||
private val localStorage = Fir2IrLocalStorage()
|
private val localStorage = Fir2IrLocalStorage()
|
||||||
|
|
||||||
lateinit var typeConverter: Fir2IrTypeConverter
|
lateinit var typeConverter: Fir2IrTypeConverter
|
||||||
|
|
||||||
|
lateinit var classifierStorage: Fir2IrClassifierStorage
|
||||||
|
|
||||||
fun registerFile(firFile: FirFile, irFile: IrFile) {
|
fun registerFile(firFile: FirFile, irFile: IrFile) {
|
||||||
fileCache[firFile] = irFile
|
fileCache[firFile] = irFile
|
||||||
}
|
}
|
||||||
@@ -121,68 +114,7 @@ class Fir2IrDeclarationStorage(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun IrDeclaration.declareThisReceiverParameter(
|
internal fun addDeclarationsToExternalClass(regularClass: FirRegularClass, irClass: IrClass) {
|
||||||
parent: IrDeclarationParent,
|
|
||||||
thisType: IrType,
|
|
||||||
thisOrigin: IrDeclarationOrigin,
|
|
||||||
startOffset: Int = this.startOffset,
|
|
||||||
endOffset: Int = this.endOffset
|
|
||||||
): IrValueParameter {
|
|
||||||
val receiverDescriptor = WrappedReceiverParameterDescriptor()
|
|
||||||
return irSymbolTable.declareValueParameter(
|
|
||||||
startOffset, endOffset, thisOrigin, receiverDescriptor, thisType
|
|
||||||
) { symbol ->
|
|
||||||
IrValueParameterImpl(
|
|
||||||
startOffset, endOffset, thisOrigin, symbol,
|
|
||||||
Name.special("<this>"), -1, thisType,
|
|
||||||
varargElementType = null, isCrossinline = false, isNoinline = false
|
|
||||||
).apply {
|
|
||||||
this.parent = parent
|
|
||||||
receiverDescriptor.bind(this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun IrClass.setThisReceiver() {
|
|
||||||
enterScope(descriptor)
|
|
||||||
val typeArguments = this.typeParameters.map {
|
|
||||||
IrSimpleTypeImpl(it.symbol, false, emptyList(), emptyList())
|
|
||||||
}
|
|
||||||
thisReceiver = declareThisReceiverParameter(
|
|
||||||
parent = this,
|
|
||||||
thisType = IrSimpleTypeImpl(symbol, false, typeArguments, emptyList()),
|
|
||||||
thisOrigin = IrDeclarationOrigin.INSTANCE_RECEIVER
|
|
||||||
)
|
|
||||||
leaveScope(descriptor)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun preCacheTypeParameters(owner: FirTypeParametersOwner) {
|
|
||||||
owner.typeParameters.mapIndexed { index, typeParameter ->
|
|
||||||
getIrTypeParameter(typeParameter, index)
|
|
||||||
if (owner is FirProperty && owner.isVar) {
|
|
||||||
getIrTypeParameter(typeParameter, index, ConversionTypeContext.DEFAULT.inSetter())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun IrTypeParametersContainer.setTypeParameters(
|
|
||||||
owner: FirTypeParametersOwner,
|
|
||||||
typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT
|
|
||||||
) {
|
|
||||||
typeParameters = owner.typeParameters.mapIndexed { index, typeParameter ->
|
|
||||||
getIrTypeParameter(typeParameter, index, typeContext).apply { parent = this@setTypeParameters }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun IrClass.declareSupertypesAndTypeParameters(klass: FirClass<*>): IrClass {
|
|
||||||
if (klass is FirRegularClass) {
|
|
||||||
setTypeParameters(klass)
|
|
||||||
}
|
|
||||||
superTypes = klass.superTypeRefs.map { superTypeRef -> superTypeRef.toIrType() }
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun addDeclarationsToExternalClass(regularClass: FirRegularClass, irClass: IrClass) {
|
|
||||||
if (regularClass.symbol.classId.packageFqName.startsWith(Name.identifier("kotlin"))) {
|
if (regularClass.symbol.classId.packageFqName.startsWith(Name.identifier("kotlin"))) {
|
||||||
// Note: yet this is necessary only for *Range / *Progression classes
|
// Note: yet this is necessary only for *Range / *Progression classes
|
||||||
// due to BE optimizations (for lowering) that use their first / last / step members
|
// due to BE optimizations (for lowering) that use their first / last / step members
|
||||||
@@ -202,7 +134,7 @@ class Fir2IrDeclarationStorage(
|
|||||||
createIrConstructor(declaration, irClass)
|
createIrConstructor(declaration, irClass)
|
||||||
}
|
}
|
||||||
is FirRegularClass -> {
|
is FirRegularClass -> {
|
||||||
createIrClass(declaration, irClass)
|
classifierStorage.createIrClass(declaration, irClass)
|
||||||
}
|
}
|
||||||
else -> continue
|
else -> continue
|
||||||
}
|
}
|
||||||
@@ -235,190 +167,12 @@ class Fir2IrDeclarationStorage(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getCachedIrClass(klass: FirClass<*>): IrClass? {
|
internal fun findIrParent(packageFqName: FqName, parentClassId: ClassId?, firBasedSymbol: FirBasedSymbol<*>): IrDeclarationParent? {
|
||||||
return if (klass is FirAnonymousObject || klass is FirRegularClass && klass.visibility == Visibilities.LOCAL) {
|
|
||||||
localStorage.getLocalClass(klass)
|
|
||||||
} else {
|
|
||||||
classCache[klass]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun FirRegularClass.enumClassModality(): Modality {
|
|
||||||
return when {
|
|
||||||
declarations.any { it is FirCallableMemberDeclaration<*> && it.modality == Modality.ABSTRACT } -> {
|
|
||||||
Modality.ABSTRACT
|
|
||||||
}
|
|
||||||
declarations.any { it is FirEnumEntry && it.initializer != null } -> {
|
|
||||||
Modality.OPEN
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
Modality.FINAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createIrClass(klass: FirClass<*>, parent: IrDeclarationParent? = null): IrClass {
|
|
||||||
// NB: klass can be either FirRegularClass or FirAnonymousObject
|
|
||||||
if (klass is FirAnonymousObject) {
|
|
||||||
return createIrAnonymousObject(klass, irParent = parent)
|
|
||||||
}
|
|
||||||
val regularClass = klass as FirRegularClass
|
|
||||||
val origin =
|
|
||||||
if (firProvider.getFirClassifierContainerFileIfAny(klass.symbol) != null) IrDeclarationOrigin.DEFINED
|
|
||||||
else IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB
|
|
||||||
val irClass = registerIrClass(regularClass, parent, origin)
|
|
||||||
processClassHeader(regularClass, irClass)
|
|
||||||
return irClass
|
|
||||||
}
|
|
||||||
|
|
||||||
fun processClassHeader(regularClass: FirRegularClass, irClass: IrClass = getCachedIrClass(regularClass)!!): IrClass {
|
|
||||||
irClass.declareSupertypesAndTypeParameters(regularClass)
|
|
||||||
irClass.setThisReceiver()
|
|
||||||
return irClass
|
|
||||||
}
|
|
||||||
|
|
||||||
fun registerIrClass(
|
|
||||||
regularClass: FirRegularClass,
|
|
||||||
parent: IrDeclarationParent? = null,
|
|
||||||
origin: IrDeclarationOrigin = IrDeclarationOrigin.DEFINED
|
|
||||||
): IrClass {
|
|
||||||
val descriptor = WrappedClassDescriptor()
|
|
||||||
val visibility = regularClass.visibility
|
|
||||||
val modality = if (regularClass.classKind == ClassKind.ENUM_CLASS) {
|
|
||||||
regularClass.enumClassModality()
|
|
||||||
} else {
|
|
||||||
regularClass.modality ?: Modality.FINAL
|
|
||||||
}
|
|
||||||
val irClass = regularClass.convertWithOffsets { startOffset, endOffset ->
|
|
||||||
irSymbolTable.declareClass(startOffset, endOffset, origin, descriptor, modality, visibility) { symbol ->
|
|
||||||
IrClassImpl(
|
|
||||||
startOffset,
|
|
||||||
endOffset,
|
|
||||||
origin,
|
|
||||||
symbol,
|
|
||||||
regularClass.name,
|
|
||||||
regularClass.classKind,
|
|
||||||
visibility,
|
|
||||||
modality,
|
|
||||||
isCompanion = regularClass.isCompanion,
|
|
||||||
isInner = regularClass.isInner,
|
|
||||||
isData = regularClass.isData,
|
|
||||||
isExternal = regularClass.isExternal,
|
|
||||||
isInline = regularClass.isInline,
|
|
||||||
isExpect = regularClass.isExpect,
|
|
||||||
isFun = false // TODO FirRegularClass.isFun
|
|
||||||
).apply {
|
|
||||||
descriptor.bind(this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (parent != null) {
|
|
||||||
irClass.parent = parent
|
|
||||||
}
|
|
||||||
if (regularClass.visibility == Visibilities.LOCAL) {
|
|
||||||
localStorage.putLocalClass(regularClass, irClass)
|
|
||||||
} else {
|
|
||||||
classCache[regularClass] = irClass
|
|
||||||
}
|
|
||||||
return irClass
|
|
||||||
}
|
|
||||||
|
|
||||||
fun createIrAnonymousObject(
|
|
||||||
anonymousObject: FirAnonymousObject,
|
|
||||||
visibility: Visibility = Visibilities.LOCAL,
|
|
||||||
name: Name = Name.special("<no name provided>"),
|
|
||||||
irParent: IrDeclarationParent? = null
|
|
||||||
): IrClass {
|
|
||||||
val descriptor = WrappedClassDescriptor()
|
|
||||||
val origin = IrDeclarationOrigin.DEFINED
|
|
||||||
val modality = Modality.FINAL
|
|
||||||
val result = anonymousObject.convertWithOffsets { startOffset, endOffset ->
|
|
||||||
irSymbolTable.declareClass(startOffset, endOffset, origin, descriptor, modality, visibility) { symbol ->
|
|
||||||
IrClassImpl(
|
|
||||||
startOffset, endOffset, origin, symbol, name,
|
|
||||||
// NB: for unknown reason, IR uses 'CLASS' kind for simple anonymous objects
|
|
||||||
anonymousObject.classKind.takeIf { it == ClassKind.ENUM_ENTRY } ?: ClassKind.CLASS,
|
|
||||||
visibility, modality,
|
|
||||||
isCompanion = false, isInner = false, isData = false,
|
|
||||||
isExternal = false, isInline = false, isExpect = false, isFun = false
|
|
||||||
).apply {
|
|
||||||
descriptor.bind(this)
|
|
||||||
setThisReceiver()
|
|
||||||
if (irParent != null) {
|
|
||||||
this.parent = irParent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.declareSupertypesAndTypeParameters(anonymousObject)
|
|
||||||
localStorage.putLocalClass(anonymousObject, result)
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getIrAnonymousObjectForEnumEntry(anonymousObject: FirAnonymousObject, name: Name, irParent: IrClass?): IrClass {
|
|
||||||
localStorage.getLocalClass(anonymousObject)?.let { return it }
|
|
||||||
return createIrAnonymousObject(anonymousObject, Visibilities.PRIVATE, name, irParent)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getIrTypeParameter(
|
|
||||||
typeParameter: FirTypeParameter,
|
|
||||||
index: Int = -1,
|
|
||||||
typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT
|
|
||||||
): IrTypeParameter {
|
|
||||||
// Here transformation is a bit difficult because one FIR property type parameter
|
|
||||||
// can be transformed to two different type parameters: one for getter and another one for setter
|
|
||||||
val simpleCachedParameter = typeParameterCache[typeParameter]
|
|
||||||
if (simpleCachedParameter != null) {
|
|
||||||
if (typeContext.origin != ConversionTypeOrigin.SETTER) {
|
|
||||||
return simpleCachedParameter
|
|
||||||
}
|
|
||||||
if (index < 0) {
|
|
||||||
val parent = simpleCachedParameter.parent
|
|
||||||
if (parent !is IrSimpleFunction || parent.returnType == typeConverter.unitType) {
|
|
||||||
return simpleCachedParameter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (typeContext.origin == ConversionTypeOrigin.SETTER) {
|
|
||||||
typeParameterCacheForSetter[typeParameter]?.let { return it }
|
|
||||||
}
|
|
||||||
return typeParameter.run {
|
|
||||||
// Yet I don't want to enable this requirement because it breaks some tests
|
|
||||||
// However, if we get here it *should* mean that type parameter index is given explicitly
|
|
||||||
// At this moment (20.02.2020) this requirement breaks 11/355 Fir2IrText tests
|
|
||||||
// require(index != -1)
|
|
||||||
val descriptor = WrappedTypeParameterDescriptor()
|
|
||||||
val origin = IrDeclarationOrigin.DEFINED
|
|
||||||
val irTypeParameter =
|
|
||||||
convertWithOffsets { startOffset, endOffset ->
|
|
||||||
irSymbolTable.declareGlobalTypeParameter(startOffset, endOffset, origin, descriptor) { symbol ->
|
|
||||||
IrTypeParameterImpl(
|
|
||||||
startOffset, endOffset, origin, symbol,
|
|
||||||
name, if (index < 0) 0 else index,
|
|
||||||
isReified,
|
|
||||||
variance
|
|
||||||
).apply {
|
|
||||||
descriptor.bind(this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cache the type parameter BEFORE processing its bounds/supertypes, to properly handle recursive type bounds.
|
|
||||||
if (typeContext.origin == ConversionTypeOrigin.SETTER) {
|
|
||||||
typeParameterCacheForSetter[typeParameter] = irTypeParameter
|
|
||||||
} else {
|
|
||||||
typeParameterCache[typeParameter] = irTypeParameter
|
|
||||||
}
|
|
||||||
bounds.mapTo(irTypeParameter.superTypes) { it.toIrType() }
|
|
||||||
irTypeParameter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun findIrParent(packageFqName: FqName, parentClassId: ClassId?, firBasedSymbol: FirBasedSymbol<*>): IrDeclarationParent? {
|
|
||||||
return if (parentClassId != null) {
|
return if (parentClassId != null) {
|
||||||
// TODO: this will never work for local classes
|
// TODO: this will never work for local classes
|
||||||
val parentFirSymbol = firSymbolProvider.getClassLikeSymbolByFqName(parentClassId)
|
val parentFirSymbol = firSymbolProvider.getClassLikeSymbolByFqName(parentClassId)
|
||||||
if (parentFirSymbol is FirClassSymbol) {
|
if (parentFirSymbol is FirClassSymbol) {
|
||||||
val parentIrSymbol = getIrClassSymbol(parentFirSymbol)
|
val parentIrSymbol = classifierStorage.getIrClassSymbol(parentFirSymbol)
|
||||||
parentIrSymbol.owner
|
parentIrSymbol.owner
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
@@ -485,7 +239,9 @@ class Fir2IrDeclarationStorage(
|
|||||||
) {
|
) {
|
||||||
val parent = this
|
val parent = this
|
||||||
if (function is FirSimpleFunction) {
|
if (function is FirSimpleFunction) {
|
||||||
setTypeParameters(function)
|
with(classifierStorage) {
|
||||||
|
setTypeParameters(function)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
val forSetter = function is FirPropertyAccessor && function.isSetter
|
val forSetter = function is FirPropertyAccessor && function.isSetter
|
||||||
val typeContext = ConversionTypeContext(
|
val typeContext = ConversionTypeContext(
|
||||||
@@ -509,24 +265,26 @@ class Fir2IrDeclarationStorage(
|
|||||||
if (function !is FirConstructor) {
|
if (function !is FirConstructor) {
|
||||||
val thisOrigin = IrDeclarationOrigin.DEFINED
|
val thisOrigin = IrDeclarationOrigin.DEFINED
|
||||||
val receiverTypeRef = if (function !is FirPropertyAccessor) function?.receiverTypeRef else parentPropertyReceiverType
|
val receiverTypeRef = if (function !is FirPropertyAccessor) function?.receiverTypeRef else parentPropertyReceiverType
|
||||||
if (receiverTypeRef != null) {
|
with(classifierStorage) {
|
||||||
extensionReceiverParameter = receiverTypeRef.convertWithOffsets { startOffset, endOffset ->
|
if (receiverTypeRef != null) {
|
||||||
declareThisReceiverParameter(
|
extensionReceiverParameter = receiverTypeRef.convertWithOffsets { startOffset, endOffset ->
|
||||||
|
declareThisReceiverParameter(
|
||||||
|
parent,
|
||||||
|
thisType = receiverTypeRef.toIrType(typeContext),
|
||||||
|
thisOrigin = thisOrigin,
|
||||||
|
startOffset = startOffset,
|
||||||
|
endOffset = endOffset
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (function !is FirAnonymousFunction && containingClass != null && !isStatic) {
|
||||||
|
dispatchReceiverParameter = declareThisReceiverParameter(
|
||||||
parent,
|
parent,
|
||||||
thisType = receiverTypeRef.toIrType(typeContext),
|
thisType = containingClass.thisReceiver!!.type,
|
||||||
thisOrigin = thisOrigin,
|
thisOrigin = thisOrigin
|
||||||
startOffset = startOffset,
|
|
||||||
endOffset = endOffset
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (function !is FirAnonymousFunction && containingClass != null && !isStatic) {
|
|
||||||
dispatchReceiverParameter = declareThisReceiverParameter(
|
|
||||||
parent,
|
|
||||||
thisType = containingClass.thisReceiver!!.type,
|
|
||||||
thisOrigin = thisOrigin
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -552,10 +310,6 @@ class Fir2IrDeclarationStorage(
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
fun putEnumEntryClassInScope(enumEntry: FirEnumEntry, correspondingClass: IrClass) {
|
|
||||||
localStorage.putLocalClass(enumEntry.initializer as FirAnonymousObject, correspondingClass)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getCachedIrFunction(function: FirFunction<*>): IrSimpleFunction? {
|
fun getCachedIrFunction(function: FirFunction<*>): IrSimpleFunction? {
|
||||||
return if (function !is FirSimpleFunction || function.visibility == Visibilities.LOCAL) {
|
return if (function !is FirSimpleFunction || function.visibility == Visibilities.LOCAL) {
|
||||||
localStorage.getLocalFunction(function)
|
localStorage.getLocalFunction(function)
|
||||||
@@ -578,7 +332,7 @@ class Fir2IrDeclarationStorage(
|
|||||||
function.symbol.callableId.isKFunctionInvoke() -> IrDeclarationOrigin.FAKE_OVERRIDE
|
function.symbol.callableId.isKFunctionInvoke() -> IrDeclarationOrigin.FAKE_OVERRIDE
|
||||||
else -> origin
|
else -> origin
|
||||||
}
|
}
|
||||||
preCacheTypeParameters(function)
|
classifierStorage.preCacheTypeParameters(function)
|
||||||
val name = simpleFunction?.name
|
val name = simpleFunction?.name
|
||||||
?: if (isLambda) Name.special("<anonymous>") else Name.special("<no name provided>")
|
?: if (isLambda) Name.special("<anonymous>") else Name.special("<no name provided>")
|
||||||
val visibility = simpleFunction?.visibility ?: Visibilities.LOCAL
|
val visibility = simpleFunction?.visibility ?: Visibilities.LOCAL
|
||||||
@@ -694,12 +448,14 @@ class Fir2IrDeclarationStorage(
|
|||||||
isFakeOverride = origin == IrDeclarationOrigin.FAKE_OVERRIDE,
|
isFakeOverride = origin == IrDeclarationOrigin.FAKE_OVERRIDE,
|
||||||
isOperator = false
|
isOperator = false
|
||||||
).apply {
|
).apply {
|
||||||
setTypeParameters(
|
with(classifierStorage) {
|
||||||
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(ConversionTypeContext.DEFAULT.inSetter())
|
property.returnTypeRef.toIrType(ConversionTypeContext.DEFAULT.inSetter())
|
||||||
@@ -719,44 +475,6 @@ class Fir2IrDeclarationStorage(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getCachedIrEnumEntry(enumEntry: FirEnumEntry): IrEnumEntry? = enumEntryCache[enumEntry]
|
|
||||||
|
|
||||||
fun createIrEnumEntry(
|
|
||||||
enumEntry: FirEnumEntry,
|
|
||||||
irParent: IrClass?,
|
|
||||||
origin: IrDeclarationOrigin = IrDeclarationOrigin.DEFINED
|
|
||||||
): IrEnumEntry {
|
|
||||||
return enumEntry.convertWithOffsets { startOffset, endOffset ->
|
|
||||||
val desc = WrappedEnumEntryDescriptor()
|
|
||||||
enterScope(desc)
|
|
||||||
val result = irSymbolTable.declareEnumEntry(startOffset, endOffset, origin, desc) { symbol ->
|
|
||||||
IrEnumEntryImpl(
|
|
||||||
startOffset, endOffset, origin, symbol, enumEntry.name
|
|
||||||
).apply {
|
|
||||||
desc.bind(this)
|
|
||||||
val irType = enumEntry.returnTypeRef.toIrType()
|
|
||||||
if (irParent != null) {
|
|
||||||
this.parent = irParent
|
|
||||||
}
|
|
||||||
val initializer = enumEntry.initializer
|
|
||||||
if (initializer != null) {
|
|
||||||
initializer as FirAnonymousObject
|
|
||||||
val klass = getIrAnonymousObjectForEnumEntry(initializer, enumEntry.name, irParent)
|
|
||||||
|
|
||||||
this.correspondingClass = klass
|
|
||||||
} else if (irParent != null) {
|
|
||||||
this.initializerExpression = IrExpressionBodyImpl(
|
|
||||||
IrEnumConstructorCallImpl(startOffset, endOffset, irType, irParent.constructors.first().symbol)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
leaveScope(desc)
|
|
||||||
enumEntryCache[enumEntry] = result
|
|
||||||
result
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun createIrProperty(
|
fun createIrProperty(
|
||||||
property: FirProperty,
|
property: FirProperty,
|
||||||
irParent: IrDeclarationParent?,
|
irParent: IrDeclarationParent?,
|
||||||
@@ -764,7 +482,7 @@ class Fir2IrDeclarationStorage(
|
|||||||
): IrProperty {
|
): IrProperty {
|
||||||
val containerSource = property.containerSource
|
val containerSource = property.containerSource
|
||||||
val descriptor = containerSource?.let { WrappedPropertyDescriptorWithContainerSource(it) } ?: WrappedPropertyDescriptor()
|
val descriptor = containerSource?.let { WrappedPropertyDescriptorWithContainerSource(it) } ?: WrappedPropertyDescriptor()
|
||||||
preCacheTypeParameters(property)
|
classifierStorage.preCacheTypeParameters(property)
|
||||||
return property.convertWithOffsets { startOffset, endOffset ->
|
return property.convertWithOffsets { startOffset, endOffset ->
|
||||||
enterScope(descriptor)
|
enterScope(descriptor)
|
||||||
val result = irSymbolTable.declareProperty(
|
val result = irSymbolTable.declareProperty(
|
||||||
@@ -936,36 +654,6 @@ class Fir2IrDeclarationStorage(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getIrClassSymbol(firClassSymbol: FirClassSymbol<*>): IrClassSymbol {
|
|
||||||
val firClass = firClassSymbol.fir
|
|
||||||
getCachedIrClass(firClass)?.let { return irSymbolTable.referenceClass(it.descriptor) }
|
|
||||||
// TODO: remove all this code and change to unbound symbol creation
|
|
||||||
val irClass = createIrClass(firClass)
|
|
||||||
if (firClass is FirAnonymousObject || firClass is FirRegularClass && firClass.visibility == Visibilities.LOCAL) {
|
|
||||||
return irSymbolTable.referenceClass(irClass.descriptor)
|
|
||||||
}
|
|
||||||
val classId = firClassSymbol.classId
|
|
||||||
val parentId = classId.outerClassId
|
|
||||||
val irParent = findIrParent(classId.packageFqName, parentId, firClassSymbol)
|
|
||||||
if (irParent != null) {
|
|
||||||
irClass.parent = irParent
|
|
||||||
}
|
|
||||||
if (irParent is IrExternalPackageFragment) {
|
|
||||||
addDeclarationsToExternalClass(firClass as FirRegularClass, irClass)
|
|
||||||
}
|
|
||||||
|
|
||||||
return irSymbolTable.referenceClass(irClass.descriptor)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getIrTypeParameterSymbol(
|
|
||||||
firTypeParameterSymbol: FirTypeParameterSymbol,
|
|
||||||
typeContext: ConversionTypeContext
|
|
||||||
): IrTypeParameterSymbol {
|
|
||||||
// TODO: use cached type parameter here
|
|
||||||
val irTypeParameter = getIrTypeParameter(firTypeParameterSymbol.fir, typeContext = typeContext)
|
|
||||||
return irSymbolTable.referenceTypeParameter(irTypeParameter.descriptor)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getIrConstructorSymbol(firConstructorSymbol: FirConstructorSymbol): IrConstructorSymbol {
|
fun getIrConstructorSymbol(firConstructorSymbol: FirConstructorSymbol): IrConstructorSymbol {
|
||||||
val firConstructor = firConstructorSymbol.fir
|
val firConstructor = firConstructorSymbol.fir
|
||||||
getCachedIrConstructor(firConstructor)?.let { return irSymbolTable.referenceConstructor(it.descriptor) }
|
getCachedIrConstructor(firConstructor)?.let { return irSymbolTable.referenceConstructor(it.descriptor) }
|
||||||
@@ -1043,11 +731,11 @@ class Fir2IrDeclarationStorage(
|
|||||||
fun getIrValueSymbol(firVariableSymbol: FirVariableSymbol<*>): IrSymbol {
|
fun getIrValueSymbol(firVariableSymbol: FirVariableSymbol<*>): IrSymbol {
|
||||||
return when (val firDeclaration = firVariableSymbol.fir) {
|
return when (val firDeclaration = firVariableSymbol.fir) {
|
||||||
is FirEnumEntry -> {
|
is FirEnumEntry -> {
|
||||||
getCachedIrEnumEntry(firDeclaration)?.let { return irSymbolTable.referenceEnumEntry(it.descriptor) }
|
classifierStorage.getCachedIrEnumEntry(firDeclaration)?.let { return irSymbolTable.referenceEnumEntry(it.descriptor) }
|
||||||
val containingFile = firProvider.getFirCallableContainerFile(firVariableSymbol)
|
val containingFile = firProvider.getFirCallableContainerFile(firVariableSymbol)
|
||||||
val parentClassSymbol = firVariableSymbol.callableId.classId?.let { firSymbolProvider.getClassLikeSymbolByFqName(it) }
|
val parentClassSymbol = firVariableSymbol.callableId.classId?.let { firSymbolProvider.getClassLikeSymbolByFqName(it) }
|
||||||
val irParentClass = (parentClassSymbol?.fir as? FirClass<*>)?.let { getCachedIrClass(it) }
|
val irParentClass = (parentClassSymbol?.fir as? FirClass<*>)?.let { classifierStorage.getCachedIrClass(it) }
|
||||||
val irEnumEntry = createIrEnumEntry(
|
val irEnumEntry = classifierStorage.createIrEnumEntry(
|
||||||
firDeclaration,
|
firDeclaration,
|
||||||
irParent = irParentClass,
|
irParent = irParentClass,
|
||||||
origin = if (containingFile == null) IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB else IrDeclarationOrigin.DEFINED
|
origin = if (containingFile == null) IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB else IrDeclarationOrigin.DEFINED
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.types.Variance
|
|||||||
|
|
||||||
class Fir2IrTypeConverter(
|
class Fir2IrTypeConverter(
|
||||||
private val session: FirSession,
|
private val session: FirSession,
|
||||||
private val declarationStorage: Fir2IrDeclarationStorage,
|
private val classifierStorage: Fir2IrClassifierStorage,
|
||||||
private val irBuiltIns: IrBuiltIns
|
private val irBuiltIns: IrBuiltIns
|
||||||
) {
|
) {
|
||||||
lateinit var nothingType: IrType
|
lateinit var nothingType: IrType
|
||||||
@@ -49,7 +49,7 @@ class Fir2IrTypeConverter(
|
|||||||
is ConeLookupTagBasedType -> {
|
is ConeLookupTagBasedType -> {
|
||||||
val irSymbol = getArrayType(this.classId) ?: run {
|
val irSymbol = getArrayType(this.classId) ?: run {
|
||||||
val firSymbol = this.lookupTag.toSymbol(session) ?: return createErrorType()
|
val firSymbol = this.lookupTag.toSymbol(session) ?: return createErrorType()
|
||||||
firSymbol.toIrSymbol(session, declarationStorage, typeContext)
|
firSymbol.toSymbol(session, classifierStorage, typeContext)
|
||||||
}
|
}
|
||||||
// TODO: annotations
|
// TODO: annotations
|
||||||
IrSimpleTypeImpl(
|
IrSimpleTypeImpl(
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ import java.util.*
|
|||||||
class Fir2IrVisitor(
|
class Fir2IrVisitor(
|
||||||
private val session: FirSession,
|
private val session: FirSession,
|
||||||
private val symbolTable: SymbolTable,
|
private val symbolTable: SymbolTable,
|
||||||
|
private val classifierStorage: Fir2IrClassifierStorage,
|
||||||
private val declarationStorage: Fir2IrDeclarationStorage,
|
private val declarationStorage: Fir2IrDeclarationStorage,
|
||||||
private val converter: Fir2IrConverter,
|
private val converter: Fir2IrConverter,
|
||||||
private val typeConverter: Fir2IrTypeConverter,
|
private val typeConverter: Fir2IrTypeConverter,
|
||||||
@@ -95,10 +96,10 @@ class Fir2IrVisitor(
|
|||||||
// ==================================================================================
|
// ==================================================================================
|
||||||
|
|
||||||
override fun visitEnumEntry(enumEntry: FirEnumEntry, data: Any?): IrElement {
|
override fun visitEnumEntry(enumEntry: FirEnumEntry, data: Any?): IrElement {
|
||||||
val irEnumEntry = declarationStorage.getCachedIrEnumEntry(enumEntry)!!
|
val irEnumEntry = classifierStorage.getCachedIrEnumEntry(enumEntry)!!
|
||||||
val correspondingClass = irEnumEntry.correspondingClass ?: return irEnumEntry
|
val correspondingClass = irEnumEntry.correspondingClass ?: return irEnumEntry
|
||||||
declarationStorage.enterScope(irEnumEntry.descriptor)
|
declarationStorage.enterScope(irEnumEntry.descriptor)
|
||||||
declarationStorage.putEnumEntryClassInScope(enumEntry, correspondingClass)
|
classifierStorage.putEnumEntryClassInScope(enumEntry, correspondingClass)
|
||||||
converter.processAnonymousObjectMembers(enumEntry.initializer as FirAnonymousObject, correspondingClass)
|
converter.processAnonymousObjectMembers(enumEntry.initializer as FirAnonymousObject, correspondingClass)
|
||||||
conversionScope.withParent(correspondingClass) {
|
conversionScope.withParent(correspondingClass) {
|
||||||
setClassContent(enumEntry.initializer as FirAnonymousObject)
|
setClassContent(enumEntry.initializer as FirAnonymousObject)
|
||||||
@@ -150,7 +151,7 @@ class Fir2IrVisitor(
|
|||||||
override fun visitRegularClass(regularClass: FirRegularClass, data: Any?): IrElement {
|
override fun visitRegularClass(regularClass: FirRegularClass, data: Any?): IrElement {
|
||||||
if (regularClass.visibility == Visibilities.LOCAL) {
|
if (regularClass.visibility == Visibilities.LOCAL) {
|
||||||
val irParent = conversionScope.parentFromStack()
|
val irParent = conversionScope.parentFromStack()
|
||||||
val irClass = declarationStorage.getCachedIrClass(regularClass)?.apply { this.parent = irParent }
|
val irClass = classifierStorage.getCachedIrClass(regularClass)?.apply { this.parent = irParent }
|
||||||
if (irClass != null) {
|
if (irClass != null) {
|
||||||
converter.processRegisteredLocalClassAndNestedClasses(regularClass, irClass)
|
converter.processRegisteredLocalClassAndNestedClasses(regularClass, irClass)
|
||||||
return conversionScope.withParent(irClass) {
|
return conversionScope.withParent(irClass) {
|
||||||
@@ -159,7 +160,7 @@ class Fir2IrVisitor(
|
|||||||
}
|
}
|
||||||
converter.processLocalClassAndNestedClasses(regularClass, irParent)
|
converter.processLocalClassAndNestedClasses(regularClass, irParent)
|
||||||
}
|
}
|
||||||
val irClass = declarationStorage.getCachedIrClass(regularClass)!!
|
val irClass = classifierStorage.getCachedIrClass(regularClass)!!
|
||||||
return conversionScope.withParent(irClass) {
|
return conversionScope.withParent(irClass) {
|
||||||
setClassContent(regularClass)
|
setClassContent(regularClass)
|
||||||
}
|
}
|
||||||
@@ -168,8 +169,8 @@ class Fir2IrVisitor(
|
|||||||
override fun visitAnonymousObject(anonymousObject: FirAnonymousObject, data: Any?): IrElement {
|
override fun visitAnonymousObject(anonymousObject: FirAnonymousObject, data: Any?): IrElement {
|
||||||
val irParent = conversionScope.parentFromStack()
|
val irParent = conversionScope.parentFromStack()
|
||||||
// NB: for implicit types it is possible that anonymous object is already cached
|
// NB: for implicit types it is possible that anonymous object is already cached
|
||||||
val irAnonymousObject = declarationStorage.getCachedIrClass(anonymousObject)?.apply { this.parent = irParent }
|
val irAnonymousObject = classifierStorage.getCachedIrClass(anonymousObject)?.apply { this.parent = irParent }
|
||||||
?: declarationStorage.createIrAnonymousObject(anonymousObject, irParent = irParent)
|
?: classifierStorage.createIrAnonymousObject(anonymousObject, irParent = irParent)
|
||||||
converter.processAnonymousObjectMembers(anonymousObject, irAnonymousObject)
|
converter.processAnonymousObjectMembers(anonymousObject, irAnonymousObject)
|
||||||
conversionScope.withParent(irAnonymousObject) {
|
conversionScope.withParent(irAnonymousObject) {
|
||||||
setClassContent(anonymousObject)
|
setClassContent(anonymousObject)
|
||||||
@@ -499,7 +500,7 @@ class Fir2IrVisitor(
|
|||||||
|
|
||||||
private fun FirQualifiedAccess.toIrExpression(typeRef: FirTypeRef): IrExpression {
|
private fun FirQualifiedAccess.toIrExpression(typeRef: FirTypeRef): IrExpression {
|
||||||
val type = typeRef.toIrType()
|
val type = typeRef.toIrType()
|
||||||
val symbol = calleeReference.toSymbol(declarationStorage)
|
val symbol = calleeReference.toSymbol(session, classifierStorage, declarationStorage)
|
||||||
return typeRef.convertWithOffsets { startOffset, endOffset ->
|
return typeRef.convertWithOffsets { startOffset, endOffset ->
|
||||||
if (calleeReference is FirSuperReference) {
|
if (calleeReference is FirSuperReference) {
|
||||||
if (typeRef !is FirComposedSuperTypeRef) {
|
if (typeRef !is FirComposedSuperTypeRef) {
|
||||||
@@ -647,7 +648,7 @@ class Fir2IrVisitor(
|
|||||||
it is FirAnonymousObject || it is FirRegularClass && it.classKind == ClassKind.OBJECT
|
it is FirAnonymousObject || it is FirRegularClass && it.classKind == ClassKind.OBJECT
|
||||||
}
|
}
|
||||||
firClass?.convertWithOffsets { startOffset, endOffset ->
|
firClass?.convertWithOffsets { startOffset, endOffset ->
|
||||||
val irClass = declarationStorage.getCachedIrClass(firClass)!!
|
val irClass = classifierStorage.getCachedIrClass(firClass)!!
|
||||||
IrGetObjectValueImpl(startOffset, endOffset, irClass.defaultType, irClass.symbol)
|
IrGetObjectValueImpl(startOffset, endOffset, irClass.defaultType, irClass.symbol)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -715,7 +716,7 @@ class Fir2IrVisitor(
|
|||||||
it is FirAnonymousObject || it is FirRegularClass && it.classKind == ClassKind.OBJECT
|
it is FirAnonymousObject || it is FirRegularClass && it.classKind == ClassKind.OBJECT
|
||||||
}
|
}
|
||||||
if (firObject != null) {
|
if (firObject != null) {
|
||||||
val irObject = declarationStorage.getCachedIrClass(firObject)!!
|
val irObject = classifierStorage.getCachedIrClass(firObject)!!
|
||||||
if (irObject != conversionScope.lastClass()) {
|
if (irObject != conversionScope.lastClass()) {
|
||||||
return thisReceiverExpression.convertWithOffsets { startOffset, endOffset ->
|
return thisReceiverExpression.convertWithOffsets { startOffset, endOffset ->
|
||||||
IrGetObjectValueImpl(startOffset, endOffset, irObject.defaultType, irObject.symbol)
|
IrGetObjectValueImpl(startOffset, endOffset, irObject.defaultType, irObject.symbol)
|
||||||
@@ -750,7 +751,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(session, classifierStorage, declarationStorage)
|
||||||
val type = callableReferenceAccess.typeRef.toIrType()
|
val type = callableReferenceAccess.typeRef.toIrType()
|
||||||
return callableReferenceAccess.convertWithOffsets { startOffset, endOffset ->
|
return callableReferenceAccess.convertWithOffsets { startOffset, endOffset ->
|
||||||
when (symbol) {
|
when (symbol) {
|
||||||
@@ -792,7 +793,7 @@ class Fir2IrVisitor(
|
|||||||
|
|
||||||
override fun visitVariableAssignment(variableAssignment: FirVariableAssignment, data: Any?): IrElement {
|
override fun visitVariableAssignment(variableAssignment: FirVariableAssignment, data: Any?): IrElement {
|
||||||
val calleeReference = variableAssignment.calleeReference
|
val calleeReference = variableAssignment.calleeReference
|
||||||
val symbol = calleeReference.toSymbol(declarationStorage)
|
val symbol = calleeReference.toSymbol(session, classifierStorage, declarationStorage)
|
||||||
return variableAssignment.convertWithOffsets { startOffset, endOffset ->
|
return variableAssignment.convertWithOffsets { startOffset, endOffset ->
|
||||||
if (symbol != null && symbol.isBound) {
|
if (symbol != null && symbol.isBound) {
|
||||||
when (symbol) {
|
when (symbol) {
|
||||||
@@ -1235,7 +1236,7 @@ class Fir2IrVisitor(
|
|||||||
val irClassType = argument.typeRef.toIrType()
|
val irClassType = argument.typeRef.toIrType()
|
||||||
val irClassReferenceSymbol = when (argument) {
|
val irClassReferenceSymbol = when (argument) {
|
||||||
is FirResolvedReifiedParameterReference -> {
|
is FirResolvedReifiedParameterReference -> {
|
||||||
declarationStorage.getIrTypeParameterSymbol(argument.symbol, ConversionTypeContext.DEFAULT)
|
classifierStorage.getIrTypeParameterSymbol(argument.symbol, ConversionTypeContext.DEFAULT)
|
||||||
}
|
}
|
||||||
is FirResolvedQualifier -> {
|
is FirResolvedQualifier -> {
|
||||||
val symbol = argument.symbol as? FirClassSymbol
|
val symbol = argument.symbol as? FirClassSymbol
|
||||||
@@ -1244,7 +1245,7 @@ class Fir2IrVisitor(
|
|||||||
startOffset, endOffset, irType, "Resolved qualifier ${argument.render()} does not have correct symbol"
|
startOffset, endOffset, irType, "Resolved qualifier ${argument.render()} does not have correct symbol"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
declarationStorage.getIrClassSymbol(symbol)
|
classifierStorage.getIrClassSymbol(symbol)
|
||||||
}
|
}
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
@@ -1274,7 +1275,7 @@ class Fir2IrVisitor(
|
|||||||
if (classSymbol != null) {
|
if (classSymbol != null) {
|
||||||
IrGetObjectValueImpl(
|
IrGetObjectValueImpl(
|
||||||
startOffset, endOffset, irType,
|
startOffset, endOffset, irType,
|
||||||
classSymbol.toIrSymbol(session, declarationStorage) as IrClassSymbol
|
classSymbol.toSymbol(session, classifierStorage) as IrClassSymbol
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
IrErrorCallExpressionImpl(
|
IrErrorCallExpressionImpl(
|
||||||
|
|||||||
Reference in New Issue
Block a user