[FIR2IR] OptIn to using IrClass.declarations in all appropriate places

This commit is contained in:
Dmitriy Novozhilov
2023-10-06 15:11:39 +03:00
committed by Space Team
parent 38a7f2bc07
commit 81821d4cd4
6 changed files with 68 additions and 9 deletions
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.fir.extensions.extensionService
import org.jetbrains.kotlin.fir.extensions.generatedMembers import org.jetbrains.kotlin.fir.extensions.generatedMembers
import org.jetbrains.kotlin.fir.extensions.generatedNestedClassifiers import org.jetbrains.kotlin.fir.extensions.generatedNestedClassifiers
import org.jetbrains.kotlin.fir.java.javaElementFinder import org.jetbrains.kotlin.fir.java.javaElementFinder
import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyClass
import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.symbols.lazyDeclarationResolver import org.jetbrains.kotlin.fir.symbols.lazyDeclarationResolver
import org.jetbrains.kotlin.fir.types.resolvedType import org.jetbrains.kotlin.fir.types.resolvedType
@@ -48,9 +49,10 @@ import org.jetbrains.kotlin.ir.interpreter.IrInterpreterEnvironment
import org.jetbrains.kotlin.ir.interpreter.checker.EvaluationMode import org.jetbrains.kotlin.ir.interpreter.checker.EvaluationMode
import org.jetbrains.kotlin.ir.interpreter.transformer.transformConst import org.jetbrains.kotlin.ir.interpreter.transformer.transformConst
import org.jetbrains.kotlin.ir.overrides.IrFakeOverrideBuilder import org.jetbrains.kotlin.ir.overrides.IrFakeOverrideBuilder
import org.jetbrains.kotlin.ir.symbols.IrSymbolInternals
import org.jetbrains.kotlin.ir.types.IrTypeSystemContext
import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorPublicSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorPublicSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionPublicSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionPublicSymbolImpl
import org.jetbrains.kotlin.ir.types.IrTypeSystemContext
import org.jetbrains.kotlin.ir.util.KotlinMangler import org.jetbrains.kotlin.ir.util.KotlinMangler
import org.jetbrains.kotlin.ir.util.NaiveSourceBasedFileEntryImpl import org.jetbrains.kotlin.ir.util.NaiveSourceBasedFileEntryImpl
import org.jetbrains.kotlin.ir.util.defaultType import org.jetbrains.kotlin.ir.util.defaultType
@@ -185,7 +187,10 @@ class Fir2IrConverter(
* IrFile should contain declarations in the source order, but creating of IrClass automatically adds created class to the list * IrFile should contain declarations in the source order, but creating of IrClass automatically adds created class to the list
* of file declaration. And in this step we skip all callables, so by default all classes will be declared before all callables * of file declaration. And in this step we skip all callables, so by default all classes will be declared before all callables
* To fix this issue the list of declarations is cleared at this point, and later it will be filled again in `processClassMembers` * To fix this issue the list of declarations is cleared at this point, and later it will be filled again in `processClassMembers`
*
* `irFile` is definitely not a lazy class
*/ */
@OptIn(IrSymbolInternals::class)
irFile.declarations.clear() irFile.declarations.clear()
} }
@@ -207,7 +212,10 @@ class Fir2IrConverter(
* IrClass should contain declarations in the source order, but creating of nested IrClass automatically adds created class to the list * IrClass should contain declarations in the source order, but creating of nested IrClass automatically adds created class to the list
* of class declaration. And in this step we skip all callables, so by default all classes will be declared before all callables * of class declaration. And in this step we skip all callables, so by default all classes will be declared before all callables
* To fix this issue the list of declarations is cleared at this point, and later it will be filled again in `processClassMembers` * To fix this issue the list of declarations is cleared at this point, and later it will be filled again in `processClassMembers`
*
* `irClass` is a source class and definitely is not a lazy class
*/ */
@OptIn(IrSymbolInternals::class)
irClass.declarations.clear() irClass.declarations.clear()
} }
@@ -220,6 +228,8 @@ class Fir2IrConverter(
} }
} }
// `irClass` is a source class and definitely is not a lazy class
@OptIn(IrSymbolInternals::class)
irClass.declarations.addAll(classifierStorage.getFieldsWithContextReceiversForClass(irClass, klass)) irClass.declarations.addAll(classifierStorage.getFieldsWithContextReceiversForClass(irClass, klass))
val irConstructor = klass.primaryConstructorIfAny(session)?.let { val irConstructor = klass.primaryConstructorIfAny(session)?.let {
@@ -343,6 +353,8 @@ class Fir2IrConverter(
private fun bindFakeOverridesInFile(file: FirFile) { private fun bindFakeOverridesInFile(file: FirFile) {
val irFile = declarationStorage.getIrFile(file) val irFile = declarationStorage.getIrFile(file)
// `irFile` definitely is not a lazy class
@OptIn(IrSymbolInternals::class)
for (irDeclaration in irFile.declarations) { for (irDeclaration in irFile.declarations) {
if (irDeclaration is IrClass) { if (irDeclaration is IrClass) {
bindFakeOverridesInClass(irDeclaration) bindFakeOverridesInClass(irDeclaration)
@@ -350,7 +362,10 @@ class Fir2IrConverter(
} }
} }
// `irClass` is a source class and definitely is not a lazy class
@OptIn(IrSymbolInternals::class)
fun bindFakeOverridesInClass(klass: IrClass) { fun bindFakeOverridesInClass(klass: IrClass) {
require(klass !is Fir2IrLazyClass)
fakeOverrideGenerator.bindOverriddenSymbols(klass.declarations) fakeOverrideGenerator.bindOverriddenSymbols(klass.declarations)
delegatedMemberGenerator.bindDelegatedMembersOverriddenSymbols(klass) delegatedMemberGenerator.bindDelegatedMembersOverriddenSymbols(klass)
for (irDeclaration in klass.declarations) { for (irDeclaration in klass.declarations) {
@@ -360,6 +375,8 @@ class Fir2IrConverter(
} }
} }
// `irClass` is a source class and definitely is not a lazy class
@OptIn(IrSymbolInternals::class)
private fun delegatedMembers(irClass: IrClass): List<FirDeclaration> { private fun delegatedMembers(irClass: IrClass): List<FirDeclaration> {
return irClass.declarations.filter { return irClass.declarations.filter {
it.origin == IrDeclarationOrigin.DELEGATED_MEMBER it.origin == IrDeclarationOrigin.DELEGATED_MEMBER
@@ -419,7 +436,10 @@ class Fir2IrConverter(
* IrClass should contain declarations in the source order, but creating of nested IrClass automatically adds created class to the list * IrClass should contain declarations in the source order, but creating of nested IrClass automatically adds created class to the list
* of class declaration. And in this step we skip all callables, so by default all classes will be declared before all callables * of class declaration. And in this step we skip all callables, so by default all classes will be declared before all callables
* To fix this issue the list of declarations is cleared at this point, and later it will be filled again in `processFileAndClassMembers` * To fix this issue the list of declarations is cleared at this point, and later it will be filled again in `processFileAndClassMembers`
*
* `irClass` is a source class and definitely is not a lazy class
*/ */
@OptIn(IrSymbolInternals::class)
irClass.declarations.clear() irClass.declarations.clear()
} }
@@ -443,8 +463,13 @@ class Fir2IrConverter(
containingClass: FirClass?, containingClass: FirClass?,
parent: IrDeclarationParent parent: IrDeclarationParent
) { ) {
// This function is needed to preserve the source order of declaration in file /*
// see the comment in [processClassHeaders] function * This function is needed to preserve the source order of declaration in file
* see the comment in [processClassHeaders] function
*
* `irClass` is a source class and definitely is not a lazy class
*/
@OptIn(IrSymbolInternals::class)
fun addDeclarationToParentIfNeeded(irDeclaration: IrDeclaration) { fun addDeclarationToParentIfNeeded(irDeclaration: IrDeclaration) {
when (parent) { when (parent) {
is IrFile -> parent.declarations += irDeclaration is IrFile -> parent.declarations += irDeclaration
@@ -41,6 +41,7 @@ import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbolInternals
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.types.impl.IrErrorClassImpl import org.jetbrains.kotlin.ir.types.impl.IrErrorClassImpl
@@ -147,6 +148,9 @@ class Fir2IrVisitor(
converter.bindFakeOverridesInClass(correspondingClass) converter.bindFakeOverridesInClass(correspondingClass)
conversionScope.withParent(correspondingClass) { conversionScope.withParent(correspondingClass) {
memberGenerator.convertClassContent(correspondingClass, anonymousObject) memberGenerator.convertClassContent(correspondingClass, anonymousObject)
// `correspondingClass` definitely is not a lazy class
@OptIn(IrSymbolInternals::class)
val constructor = correspondingClass.constructors.first() val constructor = correspondingClass.constructors.first()
irEnumEntry.initializerExpression = irFactory.createExpressionBody( irEnumEntry.initializerExpression = irFactory.createExpressionBody(
IrEnumConstructorCallImpl( IrEnumConstructorCallImpl(
@@ -171,6 +175,8 @@ class Fir2IrVisitor(
} }
} else if (irParentEnumClass != null && initializer == null) { } else if (irParentEnumClass != null && initializer == null) {
// a default-ish enum entry whose initializer would be a delegating constructor call // a default-ish enum entry whose initializer would be a delegating constructor call
// `irParentEnumClass` definitely is not a lazy class
@OptIn(IrSymbolInternals::class)
val constructor = irParentEnumClass.defaultConstructor val constructor = irParentEnumClass.defaultConstructor
?: error("Assuming that default constructor should exist and be converted at this point") ?: error("Assuming that default constructor should exist and be converted at this point")
enumEntry.convertWithOffsets { startOffset, endOffset -> enumEntry.convertWithOffsets { startOffset, endOffset ->
@@ -325,6 +331,8 @@ class Fir2IrVisitor(
override fun visitCodeFragment(codeFragment: FirCodeFragment, data: Any?): IrElement { override fun visitCodeFragment(codeFragment: FirCodeFragment, data: Any?): IrElement {
val irClass = classifierStorage.getCachedIrCodeFragment(codeFragment)!! val irClass = classifierStorage.getCachedIrCodeFragment(codeFragment)!!
// class for code fragment definitely is not a lazy class
@OptIn(IrSymbolInternals::class)
val irFunction = irClass.declarations.firstIsInstance<IrSimpleFunction>() val irFunction = irClass.declarations.firstIsInstance<IrSimpleFunction>()
declarationStorage.enterScope(irFunction.symbol) declarationStorage.enterScope(irFunction.symbol)
@@ -362,6 +370,8 @@ class Fir2IrVisitor(
startOffset, startOffset,
endOffset, endOffset,
anonymousClassType, anonymousClassType,
// a class for an anonymous object definitely is not a lazy class
@OptIn(IrSymbolInternals::class)
irAnonymousObject.constructors.first().symbol, irAnonymousObject.constructors.first().symbol,
irAnonymousObject.typeParameters.size, irAnonymousObject.typeParameters.size,
origin = IrStatementOrigin.OBJECT_LITERAL origin = IrStatementOrigin.OBJECT_LITERAL
@@ -157,6 +157,8 @@ class IrBuiltInsOverFir(
} }
private val intrinsicConstAnnotation: IrConstructorCall by lazy { private val intrinsicConstAnnotation: IrConstructorCall by lazy {
// class for intrinsicConst is created manually and it definitely is not a lazy class
@OptIn(IrSymbolInternals::class)
val constructor = intrinsicConst.constructors.single() val constructor = intrinsicConst.constructors.single()
IrConstructorCallImpl.Companion.fromSymbolOwner(intrinsicConst.defaultType, constructor) IrConstructorCallImpl.Companion.fromSymbolOwner(intrinsicConst.defaultType, constructor)
} }
@@ -305,10 +307,17 @@ class IrBuiltInsOverFir(
returnType: IrType, returnType: IrType,
vararg valueParameterTypes: Pair<String, IrType>, vararg valueParameterTypes: Pair<String, IrType>,
isIntrinsicConst: Boolean = false, isIntrinsicConst: Boolean = false,
) = ): IrSimpleFunctionSymbol {
createFunction(name, returnType, valueParameterTypes, origin = BUILTIN_OPERATOR, isIntrinsicConst = isIntrinsicConst).also { return createFunction(
name, returnType, valueParameterTypes,
origin = BUILTIN_OPERATOR,
isIntrinsicConst = isIntrinsicConst
).also {
// `kotlinInternalIrPackageFragment` definitely is not a lazy class
@OptIn(IrSymbolInternals::class)
declarations.add(it) declarations.add(it)
}.symbol }.symbol
}
primitiveFloatingPointIrTypes.forEach { fpType -> primitiveFloatingPointIrTypes.forEach { fpType ->
_ieee754equalsFunByOperandType[fpType.classifierOrFail] = addBuiltinOperatorSymbol( _ieee754equalsFunByOperandType[fpType.classifierOrFail] = addBuiltinOperatorSymbol(
@@ -369,6 +378,8 @@ class IrBuiltInsOverFir(
typeParameters = listOf(typeParameter), typeParameters = listOf(typeParameter),
origin = BUILTIN_OPERATOR origin = BUILTIN_OPERATOR
).also { ).also {
// `kotlinInternalIrPackageFragment` definitely is not a lazy class
@OptIn(IrSymbolInternals::class)
declarations.add(it) declarations.add(it)
}.symbol }.symbol
} }
@@ -557,6 +568,8 @@ class IrBuiltInsOverFir(
return builtInClass.functions.filter { it.owner.name == name }.asIterable() return builtInClass.functions.filter { it.owner.name == name }.asIterable()
} }
// This function should not be called from fir2ir code
@IrSymbolInternals
override fun getBinaryOperator(name: Name, lhsType: IrType, rhsType: IrType): IrSimpleFunctionSymbol { override fun getBinaryOperator(name: Name, lhsType: IrType, rhsType: IrType): IrSimpleFunctionSymbol {
val definingClass = lhsType.getMaybeBuiltinClass() ?: error("Defining class not found: $lhsType") val definingClass = lhsType.getMaybeBuiltinClass() ?: error("Defining class not found: $lhsType")
return definingClass.functions.single { function -> return definingClass.functions.single { function ->
@@ -564,6 +577,8 @@ class IrBuiltInsOverFir(
}.symbol }.symbol
} }
// This function should not be called from fir2ir code
@IrSymbolInternals
override fun getUnaryOperator(name: Name, receiverType: IrType): IrSimpleFunctionSymbol { override fun getUnaryOperator(name: Name, receiverType: IrType): IrSimpleFunctionSymbol {
val definingClass = receiverType.getMaybeBuiltinClass() ?: error("Defining class not found: $receiverType") val definingClass = receiverType.getMaybeBuiltinClass() ?: error("Defining class not found: $receiverType")
return definingClass.functions.single { function -> return definingClass.functions.single { function ->
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.ir.builders.IrGeneratorContextBase
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbolInternals
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.*
@@ -101,6 +102,8 @@ class DataClassMembersGenerator(val components: Fir2IrComponents) : Fir2IrCompon
override fun getProperty(irValueParameter: IrValueParameter?): IrProperty = override fun getProperty(irValueParameter: IrValueParameter?): IrProperty =
irValueParameter?.let { irValueParameter?.let {
// `irClass` is a source class and definitely is not a lazy class
@OptIn(IrSymbolInternals::class)
irClass.properties.single { irProperty -> irClass.properties.single { irProperty ->
irProperty.name == irValueParameter.name && irProperty.backingField?.type == irValueParameter.type irProperty.name == irValueParameter.name && irProperty.backingField?.type == irValueParameter.type
} }
@@ -232,6 +235,8 @@ class DataClassMembersGenerator(val components: Fir2IrComponents) : Fir2IrCompon
return result return result
} }
// `irClass` is a source class and definitely is not a lazy class
@OptIn(IrSymbolInternals::class)
fun generateBodies() { fun generateBodies() {
val propertyParametersCount = irClass.primaryConstructor?.explicitParameters?.size ?: 0 val propertyParametersCount = irClass.primaryConstructor?.explicitParameters?.size ?: 0
val properties = irClass.properties.filter { it.backingField != null }.take(propertyParametersCount).toList() val properties = irClass.properties.filter { it.backingField != null }.take(propertyParametersCount).toList()
@@ -280,6 +285,8 @@ class DataClassMembersGenerator(val components: Fir2IrComponents) : Fir2IrCompon
fun generateComponentBody(irFunction: IrFunction) { fun generateComponentBody(irFunction: IrFunction) {
irFunction.origin = origin irFunction.origin = origin
val index = DataClassResolver.getComponentIndex(irFunction.name.asString()) val index = DataClassResolver.getComponentIndex(irFunction.name.asString())
// `irClass` is a source class and definitely is not a lazy class
@OptIn(IrSymbolInternals::class)
val valueParameter = irClass.primaryConstructor!!.valueParameters[index - 1] val valueParameter = irClass.primaryConstructor!!.valueParameters[index - 1]
val irProperty = irDataClassMembersGenerator.getProperty(valueParameter) val irProperty = irDataClassMembersGenerator.getProperty(valueParameter)
irDataClassMembersGenerator.generateComponentFunction(irFunction, irProperty) irDataClassMembersGenerator.generateComponentFunction(irFunction, irProperty)
@@ -287,6 +294,8 @@ class DataClassMembersGenerator(val components: Fir2IrComponents) : Fir2IrCompon
fun generateCopyBody(irFunction: IrFunction) { fun generateCopyBody(irFunction: IrFunction) {
irFunction.origin = origin irFunction.origin = origin
// `irClass` is a source class and definitely is not a lazy class
@OptIn(IrSymbolInternals::class)
irDataClassMembersGenerator.generateCopyFunction(irFunction, irClass.primaryConstructor!!.symbol) irDataClassMembersGenerator.generateCopyFunction(irFunction, irClass.primaryConstructor!!.symbol)
} }
@@ -42,10 +42,7 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
import org.jetbrains.kotlin.ir.declarations.impl.SCRIPT_K2_ORIGIN import org.jetbrains.kotlin.ir.declarations.impl.SCRIPT_K2_ORIGIN
import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.impl.IrErrorExpressionImpl import org.jetbrains.kotlin.ir.expressions.impl.IrErrorExpressionImpl
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.impl.* import org.jetbrains.kotlin.ir.symbols.impl.*
import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.*
@@ -1119,6 +1116,7 @@ internal fun IrDeclaration.setParent(irParent: IrDeclarationParent?) {
* Note that IrClass will be a parent if some declaration is declared inside anonymous initializer, because IrAnonymousInitializer * Note that IrClass will be a parent if some declaration is declared inside anonymous initializer, because IrAnonymousInitializer
* is not a IrDeclarationParent * is not a IrDeclarationParent
*/ */
@OptIn(IrSymbolInternals::class)
internal fun addDeclarationToParent(declaration: IrDeclaration, irParent: IrDeclarationParent?) { internal fun addDeclarationToParent(declaration: IrDeclaration, irParent: IrDeclarationParent?) {
if (irParent == null) return if (irParent == null) return
when (irParent) { when (irParent) {
@@ -167,6 +167,8 @@ class Fir2IrClassifiersGenerator(val components: Fir2IrComponents) : Fir2IrCompo
return irClass return irClass
} }
// `irClass` is a source class and definitely is not a lazy class
@OptIn(IrSymbolInternals::class)
private fun IrClass.declareTypeParameters(klass: FirClass) { private fun IrClass.declareTypeParameters(klass: FirClass) {
classifierStorage.preCacheTypeParameters(klass, symbol) classifierStorage.preCacheTypeParameters(klass, symbol)
setTypeParameters(this, klass) setTypeParameters(this, klass)