[FIR]: fix translation of top-level property accesses like array.indices
This commit addresses the following issues: * accessors didn't take into account their property's receiver type, which caused NoSuchMethod due to signature mismatch. Now the property's receiver type is passed to Fir2Ir translation of accessors. * property's parent was not class, e.g., kotlin.collections.indices. Now the symbol table collects WrappedPropertyDescriptorWithContainerSource besides WrappedFunctionDescriptorWithContainerSource, so that facade classes for such properties can be generated before codegen. * accessor's parent was not class. Now the containerSource of the property descriptor is passed to accessor descriptor.
This commit is contained in:
committed by
Mikhail Glukhikh
parent
c9658eb6e4
commit
4f6fe1d0ca
+21
-9
@@ -408,7 +408,10 @@ class Fir2IrDeclarationStorage(
|
||||
return this
|
||||
}
|
||||
|
||||
private fun <T : IrFunction> T.declareParameters(function: FirFunction<*>?, containingClass: IrClass?, isStatic: Boolean) {
|
||||
private fun <T : IrFunction> T.declareParameters(
|
||||
function: FirFunction<*>?, containingClass: IrClass?,
|
||||
isStatic: Boolean, parentReceiverType: FirTypeRef? = null
|
||||
) {
|
||||
val parent = this
|
||||
if (function is FirSimpleFunction) {
|
||||
setTypeParameters(function)
|
||||
@@ -428,7 +431,7 @@ class Fir2IrDeclarationStorage(
|
||||
}
|
||||
if (function !is FirConstructor) {
|
||||
val thisOrigin = IrDeclarationOrigin.DEFINED
|
||||
val receiverTypeRef = function?.receiverTypeRef
|
||||
val receiverTypeRef = function?.receiverTypeRef ?: parentReceiverType
|
||||
if (receiverTypeRef != null) {
|
||||
extensionReceiverParameter = receiverTypeRef.convertWithOffsets { startOffset, endOffset ->
|
||||
declareThisReceiverParameter(
|
||||
@@ -455,11 +458,12 @@ class Fir2IrDeclarationStorage(
|
||||
descriptor: WrappedCallableDescriptor<T>,
|
||||
irParent: IrDeclarationParent?,
|
||||
isStatic: Boolean,
|
||||
shouldLeaveScope: Boolean
|
||||
shouldLeaveScope: Boolean,
|
||||
parentReceiverType: FirTypeRef? = null
|
||||
): T {
|
||||
descriptor.bind(this)
|
||||
enterScope(descriptor)
|
||||
declareParameters(function, containingClass = irParent as? IrClass, isStatic = isStatic)
|
||||
declareParameters(function, containingClass = irParent as? IrClass, isStatic = isStatic, parentReceiverType = parentReceiverType)
|
||||
if (shouldLeaveScope) {
|
||||
leaveScope(descriptor)
|
||||
}
|
||||
@@ -592,9 +596,14 @@ class Fir2IrDeclarationStorage(
|
||||
isSetter: Boolean,
|
||||
origin: IrDeclarationOrigin,
|
||||
startOffset: Int,
|
||||
endOffset: Int
|
||||
endOffset: Int,
|
||||
parentPropertyReceiverType: FirTypeRef? = null
|
||||
): IrSimpleFunction {
|
||||
val descriptor = WrappedSimpleFunctionDescriptor()
|
||||
val propertyDescriptor = correspondingProperty.descriptor
|
||||
val descriptor =
|
||||
if (propertyDescriptor is WrappedPropertyDescriptorWithContainerSource)
|
||||
WrappedFunctionDescriptorWithContainerSource(propertyDescriptor.containerSource)
|
||||
else WrappedSimpleFunctionDescriptor()
|
||||
val prefix = if (isSetter) "set" else "get"
|
||||
return irSymbolTable.declareSimpleFunction(
|
||||
propertyAccessor?.psi?.startOffsetSkippingComments ?: startOffset,
|
||||
@@ -615,7 +624,8 @@ class Fir2IrDeclarationStorage(
|
||||
declareDefaultSetterParameter(propertyType)
|
||||
}
|
||||
}.bindAndDeclareParameters(
|
||||
propertyAccessor, descriptor, irParent, isStatic = irParent !is IrClass, shouldLeaveScope = true
|
||||
propertyAccessor, descriptor, irParent, isStatic = irParent !is IrClass, shouldLeaveScope = true,
|
||||
parentReceiverType = parentPropertyReceiverType
|
||||
).apply {
|
||||
if (irParent != null) {
|
||||
parent = irParent
|
||||
@@ -692,6 +702,7 @@ class Fir2IrDeclarationStorage(
|
||||
).apply {
|
||||
descriptor.bind(this)
|
||||
val type = property.returnTypeRef.toIrType(session, this@Fir2IrDeclarationStorage)
|
||||
val receiverType = if (property.containerSource != null) property.receiverTypeRef else null
|
||||
getter = createIrPropertyAccessor(
|
||||
property.getter, this, type, irParent, false,
|
||||
when {
|
||||
@@ -699,7 +710,7 @@ class Fir2IrDeclarationStorage(
|
||||
property.getter is FirDefaultPropertyGetter -> IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR
|
||||
else -> origin
|
||||
},
|
||||
startOffset, endOffset
|
||||
startOffset, endOffset, parentPropertyReceiverType = receiverType
|
||||
)
|
||||
if (property.isVar) {
|
||||
setter = createIrPropertyAccessor(
|
||||
@@ -709,7 +720,8 @@ class Fir2IrDeclarationStorage(
|
||||
property.setter is FirDefaultPropertySetter -> IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR
|
||||
else -> origin
|
||||
},
|
||||
startOffset, endOffset
|
||||
startOffset, endOffset,
|
||||
parentPropertyReceiverType = receiverType
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.codegen.PackageCodegenImpl
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.descriptors.WrappedDeclarationDescriptor
|
||||
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
|
||||
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
@@ -48,7 +49,8 @@ class JvmIrCodegenFactory(private val phaseConfig: PhaseConfig) : CodegenFactory
|
||||
ExternalDependenciesGenerator(symbolTable, irProviders).generateUnboundSymbolsAsDependencies()
|
||||
|
||||
val stubGenerator = irProviders.filterIsInstance<DeclarationStubGenerator>().first()
|
||||
for (descriptor in symbolTable.functionDescriptorsWithNonClassParent()) {
|
||||
for (descriptor in symbolTable.wrappedTopLevelCallableDescriptors()) {
|
||||
descriptor as WrappedDeclarationDescriptor<*>
|
||||
val parentClass = stubGenerator.generateOrGetFacadeClass(descriptor)
|
||||
descriptor.owner.parent = parentClass ?: throw AssertionError("Facade class for ${descriptor.name} not found")
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.ir.symbols.*
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrUninitializedType
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DescriptorWithContainerSource
|
||||
|
||||
interface IrProvider {
|
||||
fun getDeclaration(symbol: IrSymbol): IrDeclaration?
|
||||
@@ -831,11 +832,15 @@ open class SymbolTable(val signaturer: IdSignatureComposer) : ReferenceSymbolTab
|
||||
throw IllegalArgumentException("Unexpected value descriptor: $value")
|
||||
}
|
||||
|
||||
fun functionDescriptorsWithNonClassParent(): Set<WrappedFunctionDescriptorWithContainerSource> {
|
||||
val result = mutableSetOf<WrappedFunctionDescriptorWithContainerSource>()
|
||||
fun wrappedTopLevelCallableDescriptors(): Set<DescriptorWithContainerSource> {
|
||||
val result = mutableSetOf<DescriptorWithContainerSource>()
|
||||
for (descriptor in simpleFunctionSymbolTable.descriptorToSymbol.keys) {
|
||||
if (descriptor is WrappedFunctionDescriptorWithContainerSource
|
||||
&& descriptor.owner.parent !is IrClass) {
|
||||
if (descriptor is WrappedFunctionDescriptorWithContainerSource && descriptor.owner.parent !is IrClass) {
|
||||
result.add(descriptor)
|
||||
}
|
||||
}
|
||||
for (descriptor in propertySymbolTable.descriptorToSymbol.keys) {
|
||||
if (descriptor is WrappedPropertyDescriptorWithContainerSource && descriptor.owner.parent !is IrClass) {
|
||||
result.add(descriptor)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// KJS_WITH_FULL_RUNTIME
|
||||
// WITH_RUNTIME
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
// WITH_RUNTIME
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
// WITH_RUNTIME
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
// WITH_RUNTIME
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
// WITH_RUNTIME
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
// WITH_RUNTIME
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// WITH_RUNTIME
|
||||
// IGNORE_BACKEND: JS
|
||||
|
||||
|
||||
Vendored
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// WITH_RUNTIME
|
||||
|
||||
lateinit var bar: String
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// KJS_WITH_FULL_RUNTIME
|
||||
// WITH_RUNTIME
|
||||
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// KJS_WITH_FULL_RUNTIME
|
||||
// WITH_RUNTIME
|
||||
|
||||
|
||||
Vendored
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// KJS_WITH_FULL_RUNTIME
|
||||
// WITH_RUNTIME
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// KJS_WITH_FULL_RUNTIME
|
||||
// WITH_RUNTIME
|
||||
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// KJS_WITH_FULL_RUNTIME
|
||||
// WITH_RUNTIME
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// KJS_WITH_FULL_RUNTIME
|
||||
// WITH_RUNTIME
|
||||
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// KJS_WITH_FULL_RUNTIME
|
||||
// WITH_RUNTIME
|
||||
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// KJS_WITH_FULL_RUNTIME
|
||||
// WITH_RUNTIME
|
||||
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// KJS_WITH_FULL_RUNTIME
|
||||
// WITH_RUNTIME
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// KJS_WITH_FULL_RUNTIME
|
||||
// WITH_RUNTIME
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// KJS_WITH_FULL_RUNTIME
|
||||
// WITH_RUNTIME
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// KJS_WITH_FULL_RUNTIME
|
||||
// WITH_RUNTIME
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// KJS_WITH_FULL_RUNTIME
|
||||
// WITH_RUNTIME
|
||||
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// KJS_WITH_FULL_RUNTIME
|
||||
// WITH_RUNTIME
|
||||
import kotlin.test.*
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// KJS_WITH_FULL_RUNTIME
|
||||
// WITH_RUNTIME
|
||||
import kotlin.test.*
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// KJS_WITH_FULL_RUNTIME
|
||||
// WITH_RUNTIME
|
||||
import kotlin.test.*
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
// WITH_REFLECT
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
// WITH_REFLECT
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
// WITH_REFLECT
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
// WITH_REFLECT
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
// WITH_REFLECT
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
// WITH_REFLECT
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
// WITH_RUNTIME
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
// WITH_RUNTIME
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
// WITH_RUNTIME
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
// WITH_RUNTIME
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// KJS_WITH_FULL_RUNTIME
|
||||
// WITH_RUNTIME
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
// WITH_RUNTIME
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
// WITH_RUNTIME
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
// WITH_RUNTIME
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
// WITH_RUNTIME
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
// WITH_RUNTIME
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
// WITH_RUNTIME
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
// WITH_RUNTIME
|
||||
|
||||
@@ -25,4 +25,8 @@ FILE fqName:<root> fileName:/classReference.kt
|
||||
GET_CLASS type=kotlin.reflect.KClass<<root>.A>
|
||||
CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in <root>.A' type=<root>.A origin=null
|
||||
CALL 'public final fun <get-java> (): java.lang.Class<T of <uninitialized parent>> declared in kotlin.jvm' type=java.lang.Class<<root>.A> origin=null
|
||||
$receiver: GET_CLASS type=kotlin.reflect.KClass<<root>.A>
|
||||
GET_OBJECT 'CLASS CLASS name:A modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.Unit
|
||||
CALL 'public final fun <get-java> (): java.lang.Class<T of <uninitialized parent>> declared in kotlin.jvm' type=java.lang.Class<<root>.A> origin=null
|
||||
$receiver: GET_CLASS type=kotlin.reflect.KClass<<root>.A>
|
||||
CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in <root>.A' type=<root>.A origin=null
|
||||
|
||||
@@ -23,3 +23,5 @@ FILE fqName:<root> fileName:/objectClassReference.kt
|
||||
GET_CLASS type=kotlin.reflect.KClass<<root>.A>
|
||||
GET_OBJECT 'CLASS OBJECT name:A modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.A
|
||||
CALL 'public final fun <get-java> (): java.lang.Class<T of <uninitialized parent>> declared in kotlin.jvm' type=java.lang.Class<<root>.A> origin=null
|
||||
$receiver: GET_CLASS type=kotlin.reflect.KClass<<root>.A>
|
||||
GET_OBJECT 'CLASS OBJECT name:A modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.A
|
||||
|
||||
Reference in New Issue
Block a user