[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:
Juan Chen
2020-02-21 12:51:47 -08:00
committed by Mikhail Glukhikh
parent c9658eb6e4
commit 4f6fe1d0ca
47 changed files with 39 additions and 56 deletions
@@ -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
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// KJS_WITH_FULL_RUNTIME
// WITH_RUNTIME
-1
View File
@@ -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
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_RUNTIME
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// WITH_RUNTIME
// IGNORE_BACKEND: JS
@@ -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,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,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,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
import kotlin.test.*
@@ -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
// KJS_WITH_FULL_RUNTIME
// WITH_RUNTIME
import kotlin.test.*
@@ -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_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
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_RUNTIME
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_RUNTIME
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_RUNTIME
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_RUNTIME
-1
View File
@@ -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
View File
@@ -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
View File
@@ -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