[FIR2IR] Introduce creation of Fir2Ir lazy classes
This commit is contained in:
+16
-9
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.backend
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyClass
|
||||
import org.jetbrains.kotlin.fir.resolve.firProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.Fir2IrClassSymbol
|
||||
@@ -311,7 +312,7 @@ class Fir2IrClassifierStorage(
|
||||
return irTypeParameter
|
||||
}
|
||||
|
||||
private fun getCachedIrTypeParameter(
|
||||
internal fun getCachedIrTypeParameter(
|
||||
typeParameter: FirTypeParameter,
|
||||
index: Int = -1,
|
||||
typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT
|
||||
@@ -336,7 +337,7 @@ class Fir2IrClassifierStorage(
|
||||
return null
|
||||
}
|
||||
|
||||
private fun getIrTypeParameter(
|
||||
internal fun getIrTypeParameter(
|
||||
typeParameter: FirTypeParameter,
|
||||
index: Int,
|
||||
typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT
|
||||
@@ -417,17 +418,23 @@ class Fir2IrClassifierStorage(
|
||||
declarationStorage.preCacheBuiltinClassMembers(firClass, irClass)
|
||||
return irClassSymbol
|
||||
}
|
||||
// TODO: remove all this code and change to unbound symbol creation
|
||||
firClass as FirRegularClass
|
||||
val classId = firClassSymbol.classId
|
||||
val parentId = classId.outerClassId
|
||||
val irParent = declarationStorage.findIrParent(classId.packageFqName, parentId, firClassSymbol)
|
||||
val irClass = createIrClass(firClass, irParent)
|
||||
|
||||
if (irParent is IrExternalPackageFragment) {
|
||||
declarationStorage.addDeclarationsToExternalClass(firClass as FirRegularClass, irClass)
|
||||
val irParent = declarationStorage.findIrParent(classId.packageFqName, parentId, firClassSymbol)!!
|
||||
val symbol = Fir2IrClassSymbol(signature)
|
||||
val irClass = firClass.convertWithOffsets { startOffset, endOffset ->
|
||||
symbolTable.declareClass(signature, { symbol }) {
|
||||
Fir2IrLazyClass(components, startOffset, endOffset, firClass.irOrigin(firProvider), firClass, symbol).apply {
|
||||
parent = irParent
|
||||
}
|
||||
}
|
||||
}
|
||||
classCache[firClass] = irClass
|
||||
// NB: this is needed to prevent recursions in case of self bounds
|
||||
(irClass as Fir2IrLazyClass).prepareTypeParameters()
|
||||
|
||||
return irClass.symbol
|
||||
return symbol
|
||||
}
|
||||
|
||||
fun getIrTypeParameterSymbol(
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
package org.jetbrains.kotlin.fir.backend
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.backend.generators.CallAndReferenceGenerator
|
||||
import org.jetbrains.kotlin.fir.backend.generators.FakeOverrideGenerator
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
@@ -19,4 +21,6 @@ interface Fir2IrComponents {
|
||||
val declarationStorage: Fir2IrDeclarationStorage
|
||||
val typeConverter: Fir2IrTypeConverter
|
||||
val signatureComposer: Fir2IrSignatureComposer
|
||||
val callGenerator: CallAndReferenceGenerator
|
||||
val fakeOverrideGenerator: FakeOverrideGenerator
|
||||
}
|
||||
@@ -6,6 +6,8 @@
|
||||
package org.jetbrains.kotlin.fir.backend
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.backend.generators.CallAndReferenceGenerator
|
||||
import org.jetbrains.kotlin.fir.backend.generators.FakeOverrideGenerator
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.signaturer.FirBasedSignatureComposer
|
||||
import org.jetbrains.kotlin.fir.signaturer.FirMangler
|
||||
@@ -22,6 +24,8 @@ class Fir2IrComponentsStorage(
|
||||
override lateinit var classifierStorage: Fir2IrClassifierStorage
|
||||
override lateinit var declarationStorage: Fir2IrDeclarationStorage
|
||||
override lateinit var typeConverter: Fir2IrTypeConverter
|
||||
override lateinit var callGenerator: CallAndReferenceGenerator
|
||||
override lateinit var fakeOverrideGenerator: FakeOverrideGenerator
|
||||
|
||||
override val signatureComposer = FirBasedSignatureComposer(mangler)
|
||||
}
|
||||
@@ -9,6 +9,8 @@ import org.jetbrains.kotlin.backend.common.ir.BuiltinSymbolsBase
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.backend.generators.AnnotationGenerator
|
||||
import org.jetbrains.kotlin.fir.backend.generators.CallAndReferenceGenerator
|
||||
import org.jetbrains.kotlin.fir.backend.generators.FakeOverrideGenerator
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.descriptors.FirModuleDescriptor
|
||||
import org.jetbrains.kotlin.fir.psi
|
||||
@@ -188,8 +190,7 @@ class Fir2IrConverter(
|
||||
val components = Fir2IrComponentsStorage(session, scopeSession, symbolTable, builtIns, mangler)
|
||||
val conversionScope = Fir2IrConversionScope()
|
||||
val classifierStorage = Fir2IrClassifierStorage(components)
|
||||
val declarationStorage =
|
||||
Fir2IrDeclarationStorage(components, moduleDescriptor, classifierStorage, conversionScope, fakeOverrideMode)
|
||||
val declarationStorage = Fir2IrDeclarationStorage(components, moduleDescriptor)
|
||||
val typeConverter = Fir2IrTypeConverter(components)
|
||||
components.declarationStorage = declarationStorage
|
||||
components.classifierStorage = classifierStorage
|
||||
@@ -214,12 +215,18 @@ class Fir2IrConverter(
|
||||
for (firFile in firFiles) {
|
||||
converter.processClassHeaders(firFile)
|
||||
}
|
||||
val fakeOverrideGenerator = FakeOverrideGenerator(
|
||||
session, scopeSession, classifierStorage, declarationStorage, conversionScope, fakeOverrideMode
|
||||
)
|
||||
components.fakeOverrideGenerator = fakeOverrideGenerator
|
||||
for (firFile in firFiles) {
|
||||
converter.processFileAndClassMembers(firFile)
|
||||
}
|
||||
|
||||
val fir2irVisitor = Fir2IrVisitor(converter, components, conversionScope, fakeOverrideMode)
|
||||
declarationStorage.annotationGenerator = AnnotationGenerator(fir2irVisitor)
|
||||
val callGenerator = CallAndReferenceGenerator(components, fir2irVisitor, conversionScope)
|
||||
components.callGenerator = callGenerator
|
||||
declarationStorage.annotationGenerator = AnnotationGenerator(components)
|
||||
for (firFile in firFiles) {
|
||||
val irFile = firFile.accept(fir2irVisitor, null) as IrFile
|
||||
val fileEntry = sourceManager.getOrCreateFileEntry(firFile.psi as KtFile)
|
||||
|
||||
+1
-87
@@ -11,7 +11,6 @@ import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.fir.FirAnnotationContainer
|
||||
import org.jetbrains.kotlin.fir.backend.generators.AnnotationGenerator
|
||||
import org.jetbrains.kotlin.fir.backend.generators.FakeOverrideGenerator
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertySetter
|
||||
@@ -23,7 +22,6 @@ import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirExpressionStub
|
||||
import org.jetbrains.kotlin.fir.render
|
||||
import org.jetbrains.kotlin.fir.resolve.*
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirClassSubstitutionScope
|
||||
import org.jetbrains.kotlin.fir.symbols.*
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
@@ -49,18 +47,11 @@ import org.jetbrains.kotlin.serialization.deserialization.descriptors.Deserializ
|
||||
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
||||
class Fir2IrDeclarationStorage(
|
||||
private val components: Fir2IrComponents,
|
||||
private val moduleDescriptor: FirModuleDescriptor,
|
||||
classifierStorage: Fir2IrClassifierStorage,
|
||||
conversionScope: Fir2IrConversionScope,
|
||||
fakeOverrideMode: FakeOverrideMode
|
||||
private val moduleDescriptor: FirModuleDescriptor
|
||||
) : Fir2IrComponents by components {
|
||||
|
||||
internal var annotationGenerator: AnnotationGenerator? = null
|
||||
|
||||
private val fakeOverrideGenerator = FakeOverrideGenerator(
|
||||
session, components.scopeSession, classifierStorage, this, conversionScope, fakeOverrideMode
|
||||
)
|
||||
|
||||
private val firSymbolProvider = session.firSymbolProvider
|
||||
|
||||
private val firProvider = session.firProvider
|
||||
@@ -192,83 +183,6 @@ class Fir2IrDeclarationStorage(
|
||||
}
|
||||
}
|
||||
|
||||
internal fun addDeclarationsToExternalClass(regularClass: FirRegularClass, irClass: IrClass) {
|
||||
if (regularClass.origin == FirDeclarationOrigin.Java) {
|
||||
val sam = regularClass.getSamIfAny()
|
||||
if (sam != null) {
|
||||
val scope = regularClass.buildUseSiteMemberScope(session, scopeSession)!!
|
||||
scope.processFunctionsByName(sam.name) {
|
||||
if (it is FirNamedFunctionSymbol && !it.isFakeOverride) {
|
||||
irClass.declarations += createIrFunction(it.fir, irClass)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (regularClass.symbol.classId.packageFqName.startsWith(Name.identifier("kotlin"))) {
|
||||
// Note: yet this is necessary only for *Range / *Progression classes
|
||||
// due to BE optimizations (for lowering) that use their first / last / step members
|
||||
// TODO: think how to refactor this piece of code and/or merge it with similar Fir2IrVisitor fragment
|
||||
val processedNames = mutableSetOf<Name>()
|
||||
// NB: it's necessary to take all callables from scope,
|
||||
// e.g. to avoid accessing un-enhanced Java declarations with FirJavaTypeRef etc. inside
|
||||
val scope = regularClass.buildUseSiteMemberScope(session, scopeSession)!!
|
||||
scope.processDeclaredConstructors {
|
||||
irClass.declarations += createIrConstructor(it.fir, irClass)
|
||||
}
|
||||
classifierStorage.processClassHeader(regularClass, irClass)
|
||||
for (declaration in regularClass.declarations) {
|
||||
when (declaration) {
|
||||
is FirSimpleFunction -> {
|
||||
if (declaration.name !in processedNames) {
|
||||
processedNames += declaration.name
|
||||
scope.processFunctionsByName(declaration.name) {
|
||||
if (it is FirNamedFunctionSymbol) {
|
||||
if (!it.isFakeOverride) {
|
||||
irClass.declarations += createIrFunction(it.fir, irClass)
|
||||
} else {
|
||||
val fakeOverrideSymbol =
|
||||
FirClassSubstitutionScope.createFakeOverrideFunction(session, it.fir, it)
|
||||
classifierStorage.preCacheTypeParameters(it.fir)
|
||||
irClass.declarations += createIrFunction(fakeOverrideSymbol.fir, irClass)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
is FirProperty -> {
|
||||
if (declaration.name !in processedNames) {
|
||||
processedNames += declaration.name
|
||||
scope.processPropertiesByName(declaration.name) {
|
||||
if (it is FirPropertySymbol) {
|
||||
if (!it.isFakeOverride) {
|
||||
irClass.declarations += createIrProperty(it.fir, irClass)
|
||||
} else {
|
||||
val fakeOverrideSymbol =
|
||||
FirClassSubstitutionScope.createFakeOverrideProperty(session, it.fir, it)
|
||||
classifierStorage.preCacheTypeParameters(it.fir)
|
||||
irClass.declarations += createIrProperty(fakeOverrideSymbol.fir, irClass)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
is FirRegularClass -> {
|
||||
val nestedExternalClass = classifierStorage.createIrClass(declaration, irClass)
|
||||
addDeclarationsToExternalClass(declaration, nestedExternalClass)
|
||||
irClass.declarations += nestedExternalClass
|
||||
}
|
||||
else -> continue
|
||||
}
|
||||
}
|
||||
with(fakeOverrideGenerator) {
|
||||
irClass.addFakeOverrides(regularClass, processedNames)
|
||||
}
|
||||
for (irDeclaration in irClass.declarations) {
|
||||
irDeclaration.parent = irClass
|
||||
}
|
||||
}
|
||||
irClass.convertAnnotationsFromLibrary(regularClass)
|
||||
}
|
||||
|
||||
internal fun findIrParent(packageFqName: FqName, parentClassId: ClassId?, firBasedSymbol: FirBasedSymbol<*>): IrDeclarationParent? {
|
||||
return if (parentClassId != null) {
|
||||
// TODO: this will never work for local classes
|
||||
|
||||
@@ -9,7 +9,6 @@ import org.jetbrains.kotlin.KtNodeTypes
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.backend.generators.CallAndReferenceGenerator
|
||||
import org.jetbrains.kotlin.fir.backend.generators.ClassMemberGenerator
|
||||
import org.jetbrains.kotlin.fir.backend.generators.OperatorExpressionGenerator
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
@@ -63,9 +62,7 @@ class Fir2IrVisitor(
|
||||
session
|
||||
)
|
||||
|
||||
private val callGenerator = CallAndReferenceGenerator(components, this, conversionScope)
|
||||
|
||||
private val memberGenerator = ClassMemberGenerator(components, this, conversionScope, callGenerator, fakeOverrideMode)
|
||||
private val memberGenerator = ClassMemberGenerator(components, this, conversionScope)
|
||||
|
||||
private val operatorGenerator = OperatorExpressionGenerator(components, this, conversionScope)
|
||||
|
||||
|
||||
+32
-13
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.backend.generators
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||
import org.jetbrains.kotlin.fir.FirAnnotationContainer
|
||||
import org.jetbrains.kotlin.fir.backend.Fir2IrComponents
|
||||
import org.jetbrains.kotlin.fir.backend.Fir2IrVisitor
|
||||
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
||||
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||
@@ -23,11 +24,11 @@ import org.jetbrains.kotlin.ir.util.isSetter
|
||||
* whose targets may vary. After all the necessary pieces of IR elements, e.g., backing field, are ready, this generator splits those
|
||||
* annotations to the specified targets.
|
||||
*/
|
||||
internal class AnnotationGenerator(private val visitor: Fir2IrVisitor) {
|
||||
internal class AnnotationGenerator(private val components: Fir2IrComponents) : Fir2IrComponents by components {
|
||||
|
||||
fun generate(irContainer: IrMutableAnnotationContainer, firContainer: FirAnnotationContainer) {
|
||||
irContainer.annotations = firContainer.annotations.mapNotNull {
|
||||
it.accept(visitor, null) as? IrConstructorCall
|
||||
callGenerator.convertToIrConstructorCall(it) as? IrConstructorCall
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +39,7 @@ internal class AnnotationGenerator(private val visitor: Fir2IrVisitor) {
|
||||
it.useSiteTarget == null || !isInConstructor || it.useSiteTarget == AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER
|
||||
}
|
||||
.mapNotNull {
|
||||
it.accept(visitor, null) as? IrConstructorCall
|
||||
callGenerator.convertToIrConstructorCall(it) as? IrConstructorCall
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +50,7 @@ internal class AnnotationGenerator(private val visitor: Fir2IrVisitor) {
|
||||
it.useSiteTarget == null || it.useSiteTarget == AnnotationUseSiteTarget.PROPERTY
|
||||
}
|
||||
.mapNotNull {
|
||||
it.accept(visitor, null) as? IrConstructorCall
|
||||
callGenerator.convertToIrConstructorCall(it) as? IrConstructorCall
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +64,9 @@ internal class AnnotationGenerator(private val visitor: Fir2IrVisitor) {
|
||||
it.useSiteTarget == AnnotationUseSiteTarget.FIELD ||
|
||||
it.useSiteTarget == AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD
|
||||
}
|
||||
.mapNotNull { it.accept(visitor, null) as? IrConstructorCall }
|
||||
.mapNotNull {
|
||||
callGenerator.convertToIrConstructorCall(it) as? IrConstructorCall
|
||||
}
|
||||
}
|
||||
|
||||
fun generate(propertyAccessor: IrFunction, property: FirProperty) {
|
||||
@@ -73,25 +76,41 @@ internal class AnnotationGenerator(private val visitor: Fir2IrVisitor) {
|
||||
if (propertyAccessor.isSetter) {
|
||||
propertyAccessor.annotations +=
|
||||
property.annotations
|
||||
.filter { it.useSiteTarget == AnnotationUseSiteTarget.PROPERTY_SETTER }
|
||||
.mapNotNull { it.accept(visitor, null) as? IrConstructorCall }
|
||||
.filter {
|
||||
it.useSiteTarget == AnnotationUseSiteTarget.PROPERTY_SETTER
|
||||
}
|
||||
.mapNotNull {
|
||||
callGenerator.convertToIrConstructorCall(it) as? IrConstructorCall
|
||||
}
|
||||
propertyAccessor.valueParameters.singleOrNull()?.annotations =
|
||||
propertyAccessor.valueParameters.singleOrNull()?.annotations?.plus(
|
||||
property.annotations
|
||||
.filter { it.useSiteTarget == AnnotationUseSiteTarget.SETTER_PARAMETER }
|
||||
.mapNotNull { it.accept(visitor, null) as? IrConstructorCall }
|
||||
.filter {
|
||||
it.useSiteTarget == AnnotationUseSiteTarget.SETTER_PARAMETER
|
||||
}
|
||||
.mapNotNull {
|
||||
callGenerator.convertToIrConstructorCall(it) as? IrConstructorCall
|
||||
}
|
||||
)!!
|
||||
} else {
|
||||
propertyAccessor.annotations +=
|
||||
property.annotations
|
||||
.filter { it.useSiteTarget == AnnotationUseSiteTarget.PROPERTY_GETTER }
|
||||
.mapNotNull { it.accept(visitor, null) as? IrConstructorCall }
|
||||
.filter {
|
||||
it.useSiteTarget == AnnotationUseSiteTarget.PROPERTY_GETTER
|
||||
}
|
||||
.mapNotNull {
|
||||
callGenerator.convertToIrConstructorCall(it) as? IrConstructorCall
|
||||
}
|
||||
}
|
||||
propertyAccessor.extensionReceiverParameter?.annotations =
|
||||
propertyAccessor.extensionReceiverParameter?.annotations?.plus(
|
||||
property.annotations
|
||||
.filter { it.useSiteTarget == AnnotationUseSiteTarget.RECEIVER }
|
||||
.mapNotNull { it.accept(visitor, null) as? IrConstructorCall }
|
||||
.filter {
|
||||
it.useSiteTarget == AnnotationUseSiteTarget.RECEIVER
|
||||
}
|
||||
.mapNotNull {
|
||||
callGenerator.convertToIrConstructorCall(it) as? IrConstructorCall
|
||||
}
|
||||
)!!
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ import org.jetbrains.kotlin.ir.util.parentClassOrNull
|
||||
import org.jetbrains.kotlin.psi.KtPropertyDelegate
|
||||
import org.jetbrains.kotlin.psi2ir.generators.hasNoSideEffects
|
||||
|
||||
internal class CallAndReferenceGenerator(
|
||||
class CallAndReferenceGenerator(
|
||||
private val components: Fir2IrComponents,
|
||||
private val visitor: Fir2IrVisitor,
|
||||
private val conversionScope: Fir2IrConversionScope
|
||||
|
||||
+1
-7
@@ -27,17 +27,11 @@ import org.jetbrains.kotlin.ir.util.*
|
||||
internal class ClassMemberGenerator(
|
||||
private val components: Fir2IrComponents,
|
||||
private val visitor: Fir2IrVisitor,
|
||||
private val conversionScope: Fir2IrConversionScope,
|
||||
private val callGenerator: CallAndReferenceGenerator,
|
||||
fakeOverrideMode: FakeOverrideMode
|
||||
private val conversionScope: Fir2IrConversionScope
|
||||
) : Fir2IrComponents by components {
|
||||
|
||||
private val annotationGenerator = AnnotationGenerator(visitor)
|
||||
|
||||
private val fakeOverrideGenerator = FakeOverrideGenerator(
|
||||
session, components.scopeSession, classifierStorage, declarationStorage, conversionScope, fakeOverrideMode
|
||||
)
|
||||
|
||||
private fun FirTypeRef.toIrType(): IrType = with(typeConverter) { toIrType() }
|
||||
|
||||
private fun ConeKotlinType.toIrType(): IrType = with(typeConverter) { toIrType() }
|
||||
|
||||
+13
-7
@@ -24,7 +24,7 @@ import org.jetbrains.kotlin.ir.types.IrTypeProjection
|
||||
import org.jetbrains.kotlin.load.java.JavaVisibilities
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
internal class FakeOverrideGenerator(
|
||||
class FakeOverrideGenerator(
|
||||
private val session: FirSession,
|
||||
private val scopeSession: ScopeSession,
|
||||
private val classifierStorage: Fir2IrClassifierStorage,
|
||||
@@ -56,9 +56,14 @@ internal class FakeOverrideGenerator(
|
||||
}
|
||||
|
||||
fun IrClass.addFakeOverrides(klass: FirClass<*>, processedCallableNames: MutableSet<Name>) {
|
||||
if (fakeOverrideMode == FakeOverrideMode.NONE) return
|
||||
declarations += getFakeOverrides(klass, processedCallableNames)
|
||||
}
|
||||
|
||||
fun IrClass.getFakeOverrides(klass: FirClass<*>, processedCallableNames: MutableSet<Name>): List<IrDeclaration> {
|
||||
val result = mutableListOf<IrDeclaration>()
|
||||
if (fakeOverrideMode == FakeOverrideMode.NONE) return emptyList()
|
||||
val superTypesCallableNames = klass.collectCallableNamesFromSupertypes(session)
|
||||
val useSiteMemberScope = klass.buildUseSiteMemberScope(session, scopeSession) ?: return
|
||||
val useSiteMemberScope = klass.buildUseSiteMemberScope(session, scopeSession) ?: return emptyList()
|
||||
for (name in superTypesCallableNames) {
|
||||
if (name in processedCallableNames) continue
|
||||
processedCallableNames += name
|
||||
@@ -82,7 +87,7 @@ internal class FakeOverrideGenerator(
|
||||
// but fake override itself uses parent from its containing (derived) class
|
||||
val overriddenSymbol = declarationStorage.getIrFunctionSymbol(baseSymbol) as IrSimpleFunctionSymbol
|
||||
irFunction.parent = this
|
||||
declarations += irFunction.withFunction {
|
||||
result += irFunction.withFunction {
|
||||
overriddenSymbols = listOf(overriddenSymbol)
|
||||
}
|
||||
} else if (fakeOverrideMode != FakeOverrideMode.SUBSTITUTION && originalFunction.allowsToHaveFakeOverrideIn(klass)) {
|
||||
@@ -103,7 +108,7 @@ internal class FakeOverrideGenerator(
|
||||
}
|
||||
val overriddenSymbol = declarationStorage.getIrFunctionSymbol(functionSymbol) as IrSimpleFunctionSymbol
|
||||
irFunction.parent = this
|
||||
declarations += irFunction.withFunction {
|
||||
result += irFunction.withFunction {
|
||||
overriddenSymbols = listOf(overriddenSymbol)
|
||||
}
|
||||
}
|
||||
@@ -122,7 +127,7 @@ internal class FakeOverrideGenerator(
|
||||
origin = origin
|
||||
)
|
||||
irProperty.parent = this
|
||||
declarations += irProperty.withProperty {
|
||||
result += irProperty.withProperty {
|
||||
setOverriddenSymbolsForAccessors(declarationStorage, originalProperty, firOverriddenSymbol = baseSymbol)
|
||||
}
|
||||
} else if (fakeOverrideMode != FakeOverrideMode.SUBSTITUTION && originalProperty.allowsToHaveFakeOverrideIn(klass)) {
|
||||
@@ -152,13 +157,14 @@ internal class FakeOverrideGenerator(
|
||||
return@processPropertiesByName
|
||||
}
|
||||
irProperty.parent = this
|
||||
declarations += irProperty.withProperty {
|
||||
result += irProperty.withProperty {
|
||||
setOverriddenSymbolsForAccessors(declarationStorage, fakeOverrideProperty, firOverriddenSymbol = propertySymbol)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private fun IrProperty.setOverriddenSymbolsForAccessors(
|
||||
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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.lazy
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.fir.backend.Fir2IrComponents
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.symbols.Fir2IrBindableSymbol
|
||||
import org.jetbrains.kotlin.ir.IrElementBase
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.lazy.lazyVar
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||
|
||||
abstract class AbstractFir2IrLazyDeclaration<F : FirMemberDeclaration, D : IrSymbolOwner>(
|
||||
private val components: Fir2IrComponents,
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
override var origin: IrDeclarationOrigin,
|
||||
val fir: F,
|
||||
open val symbol: Fir2IrBindableSymbol<*, D>
|
||||
) : IrElementBase(startOffset, endOffset), IrDeclaration, Fir2IrComponents by components {
|
||||
override var metadata: Nothing?
|
||||
get() = null
|
||||
set(_) = error("We should never need to store metadata of external declarations.")
|
||||
|
||||
override lateinit var parent: IrDeclarationParent
|
||||
|
||||
@ObsoleteDescriptorBasedAPI
|
||||
override val descriptor: DeclarationDescriptor
|
||||
get() = symbol.descriptor
|
||||
|
||||
override var annotations: List<IrConstructorCall> by lazyVar {
|
||||
fir.annotations.mapNotNull {
|
||||
callGenerator.convertToIrConstructorCall(it) as? IrConstructorCall
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,222 @@
|
||||
/*
|
||||
* 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.lazy
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.fir.backend.*
|
||||
import org.jetbrains.kotlin.fir.backend.declareThisReceiverParameter
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.resolve.buildUseSiteMemberScope
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirClassSubstitutionScope
|
||||
import org.jetbrains.kotlin.fir.symbols.Fir2IrClassSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||
import org.jetbrains.kotlin.fir.types.isNullableAny
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.lazy.lazyVar
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||
import org.jetbrains.kotlin.ir.util.mapOptimized
|
||||
import org.jetbrains.kotlin.ir.util.transform
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
class Fir2IrLazyClass(
|
||||
components: Fir2IrComponents,
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
fir: FirRegularClass,
|
||||
symbol: Fir2IrClassSymbol
|
||||
) : AbstractFir2IrLazyDeclaration<FirRegularClass, IrClass>(
|
||||
components, startOffset, endOffset, origin, fir, symbol
|
||||
), IrClass {
|
||||
init {
|
||||
symbol.bind(this)
|
||||
classifierStorage.preCacheTypeParameters(fir)
|
||||
}
|
||||
|
||||
internal fun prepareTypeParameters() {
|
||||
typeParameters = fir.typeParameters.mapIndexedNotNull { index, typeParameter ->
|
||||
if (typeParameter !is FirTypeParameter) return@mapIndexedNotNull null
|
||||
classifierStorage.getIrTypeParameter(typeParameter, index).apply {
|
||||
parent = this@Fir2IrLazyClass
|
||||
if (superTypes.isEmpty()) {
|
||||
typeParameter.bounds.mapTo(superTypes) { it.toIrType(typeConverter) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override val source: SourceElement
|
||||
get() = SourceElement.NO_SOURCE
|
||||
|
||||
@ObsoleteDescriptorBasedAPI
|
||||
override val descriptor: ClassDescriptor
|
||||
get() = super.descriptor as ClassDescriptor
|
||||
|
||||
override val symbol: Fir2IrClassSymbol
|
||||
get() = super.symbol as Fir2IrClassSymbol
|
||||
|
||||
override val name: Name
|
||||
get() = fir.name
|
||||
|
||||
override var visibility: Visibility
|
||||
get() = fir.visibility
|
||||
set(_) {
|
||||
throw AssertionError("Mutating Fir2Ir lazy elements is not possible")
|
||||
}
|
||||
|
||||
override var modality: Modality
|
||||
get() = fir.modality!!
|
||||
set(_) {
|
||||
throw AssertionError("Mutating Fir2Ir lazy elements is not possible")
|
||||
}
|
||||
|
||||
override var attributeOwnerId: IrAttributeContainer
|
||||
get() = this
|
||||
set(_) {
|
||||
throw AssertionError("Mutating Fir2Ir lazy elements is not possible")
|
||||
}
|
||||
|
||||
override val kind: ClassKind
|
||||
get() = fir.classKind
|
||||
|
||||
override val isCompanion: Boolean
|
||||
get() = fir.isCompanion
|
||||
|
||||
override val isInner: Boolean
|
||||
get() = fir.isInner
|
||||
|
||||
override val isData: Boolean
|
||||
get() = fir.isData
|
||||
|
||||
override val isExternal: Boolean
|
||||
get() = fir.isExternal
|
||||
|
||||
override val isInline: Boolean
|
||||
get() = fir.isInline
|
||||
|
||||
override val isExpect: Boolean
|
||||
get() = fir.isExpect
|
||||
|
||||
override val isFun: Boolean
|
||||
get() = fir.isFun
|
||||
|
||||
override var superTypes: List<IrType> by lazyVar {
|
||||
fir.superTypeRefs.map { it.toIrType(typeConverter) }
|
||||
}
|
||||
|
||||
override lateinit var typeParameters: List<IrTypeParameter>
|
||||
|
||||
override var thisReceiver: IrValueParameter? by lazyVar {
|
||||
symbolTable.enterScope(this)
|
||||
val typeArguments = fir.typeParameters.map {
|
||||
IrSimpleTypeImpl(
|
||||
classifierStorage.getCachedIrTypeParameter(it.symbol.fir)!!.symbol,
|
||||
hasQuestionMark = false, arguments = emptyList(), annotations = emptyList()
|
||||
)
|
||||
}
|
||||
val receiver = declareThisReceiverParameter(
|
||||
symbolTable,
|
||||
thisType = IrSimpleTypeImpl(symbol, hasQuestionMark = false, arguments = typeArguments, annotations = emptyList()),
|
||||
thisOrigin = IrDeclarationOrigin.INSTANCE_RECEIVER
|
||||
)
|
||||
symbolTable.leaveScope(this)
|
||||
receiver
|
||||
}
|
||||
|
||||
override val declarations: MutableList<IrDeclaration> by lazyVar {
|
||||
val result = mutableListOf<IrDeclaration>()
|
||||
val processedNames = mutableSetOf<Name>()
|
||||
// NB: it's necessary to take all callables from scope,
|
||||
// e.g. to avoid accessing un-enhanced Java declarations with FirJavaTypeRef etc. inside
|
||||
val scope = fir.buildUseSiteMemberScope(session, scopeSession)!!
|
||||
scope.processDeclaredConstructors {
|
||||
result += declarationStorage.createIrConstructor(it.fir, this)
|
||||
}
|
||||
for (declaration in fir.declarations) {
|
||||
when (declaration) {
|
||||
is FirSimpleFunction -> {
|
||||
if (declaration.name !in processedNames) {
|
||||
processedNames += declaration.name
|
||||
scope.processFunctionsByName(declaration.name) {
|
||||
if (it is FirNamedFunctionSymbol) {
|
||||
if (it.isAbstractMethodOfAny()) {
|
||||
return@processFunctionsByName
|
||||
}
|
||||
result += if (!it.isFakeOverride) {
|
||||
declarationStorage.createIrFunction(it.fir, irParent = this, origin = origin)
|
||||
} else {
|
||||
val fakeOverrideSymbol =
|
||||
FirClassSubstitutionScope.createFakeOverrideFunction(session, it.fir, it)
|
||||
classifierStorage.preCacheTypeParameters(it.fir)
|
||||
declarationStorage.createIrFunction(fakeOverrideSymbol.fir, irParent = this)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
is FirProperty -> {
|
||||
if (declaration.name !in processedNames) {
|
||||
processedNames += declaration.name
|
||||
scope.processPropertiesByName(declaration.name) {
|
||||
if (it is FirPropertySymbol) {
|
||||
result += if (!it.isFakeOverride) {
|
||||
declarationStorage.createIrProperty(it.fir, irParent = this, origin = origin)
|
||||
} else {
|
||||
val fakeOverrideSymbol =
|
||||
FirClassSubstitutionScope.createFakeOverrideProperty(session, it.fir, it)
|
||||
classifierStorage.preCacheTypeParameters(it.fir)
|
||||
declarationStorage.createIrProperty(fakeOverrideSymbol.fir, irParent = this)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
is FirRegularClass -> {
|
||||
val nestedSymbol = classifierStorage.getIrClassSymbol(declaration.symbol)
|
||||
result += nestedSymbol.owner
|
||||
}
|
||||
else -> continue
|
||||
}
|
||||
}
|
||||
with(fakeOverrideGenerator) {
|
||||
result += getFakeOverrides(fir, processedNames)
|
||||
}
|
||||
for (irDeclaration in result) {
|
||||
irDeclaration.parent = this
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
private fun FirNamedFunctionSymbol.isAbstractMethodOfAny(): Boolean {
|
||||
val fir = fir
|
||||
if (fir.modality != Modality.ABSTRACT) return false
|
||||
return when (fir.name.asString()) {
|
||||
"equals" -> fir.valueParameters.singleOrNull()?.returnTypeRef?.isNullableAny == true
|
||||
"hashCode", "toString" -> fir.valueParameters.isEmpty()
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitClass(this, data)
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
thisReceiver?.accept(visitor, data)
|
||||
typeParameters.forEach { it.accept(visitor, data) }
|
||||
declarations.forEach { it.accept(visitor, data) }
|
||||
}
|
||||
|
||||
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
|
||||
thisReceiver = thisReceiver?.transform(transformer, data)
|
||||
typeParameters = typeParameters.mapOptimized { it.transform(transformer, data) }
|
||||
declarations.transform { it.transform(transformer, data) }
|
||||
}
|
||||
}
|
||||
@@ -8,9 +8,9 @@ package org.jetbrains.kotlin.ir.declarations.lazy
|
||||
import org.jetbrains.kotlin.ir.declarations.withInitialIr
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
internal fun <T> lazyVar(initializer: () -> T): UnsafeLazyVar<T> = UnsafeLazyVar(initializer)
|
||||
fun <T> lazyVar(initializer: () -> T): UnsafeLazyVar<T> = UnsafeLazyVar(initializer)
|
||||
|
||||
internal class UnsafeLazyVar<T>(initializer: () -> T) {
|
||||
class UnsafeLazyVar<T>(initializer: () -> T) {
|
||||
private var isInitialized = false;
|
||||
private var initializer: (() -> T)? = initializer
|
||||
private var _value: Any? = null
|
||||
|
||||
@@ -67,7 +67,7 @@ fun IrDeclarationContainer.transformDeclarationsFlat(transformation: (IrDeclarat
|
||||
/**
|
||||
* Similar to `map`. Return the same List instance if no element instances have changed.
|
||||
*/
|
||||
internal inline fun <reified T : IrElement> List<T>.mapOptimized(transformation: (T) -> IrElement): List<T> {
|
||||
inline fun <reified T : IrElement> List<T>.mapOptimized(transformation: (T) -> IrElement): List<T> {
|
||||
var result: ArrayList<T>? = null
|
||||
for ((i, item) in withIndex()) {
|
||||
val transformed = transformation(item) as T
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
// WITH_RUNTIME
|
||||
|
||||
-1
@@ -1,5 +1,4 @@
|
||||
// !JVM_DEFAULT_MODE: all-compatibility
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
// JVM_TARGET: 1.8
|
||||
// WITH_RUNTIME
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// !JVM_DEFAULT_MODE: enable
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
// JVM_TARGET: 1.8
|
||||
// WITH_RUNTIME
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// !JVM_DEFAULT_MODE: all
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
// JVM_TARGET: 1.8
|
||||
// WITH_RUNTIME
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
// FILE: JavaClass.java
|
||||
|
||||
+2
-1
@@ -47,7 +47,7 @@ FILE fqName:<root> fileName:/implicitNotNullOnDelegatedImplementation.kt
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:K2 modality:FINAL visibility:public superTypes:[<root>.JFoo]'
|
||||
FUN name:foo visibility:public modality:FINAL <> ($this:<root>.K2) returnType:kotlin.String
|
||||
overridden:
|
||||
public abstract fun foo (): kotlin.String declared in <root>.IFoo
|
||||
public open fun foo (): kotlin.String declared in <root>.JFoo
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.K2
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun foo (): kotlin.String declared in <root>.K2'
|
||||
@@ -97,6 +97,7 @@ FILE fqName:<root> fileName:/implicitNotNullOnDelegatedImplementation.kt
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:K4 modality:FINAL visibility:public superTypes:[<root>.JUnrelatedFoo; <root>.IFoo]'
|
||||
FUN name:foo visibility:public modality:FINAL <> ($this:<root>.K4) returnType:kotlin.String?
|
||||
overridden:
|
||||
public open fun foo (): kotlin.String? declared in <root>.JUnrelatedFoo
|
||||
public abstract fun foo (): kotlin.String declared in <root>.IFoo
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.K4
|
||||
BLOCK_BODY
|
||||
|
||||
@@ -87,4 +87,5 @@ FILE fqName:<root> fileName:/samConversionToGeneric.kt
|
||||
BLOCK_BODY
|
||||
CALL 'public open fun bar2x <Y> (j2x: <root>.J2X<Y of <root>.H.bar2x?>?): kotlin.Unit declared in <root>.H' type=kotlin.Unit origin=null
|
||||
<Y>: kotlin.Int?
|
||||
j2x: GET_VAR 'fn: kotlin.Function1<kotlin.Int, kotlin.String> declared in <root>.test10' type=kotlin.Function1<kotlin.Int, kotlin.String> origin=null
|
||||
j2x: TYPE_OP type=<root>.J2X<Y of <root>.H.bar2x?>? origin=SAM_CONVERSION typeOperand=<root>.J2X<Y of <root>.H.bar2x?>?
|
||||
GET_VAR 'fn: kotlin.Function1<kotlin.Int, kotlin.String> declared in <root>.test10' type=kotlin.Function1<kotlin.Int, kotlin.String> origin=null
|
||||
|
||||
Reference in New Issue
Block a user